Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
3124b99
Add string reversal function implementation
labrocadabro Apr 21, 2025
1580b7c
Add comprehensive tests for string reversal function
labrocadabro Apr 21, 2025
bd1dc51
Reimplement string reversal with manual character swapping
labrocadabro Apr 21, 2025
db3a47a
Update tests for comprehensive string reversal coverage
labrocadabro Apr 21, 2025
2d0c1d6
Add array flattening function with recursive implementation
laura-abro Apr 21, 2025
ccd09a3
Add comprehensive test cases for array flattening function
laura-abro Apr 21, 2025
b81d02a
Implement binary search function with comprehensive error handling
labrocadabro Apr 21, 2025
ad154d7
Add comprehensive tests for binary search function
labrocadabro Apr 21, 2025
38c05d9
Implement URL parser function with comprehensive parsing
laura-abro Apr 21, 2025
517eafa
Add comprehensive tests for URL parser function
laura-abro Apr 21, 2025
a578be2
Add pytest to requirements
laura-abro Apr 21, 2025
b208879
Update URL parser to handle edge cases and normalize empty values
laura-abro Apr 21, 2025
9a062c3
Update test_invalid_url_parsing test to match implementation
laura-abro Apr 21, 2025
7f9c363
Update URL parser to handle invalid URL edge cases
laura-abro Apr 21, 2025
dc9f983
Add RGB to Hex converter function
labrocadabro Apr 21, 2025
9807074
Add tests for RGB to Hex converter
labrocadabro Apr 21, 2025
1337fd5
Merged branch pr-246-momstrosity-builder-test for PR https://github.c…
momstrosity Apr 21, 2025
21c4696
Merged branch pr-247-momstrosity-builder-test for PR https://github.c…
momstrosity Apr 21, 2025
d64bd17
Merged branch pr-248-momstrosity-builder-test for PR https://github.c…
momstrosity Apr 21, 2025
6bbda12
Merged branch pr-249-momstrosity-builder-test for PR https://github.c…
momstrosity Apr 21, 2025
fb3dcac
Merged branch pr-250-momstrosity-builder-test for PR https://github.c…
momstrosity Apr 21, 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
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pytest
44 changes: 44 additions & 0 deletions src/array_flatten.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
from typing import List, Union

def flatten_array(nested_array: List[Union[int, List]]) -> List[int]:
"""
Flatten a nested array of integers into a single-level array.

Args:
nested_array (List[Union[int, List]]): An array that may contain
integers or nested lists of integers.

Returns:
List[int]: A flattened list containing all integers from the input.

Raises:
TypeError: If the input contains non-integer and non-list elements.

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

# Recursive flattening function
def _flatten(item):
# If item is an integer, return it as a single-element list
if isinstance(item, int):
return [item]

# If item is a list, recursively flatten it
if isinstance(item, list):
flattened = []
for sub_item in item:
flattened.extend(_flatten(sub_item))
return flattened

# Raise error for unsupported types
raise TypeError(f"Unsupported type in array: {type(item)}")

# Flatten the entire input array
return _flatten(nested_array)
46 changes: 46 additions & 0 deletions src/binary_search.py
Original file line number Diff line number Diff line change
@@ -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 input is not a list or target is not comparable
ValueError: If the input list is not sorted
"""
# Validate input
if not isinstance(arr, list):
raise TypeError("Input must be a list")

# Check if list is sorted
if any(arr[i] > arr[i+1] for i in range(len(arr)-1)):
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

# Adjust search boundaries
if arr[mid] < target:
left = mid + 1
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 string.

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

Raises:
ValueError: If any color value is outside the valid range of 0-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 each color value to a two-digit hex representation
hex_color = '#{:02X}{:02X}{:02X}'.format(r, g, b)

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

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")

# Manual string reversal using a list-based approach
# Convert string to list of characters
chars = list(s)

# Swap characters from start to end
left, right = 0, len(chars) - 1
while left < right:
chars[left], chars[right] = chars[right], chars[left]
left += 1
right -= 1

