Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
593fb0c
Add string reversal function implementation
momstrosity Apr 10, 2025
eaf9e1e
Add comprehensive tests for string reversal function
momstrosity Apr 10, 2025
6426a51
Implement manual string reversal without slice notation
momstrosity Apr 10, 2025
9096fa5
Update tests for manual string reversal implementation
momstrosity Apr 10, 2025
75203a0
Fix syntax error in test file
momstrosity Apr 10, 2025
28a4f92
Implement array flattening function with recursive approach
labrocadabro Apr 10, 2025
e322490
Implement binary search function with comprehensive error handling
laura-abro Apr 10, 2025
4b997e5
Add comprehensive tests for array flattening function
labrocadabro Apr 10, 2025
64023a0
Add comprehensive test cases for binary search function
laura-abro Apr 10, 2025
d67d892
Implement URL parser function
laura-abro Apr 10, 2025
e6256d6
Implement RGB to Hex converter function
momstrosity Apr 10, 2025
ca28f9a
Add comprehensive tests for RGB to Hex converter
momstrosity Apr 10, 2025
f21377e
Add comprehensive tests for URL parser
laura-abro Apr 10, 2025
fbcbe9e
Update URL parser to preserve URL-encoded values
laura-abro Apr 10, 2025
6cbf538
Update URL parser to handle multiple query parameters
laura-abro Apr 10, 2025
86da26f
Merged branch pr-175-momstrosity-builder-test for PR https://github.c…
labrocadabro Apr 10, 2025
f135378
Merged branch pr-176-momstrosity-builder-test for PR https://github.c…
labrocadabro Apr 10, 2025
fdb4f92
Merged branch pr-177-momstrosity-builder-test for PR https://github.c…
labrocadabro Apr 10, 2025
85bb219
Merged branch pr-178-momstrosity-builder-test for PR https://github.c…
labrocadabro Apr 10, 2025
2f629b9
Merged branch pr-179-momstrosity-builder-test for PR https://github.c…
labrocadabro Apr 10, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions src/array_flattening.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
from typing import List, Union, Any

def flatten_array(arr: List[Union[Any, List]]) -> List[Any]:
"""
Recursively flatten a nested list into a single-level list.

Args:
arr (List[Union[Any, List]]): A potentially nested list to be flattened.

Returns:
List[Any]: A flattened list with all nested elements extracted.

Raises:
TypeError: If the input is not a list.

Examples:
>>> flatten_array([1, [2, 3], [4, [5, 6]]])
[1, 2, 3, 4, 5, 6]
>>> flatten_array([1, 2, 3])
[1, 2, 3]
>>> flatten_array([])
[]
"""
# Validate input is a list
if not isinstance(arr, list):
raise TypeError("Input must be a list")

# Recursive flattening function
flattened = []
for item in arr:
# If the item is a list, recursively flatten
if isinstance(item, list):
flattened.extend(flatten_array(item))
else:
# Otherwise, append the item directly
flattened.append(item)

return flattened
48 changes: 48 additions & 0 deletions src/binary_search.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
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 input is not a list
ValueError: If the 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 sorted
if arr != sorted(arr):
raise ValueError("Input list must be sorted in ascending order")

# Handle empty list
if not arr:
return -1

# Perform binary search
left, right = 0, len(arr) - 1

while left <= right:
# Calculate mid point to avoid potential integer overflow
mid = left + (right - left) // 2

# Check if target is found
if arr[mid] == target:
return mid

# If target is greater, ignore left half
elif arr[mid] < target:
left = mid + 1

# If target is smaller, ignore right half
else:
right = mid - 1

# Target not found
return -1
26 changes: 26 additions & 0 deletions src/rgb_to_hex.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
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 not between 0 and 255
"""
# Validate input values
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 and ensure two digits with leading zero if needed
hex_color = ''.join(f'{color:02X}' for color in [r, g, b])

return hex_color
24 changes: 24 additions & 0 deletions src/string_reversal.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
def reverse_string(s: str) -> str:
"""
Reverse a given string manually, preserving all characters.

Args:
s (str): The input string to be reversed.

Returns:
str: The reversed string.

Raises:
TypeError: If the input is not a string.
"""
# Type checking
if not isinstance(s, str):
raise TypeError("Input must be a string")

# Manual string reversal using a list-based approach
# This method preserves all characters, including spaces and special characters
reversed_chars = []
for i in range(len(s) - 1, -1, -1):
reversed_chars.append(s[i])

return ''.join(reversed_chars)
58 changes: 58 additions & 0 deletions src/url_parser.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
from urllib.parse import urlparse, unquote
from typing import Dict, Any, Optional, Union, List

def parse_url(url: str) -> Dict[str, Any]:
"""
Parse a given URL into its component parts.

Args:
url (str): The URL to parse

Returns:
Dict[str, Any]: A dictionary containing URL components

