From 34379a1e4ffba24f2a8a92c82cb46a06db538698 Mon Sep 17 00:00:00 2001 From: labrocadabro Date: Mon, 21 Apr 2025 15:36:47 -0300 Subject: [PATCH 01/13] Add string reversal function implementation --- src/string_reversal.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 src/string_reversal.py diff --git a/src/string_reversal.py b/src/string_reversal.py new file mode 100644 index 00000000..6c5177aa --- /dev/null +++ b/src/string_reversal.py @@ -0,0 +1,19 @@ +def reverse_string(s: str) -> str: + """ + Reverse the given string. + + Args: + s (str): The input string to be reversed. + + Returns: + str: The reversed string. + + Raises: + TypeError: If the input is not a string. + """ + # Check if input is a string + if not isinstance(s, str): + raise TypeError("Input must be a string") + + # Return the reversed string + return s[::-1] \ No newline at end of file From bda1af389cd914181e9e193357d9e40daa85b9a4 Mon Sep 17 00:00:00 2001 From: labrocadabro Date: Mon, 21 Apr 2025 15:37:00 -0300 Subject: [PATCH 02/13] Add comprehensive tests for string reversal function --- tests/test_string_reversal.py | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 tests/test_string_reversal.py diff --git a/tests/test_string_reversal.py b/tests/test_string_reversal.py new file mode 100644 index 00000000..862ea5c9 --- /dev/null +++ b/tests/test_string_reversal.py @@ -0,0 +1,34 @@ +import pytest +from src.string_reversal import reverse_string + +def test_reverse_string_normal(): + """Test reversing a normal string.""" + assert reverse_string("hello") == "olleh" + +def test_reverse_string_empty(): + """Test reversing an empty string.""" + assert reverse_string("") == "" + +def test_reverse_string_single_char(): + """Test reversing a single character string.""" + assert reverse_string("a") == "a" + +def test_reverse_string_with_spaces(): + """Test reversing a string with spaces.""" + assert reverse_string("hello world") == "dlrow olleh" + +def test_reverse_string_with_numbers(): + """Test reversing a string with numbers.""" + assert reverse_string("h3ll0") == "0ll3h" + +def test_reverse_string_with_symbols(): + """Test reversing a string with symbols.""" + assert reverse_string("h@llo!") == "!oll@h" + +def test_reverse_string_invalid_input(): + """Test that a TypeError is raised for non-string input.""" + with pytest.raises(TypeError, match="Input must be a string"): + reverse_string(123) + + with pytest.raises(TypeError, match="Input must be a string"): + reverse_string(None) \ No newline at end of file From fa439250fa54cbf1599b07efc1a0a30ab4289cad Mon Sep 17 00:00:00 2001 From: labrocadabro Date: Mon, 21 Apr 2025 15:38:10 -0300 Subject: [PATCH 03/13] Implement string reversal without slice notation or reverse() --- src/string_reversal.py | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/string_reversal.py b/src/string_reversal.py index 6c5177aa..5025ac79 100644 --- a/src/string_reversal.py +++ b/src/string_reversal.py @@ -1,6 +1,6 @@ def reverse_string(s: str) -> str: """ - Reverse the given string. + Reverse the given string manually without using slice notation or reverse(). Args: s (str): The input string to be reversed. @@ -15,5 +15,16 @@ def reverse_string(s: str) -> str: if not isinstance(s, str): raise TypeError("Input must be a string") - # Return the reversed string - return s[::-1] \ No newline at end of file + # Convert string to list of characters + chars = list(s) + + # Manually reverse the list of characters + left, right = 0, len(chars) - 1 + while left < right: + # Swap characters from both ends + chars[left], chars[right] = chars[right], chars[left] + left += 1 + right -= 1 + + # Convert back to string and return + return ''.join(chars) \ No newline at end of file From a9564daeb7f2218b9a341c0cf7dc543329c5d06b Mon Sep 17 00:00:00 2001 From: laura-abro Date: Mon, 21 Apr 2025 15:39:53 -0300 Subject: [PATCH 04/13] Implement array flattening function --- src/array_flattener.py | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 src/array_flattener.py diff --git a/src/array_flattener.py b/src/array_flattener.py new file mode 100644 index 00000000..f21d882a --- /dev/null +++ b/src/array_flattener.py @@ -0,0 +1,37 @@ +from typing import List, Union + +def flatten_array(arr: List[Union[int, List]]) -> List[int]: + """ + Flatten a nested list of integers into a single-level list. + + This function recursively flattens a potentially nested list of integers, + handling various levels of nesting and different types of nested lists. + + Args: + arr (List[Union[int, List]]): A potentially nested list of integers + + Returns: + List[int]: A flattened list of integers + + Raises: + TypeError: If non-integer or non-list elements are found + + Examples: + >>> flatten_array([1, [2, 3], 4]) + [1, 2, 3, 4] + >>> flatten_array([1, [2, [3, 4]], 5]) + [1, 2, 3, 4, 5] + """ + flattened = [] + + for item in arr: + if isinstance(item, int): + flattened.append(item) + elif isinstance(item, list): + # Recursively flatten nested lists + flattened.extend(flatten_array(item)) + else: + # Raise TypeError for invalid input types + raise TypeError(f"Invalid type in array: {type(item)}. Only integers and lists are allowed.") + + return flattened \ No newline at end of file From 65e0f92a3472f18ac00d174923692d07f1db383b Mon Sep 17 00:00:00 2001 From: laura-abro Date: Mon, 21 Apr 2025 15:40:05 -0300 Subject: [PATCH 05/13] Add comprehensive tests for array flattening function --- tests/test_array_flattener.py | 43 +++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 tests/test_array_flattener.py diff --git a/tests/test_array_flattener.py b/tests/test_array_flattener.py new file mode 100644 index 00000000..5e00e76a --- /dev/null +++ b/tests/test_array_flattener.py @@ -0,0 +1,43 @@ +import pytest +from src.array_flattener import flatten_array + +def test_flat_list(): + """Test flattening a list that is already flat.""" + assert flatten_array([1, 2, 3]) == [1, 2, 3] + +def test_nested_list(): + """Test flattening a list with one level of nesting.""" + assert flatten_array([1, [2, 3], 4]) == [1, 2, 3, 4] + +def test_deeply_nested_list(): + """Test flattening a list with multiple levels of nesting.""" + assert flatten_array([1, [2, [3, 4]], 5]) == [1, 2, 3, 4, 5] + +def test_empty_list(): + """Test flattening an empty list.""" + assert flatten_array([]) == [] + +def test_list_with_empty_nested_list(): + """Test flattening a list containing an empty nested list.""" + assert flatten_array([1, [], 2]) == [1, 2] + +def test_multiple_empty_nested_lists(): + """Test flattening a list with multiple empty nested lists.""" + assert flatten_array([[], [1], [], [2, []]]) == [1, 2] + +def test_invalid_type_raises_error(): + """Test that an error is raised for invalid input types.""" + with pytest.raises(TypeError, match="Invalid type in array"): + flatten_array([1, "string", 3]) + + with pytest.raises(TypeError, match="Invalid type in array"): + flatten_array([1, [2, "nested"], 3]) + +def test_complex_nested_structure(): + """Test a more complex nested structure.""" + assert flatten_array([1, [2, [3, [4]]], 5]) == [1, 2, 3, 4, 5] + +def test_nested_lists_with_different_depths(): + """Test flattening lists with varying nesting depths.""" + input_list = [1, [2], [[3]], [[[4]]], 5] + assert flatten_array(input_list) == [1, 2, 3, 4, 5] \ No newline at end of file From a8ca4514ac7c1f04083f7f83a3ae8c8cc815fda6 Mon Sep 17 00:00:00 2001 From: laura-abro Date: Mon, 21 Apr 2025 15:40:12 -0300 Subject: [PATCH 06/13] Add pytest to requirements --- requirements.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 requirements.txt diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 00000000..55b033e9 --- /dev/null +++ b/requirements.txt @@ -0,0 +1 @@ +pytest \ No newline at end of file From 3d789d3c70068bba4f59333471a75a5fdffb4d61 Mon Sep 17 00:00:00 2001 From: labrocadabro Date: Mon, 21 Apr 2025 16:22:53 -0300 Subject: [PATCH 07/13] Implement binary search function with comprehensive error handling --- src/binary_search.py | 46 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 src/binary_search.py diff --git a/src/binary_search.py b/src/binary_search.py new file mode 100644 index 00000000..4d4069ea --- /dev/null +++ b/src/binary_search.py @@ -0,0 +1,46 @@ +def binary_search(arr, target): + """ + Perform binary search on a sorted array to find the target element. + + Args: + arr (list): A sorted list of comparable elements + target: The element to search for + + Returns: + int: Index of the target element if found, otherwise -1 + + Raises: + TypeError: If the input is not a list + ValueError: If the input list is not sorted + """ + # Check if input is a list + if not isinstance(arr, list): + raise TypeError("Input must be a list") + + # Check if list is empty + if not arr: + return -1 + + # Verify the list is sorted + if not all(arr[i] <= arr[i+1] for i in range(len(arr)-1)): + raise ValueError("Input list must be sorted in ascending order") + + # Perform binary search + left, right = 0, len(arr) - 1 + + while left <= right: + # Calculate middle index to avoid integer overflow + mid = left + (right - left) // 2 + + # Check if target is found + if arr[mid] == target: + return mid + + # Adjust search boundaries + if arr[mid] < target: + left = mid + 1 + else: + right = mid - 1 + + # Target not found + return -1 \ No newline at end of file From 7d135bf6aa5307c1612f76ef0145127ed450ab75 Mon Sep 17 00:00:00 2001 From: labrocadabro Date: Mon, 21 Apr 2025 16:23:07 -0300 Subject: [PATCH 08/13] Add comprehensive tests for binary search implementation --- tests/test_binary_search.py | 39 +++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 tests/test_binary_search.py diff --git a/tests/test_binary_search.py b/tests/test_binary_search.py new file mode 100644 index 00000000..3a5a9cf7 --- /dev/null +++ b/tests/test_binary_search.py @@ -0,0 +1,39 @@ +import pytest +from src.binary_search import binary_search + +def test_binary_search_basic(): + """Test basic functionality of binary search""" + arr = [1, 3, 5, 7, 9, 11, 13] + assert binary_search(arr, 7) == 3 + assert binary_search(arr, 13) == 6 + assert binary_search(arr, 1) == 0 + +def test_binary_search_not_found(): + """Test when target is not in the array""" + arr = [1, 3, 5, 7, 9, 11, 13] + assert binary_search(arr, 4) == -1 + assert binary_search(arr, 0) == -1 + assert binary_search(arr, 14) == -1 + +def test_binary_search_empty_list(): + """Test binary search on an empty list""" + assert binary_search([], 5) == -1 + +def test_binary_search_single_element(): + """Test binary search on a single-element list""" + arr = [5] + assert binary_search(arr, 5) == 0 + assert binary_search(arr, 6) == -1 + +def test_binary_search_invalid_input(): + """Test error handling for invalid inputs""" + with pytest.raises(TypeError): + binary_search("not a list", 5) + + with pytest.raises(ValueError): + binary_search([5, 3, 1], 3) # Unsorted list + +def test_binary_search_duplicate_elements(): + """Test binary search with duplicate elements""" + arr = [1, 2, 2, 3, 3, 3, 4, 5] + assert binary_search(arr, 3) in [3, 4, 5] # Any index of 3 is acceptable \ No newline at end of file From 0b25fce882d2d9e441014cd148239965a0ecfc8e Mon Sep 17 00:00:00 2001 From: laura-abro Date: Mon, 21 Apr 2025 16:24:58 -0300 Subject: [PATCH 09/13] Add URL parser function implementation --- src/url_parser.py | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 src/url_parser.py diff --git a/src/url_parser.py b/src/url_parser.py new file mode 100644 index 00000000..6ca14db6 --- /dev/null +++ b/src/url_parser.py @@ -0,0 +1,45 @@ +from urllib.parse import urlparse, parse_qs +from typing import Dict, Any, Optional + +def parse_url(url: str) -> Dict[str, Any]: + """ + Parse a given URL into its components. + + Args: + url (str): The URL to parse. + + Returns: + Dict[str, Any]: A dictionary containing URL components: + - scheme: The URL scheme (protocol) + - netloc: The network location (domain) + - path: The path component of the URL + - params: The query parameters as a dictionary + - fragment: The fragment identifier + + Raises: + ValueError: If the input URL is empty or invalid + """ + # Check for empty or None input + if not url: + raise ValueError("URL cannot be empty") + + try: + # Use urlparse to break down the URL + parsed_url = urlparse(url) + + # Parse query parameters + query_params = parse_qs(parsed_url.query) + + # Convert single-item lists to their values for cleaner output + query_params = {k: v[0] if len(v) == 1 else v for k, v in query_params.items()} + + # Construct and return the parsed URL dictionary + return { + 'scheme': parsed_url.scheme, + 'netloc': parsed_url.netloc, + 'path': parsed_url.path, + 'params': query_params, + 'fragment': parsed_url.fragment + } + except Exception as e: + raise ValueError(f"Invalid URL: {str(e)}") \ No newline at end of file From ab2b1dde52bcb4f083417ef18139e7248f68a2e0 Mon Sep 17 00:00:00 2001 From: laura-abro Date: Mon, 21 Apr 2025 16:25:11 -0300 Subject: [PATCH 10/13] Add comprehensive tests for URL parser function --- tests/test_url_parser.py | 85 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 tests/test_url_parser.py diff --git a/tests/test_url_parser.py b/tests/test_url_parser.py new file mode 100644 index 00000000..bec48ac9 --- /dev/null +++ b/tests/test_url_parser.py @@ -0,0 +1,85 @@ +import pytest +from src.url_parser import parse_url + +def test_full_url_parsing(): + """Test parsing a full URL with all components""" + url = "https://www.example.com/path/to/page?param1=value1¶m2=value2#section" + result = parse_url(url) + + assert result == { + 'scheme': 'https', + 'netloc': 'www.example.com', + 'path': '/path/to/page', + 'params': { + 'param1': 'value1', + 'param2': 'value2' + }, + 'fragment': 'section' + } + +def test_url_with_multiple_params(): + """Test URL with multiple values for same parameter""" + url = "http://example.com/search?tag=python&tag=programming" + result = parse_url(url) + + assert result == { + 'scheme': 'http', + 'netloc': 'example.com', + 'path': '/search', + 'params': { + 'tag': ['python', 'programming'] + }, + 'fragment': '' + } + +def test_minimal_url(): + """Test parsing a minimal URL""" + url = "https://example.com" + result = parse_url(url) + + assert result == { + 'scheme': 'https', + 'netloc': 'example.com', + 'path': '', + 'params': {}, + 'fragment': '' + } + +def test_url_with_no_scheme(): + """Test URL without a scheme""" + url = "example.com/path" + result = parse_url(url) + + assert result == { + 'scheme': '', + 'netloc': '', + 'path': 'example.com/path', + 'params': {}, + 'fragment': '' + } + +def test_empty_url_raises_error(): + """Test that empty URL raises a ValueError""" + with pytest.raises(ValueError, match="URL cannot be empty"): + parse_url("") + +def test_none_url_raises_error(): + """Test that None input raises a ValueError""" + with pytest.raises(ValueError, match="URL cannot be empty"): + parse_url(None) # type: ignore + +def test_complex_url_with_special_characters(): + """Test URL with special characters and encoding""" + url = "https://example.com/search?q=hello%20world&lang=en" + result = parse_url(url) + + assert result == { + 'scheme': 'https', + 'netloc': 'example.com', + 'path': '/search', + 'params': { + 'q': 'hello world', + 'lang': 'en' + }, + 'fragment': '' + } \ No newline at end of file From ee6d3e1a9bf75a088dff1a029ecdcf40363450e2 Mon Sep 17 00:00:00 2001 From: laura-abro Date: Mon, 21 Apr 2025 16:25:22 -0300 Subject: [PATCH 11/13] Add pytest to requirements --- requirements.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 requirements.txt diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 00000000..55b033e9 --- /dev/null +++ b/requirements.txt @@ -0,0 +1 @@ +pytest \ No newline at end of file From a7a9168744dd37e92418d760636e7d5c402ebe79 Mon Sep 17 00:00:00 2001 From: labrocadabro Date: Mon, 21 Apr 2025 19:15:31 -0300 Subject: [PATCH 12/13] Add RGB to Hex converter function --- src/rgb_to_hex.py | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 src/rgb_to_hex.py diff --git a/src/rgb_to_hex.py b/src/rgb_to_hex.py new file mode 100644 index 00000000..0c1e9936 --- /dev/null +++ b/src/rgb_to_hex.py @@ -0,0 +1,24 @@ +def rgb_to_hex(r: int, g: int, b: int) -> str: + """ + Convert RGB color values to a hexadecimal color representation. + + Args: + r (int): Red color value (0-255) + g (int): Green color value (0-255) + b (int): Blue color value (0-255) + + Returns: + str: Hexadecimal color representation (uppercase) + + Raises: + ValueError: If any color value is outside the range 0-255 + """ + # Validate input ranges + for color, name in [(r, 'Red'), (g, 'Green'), (b, 'Blue')]: + if not isinstance(color, int): + raise TypeError(f"{name} value must be an integer") + if color < 0 or color > 255: + raise ValueError(f"{name} value must be between 0 and 255") + + # Convert to hex, remove '0x' prefix, pad with zeros, and convert to uppercase + return f"{r:02X}{g:02X}{b:02X}" \ No newline at end of file From c0284af5a976b89255c3a0eb75e2c483b01f878e Mon Sep 17 00:00:00 2001 From: labrocadabro Date: Mon, 21 Apr 2025 19:15:46 -0300 Subject: [PATCH 13/13] Add comprehensive tests for RGB to Hex converter --- tests/test_rgb_to_hex.py | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 tests/test_rgb_to_hex.py diff --git a/tests/test_rgb_to_hex.py b/tests/test_rgb_to_hex.py new file mode 100644 index 00000000..904ea8d7 --- /dev/null +++ b/tests/test_rgb_to_hex.py @@ -0,0 +1,35 @@ +import pytest +from src.rgb_to_hex import rgb_to_hex + +def test_rgb_to_hex_basic(): + """Test basic RGB to Hex conversion""" + assert rgb_to_hex(255, 255, 255) == 'FFFFFF' + assert rgb_to_hex(0, 0, 0) == '000000' + assert rgb_to_hex(148, 0, 211) == '9400D3' + +def test_rgb_to_hex_edge_cases(): + """Test edge cases of color values""" + assert rgb_to_hex(0, 0, 0) == '000000' + assert rgb_to_hex(255, 255, 255) == 'FFFFFF' + +def test_rgb_to_hex_padding(): + """Test padding of single-digit hex values""" + assert rgb_to_hex(10, 15, 20) == '0A0F14' + +def test_rgb_to_hex_invalid_input(): + """Test error handling for invalid inputs""" + # Test out of range values + with pytest.raises(ValueError, match="Red value must be between 0 and 255"): + rgb_to_hex(-1, 0, 0) + with pytest.raises(ValueError, match="Green value must be between 0 and 255"): + rgb_to_hex(0, 256, 0) + with pytest.raises(ValueError, match="Blue value must be between 0 and 255"): + rgb_to_hex(0, 0, 300) + + # Test non-integer inputs + with pytest.raises(TypeError, match="Red value must be an integer"): + rgb_to_hex(10.5, 0, 0) + with pytest.raises(TypeError, match="Green value must be an integer"): + rgb_to_hex(0, '100', 0) + with pytest.raises(TypeError, match="Blue value must be an integer"): + rgb_to_hex(0, 0, [255]) \ No newline at end of file