# Convert back to string and return
return ''.join(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, parse_qs
from typing import Dict, Any, Optional

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 parsed 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("URL must be a non-empty string")

# Basic validation to check for truly invalid URLs
if not any(char in url for char in ['/', '.']):
raise ValueError("Invalid URL")

try:
# Use urlparse to break down the URL
parsed = urlparse(url)

# Extract query parameters
query_params = parse_qs(parsed.query)

# Convert query parameters from lists to single values if possible
cleaned_params = {}
for key, value in query_params.items():
cleaned_params[key] = value[0] if len(value) == 1 else value

# Normalize empty strings and None values
scheme = parsed.scheme or ""
netloc = parsed.netloc or ""
path = parsed.path or ""
fragment = parsed.fragment or ""

# Construct and return the parsed URL dictionary
return {
"scheme": scheme,
"netloc": netloc,
"path": path,
"params": parsed.params or None,
"query": cleaned_params,
"fragment": fragment,
"username": parsed.username,
"password": parsed.password,
"hostname": parsed.hostname,
"port": parsed.port
}
except Exception as e:
# For other unexpected errors
raise ValueError(f"Invalid URL: {str(e)}")
36 changes: 36 additions & 0 deletions tests/test_array_flatten.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import pytest
from src.array_flatten import flatten_array

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

def test_flatten_single_level_nested():
"""Test flattening a list with single-level nesting."""
assert flatten_array([1, [2, 3], 4]) == [1, 2, 3, 4]

def test_flatten_multi_level_nested():
"""Test flattening a list with multiple levels of nesting."""
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_deeply_nested_list():
"""Test flattening a deeply nested list."""
assert flatten_array([1, [2, [3, [4, [5]]]], 6]) == [1, 2, 3, 4, 5, 6]

def test_invalid_input_type():
"""Test that a non-list input raises a TypeError."""
with pytest.raises(TypeError, match="Input must be a list"):
flatten_array(123)

def test_invalid_nested_type():
"""Test that an unsupported type in the list raises a TypeError."""
with pytest.raises(TypeError, match="Unsupported type"):
flatten_array([1, 2, "string"])

def test_mixed_nesting():
"""Test flattening a list with mixed nesting levels."""
assert flatten_array([1, [2], [[3]], [[[4]]], 5]) == [1, 2, 3, 4, 5]
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_normal_case():
"""Test binary search with a normal sorted list"""
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 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"""
arr = []
assert binary_search(arr, 5) == -1

def test_binary_search_single_element():
"""Test binary search with a single-element list"""
arr = [5]
assert binary_search(arr, 5) == 0
assert binary_search(arr, 4) == -1

def test_binary_search_duplicate_elements():
"""Test binary search with duplicate elements"""
arr = [1, 2, 2, 3, 3, 3, 4, 4, 5]
assert binary_search(arr, 3) in [3, 4, 5]

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(TypeError):
binary_search(None, 5)

def test_binary_search_unsorted_list():
"""Test error handling for unsorted list"""
with pytest.raises(ValueError):
binary_search([5, 3, 1, 4], 3)
38 changes: 38 additions & 0 deletions tests/test_rgb_to_hex.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import pytest
from src.rgb_to_hex import rgb_to_hex

def test_basic_conversion():
"""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(255, 0, 0) == '#FF0000'
assert rgb_to_hex(0, 255, 0) == '#00FF00'
assert rgb_to_hex(0, 0, 255) == '#0000FF'

def test_mixed_colors():
"""Test mixed color conversions"""
assert rgb_to_hex(128, 128, 128) == '#808080'
assert rgb_to_hex(173, 216, 230) == '#ADD8E6'

def test_edge_cases():
"""Test boundary values"""
assert rgb_to_hex(0, 0, 0) == '#000000'
assert rgb_to_hex(255, 255, 255) == '#FFFFFF'

def test_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)

# 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])
38 changes: 38 additions & 0 deletions tests/test_string_reversal.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
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_special_chars():
"""Test reversal of string with special characters."""
assert reverse_string("a1b2c3!@#") == "#@!3c2b1a"

def test_reverse_string_with_mixed_chars():
"""Test reversal of string with mixed character types."""
assert reverse_string("Hello, World! 123") == "321 !dlroW ,olleH"

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(["list"])
Loading