Raises:
ValueError: If the URL is invalid or empty
"""
# Check for empty or None input
if not url or not isinstance(url, str):
raise ValueError("Invalid URL: URL must be a non-empty string")

try:
# Parse the URL
parsed_url = urlparse(url)

# Extract query parameters with raw URL-encoded values
query_params: Dict[str, Union[str, List[str]]] = {}
if parsed_url.query:
# Use custom parsing to handle multiple parameters
for param in parsed_url.query.split('&'):
if '=' in param:
key, value = param.split('=', 1)
decoded_key = unquote(key)

# Handle multiple values for the same key
if decoded_key in query_params:
if isinstance(query_params[decoded_key], list):
query_params[decoded_key].append(value) # type: ignore
else:
query_params[decoded_key] = [query_params[decoded_key], value] # type: ignore
else:
query_params[decoded_key] = value

# Construct and return the parsed URL dictionary
return {
'scheme': parsed_url.scheme or None,
'netloc': parsed_url.netloc or None,
'path': parsed_url.path or None,
'params': parsed_url.params or None,
'query': query_params,
'fragment': parsed_url.fragment or None,
'username': parsed_url.username,
'password': parsed_url.password,
'hostname': parsed_url.hostname,
'port': parsed_url.port
}
except Exception as e:
# Catch any unexpected parsing errors
raise ValueError(f"Error parsing URL: {str(e)}")
33 changes: 33 additions & 0 deletions tests/test_array_flattening.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import pytest
from src.array_flattening import flatten_array

def test_flatten_simple_list():
"""Test flattening a simple list"""
assert flatten_array([1, 2, 3]) == [1, 2, 3]

def test_flatten_nested_list():
"""Test flattening a nested list"""
assert flatten_array([1, [2, 3], [4, [5, 6]]]) == [1, 2, 3, 4, 5, 6]

def test_flatten_deeply_nested_list():
"""Test flattening a deeply nested list"""
assert flatten_array([1, [2, [3, [4]]], 5]) == [1, 2, 3, 4, 5]

def test_flatten_empty_list():
"""Test flattening an empty list"""
assert flatten_array([]) == []

def test_flatten_list_with_empty_sublists():
"""Test flattening a list with empty sublists"""
assert flatten_array([1, [], [2, []], 3]) == [1, 2, 3]

def test_invalid_input_type():
"""Test that a TypeError is raised for non-list inputs"""
with pytest.raises(TypeError, match="Input must be a list"):
flatten_array("not a list")
flatten_array(123)
flatten_array(None)

def test_mixed_type_list():
"""Test flattening a list with mixed types"""
assert flatten_array([1, "string", [2, 3.14], [True, [False]]]) == [1, "string", 2, 3.14, True, False]
45 changes: 45 additions & 0 deletions tests/test_binary_search.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
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, 1) == 0
assert binary_search(arr, 13) == 6

def test_binary_search_not_found():
"""Test when target is not in the list"""
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, 4) == -1

def test_binary_search_type_error():
"""Test that TypeError is raised for non-list inputs"""
with pytest.raises(TypeError):
binary_search("not a list", 5)
with pytest.raises(TypeError):
binary_search(123, 5)

def test_binary_search_unsorted_list():
"""Test that ValueError is raised for unsorted lists"""
with pytest.raises(ValueError):
binary_search([5, 3, 1, 2, 4], 3)

def test_binary_search_duplicate_elements():
"""Test binary search with duplicate elements"""
arr = [1, 2, 2, 3, 3, 3, 4, 5]
# Returns the index of one of the duplicates (doesn't matter which)
assert binary_search(arr, 2) in [1, 2]
assert binary_search(arr, 3) in [3, 4, 5]
41 changes: 41 additions & 0 deletions tests/test_rgb_to_hex.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import pytest
from src.rgb_to_hex import rgb_to_hex

def test_rgb_to_hex_basic():
"""Test basic color conversion"""
assert rgb_to_hex(255, 128, 0) == 'FF8000'
assert rgb_to_hex(0, 0, 0) == '000000'
assert rgb_to_hex(255, 255, 255) == 'FFFFFF'

def test_rgb_to_hex_edge_cases():
"""Test edge case values"""
assert rgb_to_hex(0, 0, 0) == '000000'
assert rgb_to_hex(255, 255, 255) == 'FFFFFF'

def test_rgb_to_hex_lowercase_conversion():
"""Ensure output is always uppercase"""
result = rgb_to_hex(10, 20, 30)
assert result == result.upper()

def test_rgb_to_hex_invalid_inputs():
"""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)

def test_rgb_to_hex_type_errors():
"""Test type checking for inputs"""
with pytest.raises(TypeError, match="Red value must be an integer"):
rgb_to_hex('255', 0, 0)

with pytest.raises(TypeError, match="Green value must be an integer"):
rgb_to_hex(0, '128', 0)

with pytest.raises(TypeError, match="Blue value must be an integer"):
rgb_to_hex(0, 0, '64')
42 changes: 42 additions & 0 deletions tests/test_string_reversal.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import pytest
from src.string_reversal import reverse_string

def test_reverse_string_basic():
"""Test basic string reversal."""
assert reverse_string("hello") == "olleh"
assert reverse_string("python") == "nohtyp"

def test_reverse_string_empty():
"""Test reversal of an empty string."""
assert reverse_string("") == ""

def test_reverse_string_single_char():
"""Test reversal of a single character."""
assert reverse_string("a") == "a"

def test_reverse_string_with_spaces():
"""Test reversal of string with spaces."""
assert reverse_string("hello world") == "dlrow olleh"

def test_reverse_string_with_punctuation():
"""Test reversal of string with punctuation."""
assert reverse_string("hello, world!") == "!dlrow ,olleh"

def test_reverse_string_with_mixed_characters():
"""Test reversal of string with mixed character types."""
assert reverse_string("a1b2c3") == "3c2b1a"

def test_reverse_string_unicode():
"""Test reversal of string with unicode characters."""
assert reverse_string("café") == "éfac"

def test_reverse_string_invalid_input():
"""Test that TypeError is raised for non-string inputs."""
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)

with pytest.raises(TypeError, match="Input must be a string"):
reverse_string(["hello"])
Loading