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
08038fb
Add string reversal function implementation
labrocadabro Apr 10, 2025
e7b54d9
Add comprehensive tests for string reversal function
labrocadabro Apr 10, 2025
b57d9d2
Fix test case for special characters string reversal
labrocadabro Apr 10, 2025
4896f70
Implement string reversal without using slice notation
labrocadabro Apr 10, 2025
fad30ea
Update tests for comprehensive string reversal testing
labrocadabro Apr 10, 2025
5aa8f24
Add array flattening function implementation
laura-abro Apr 10, 2025
3d33503
Add comprehensive tests for array flattening function
laura-abro Apr 10, 2025
da7a9ab
Add pytest to requirements
laura-abro Apr 10, 2025
57a8607
Update pytest version
laura-abro Apr 10, 2025
d0b1d56
Implement binary search function with error handling
labrocadabro Apr 10, 2025
877c2b3
Add comprehensive tests for binary search function
labrocadabro Apr 10, 2025
d1a1cc4
Add URL parser function implementation
laura-abro Apr 10, 2025
3d38aac
Add comprehensive tests for URL parser function
laura-abro Apr 10, 2025
9775b66
Fix URL parser to use empty strings for None values
laura-abro Apr 10, 2025
e15fa55
Add RGB to Hex converter implementation
labrocadabro Apr 10, 2025
f130e9f
Add comprehensive tests for RGB to Hex converter
labrocadabro Apr 10, 2025
23f7e55
Merged branch pr-181-momstrosity-builder-test for PR https://github.c…
momstrosity Apr 10, 2025
ea99581
Merged branch pr-182-momstrosity-builder-test for PR https://github.c…
momstrosity Apr 10, 2025
78f80c4
Merged branch pr-183-momstrosity-builder-test for PR https://github.c…
momstrosity Apr 10, 2025
31f5201
Merged branch pr-184-momstrosity-builder-test for PR https://github.c…
momstrosity Apr 10, 2025
8377e6a
Merged branch pr-185-momstrosity-builder-test for PR https://github.c…
momstrosity 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
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pytest==8.0.2
35 changes: 35 additions & 0 deletions src/array_flatten.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
from typing import List, Union

def flatten_array(arr: List[Union[int, List]]) -> List[int]:
"""
Recursively flatten a nested list of integers.

Args:
arr (List[Union[int, List]]): A potentially nested list of integers.

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

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]
>>> flatten_array([])
[]
"""
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(f"Invalid input: {item}. Only integers and lists are allowed.")

return flattened
47 changes: 47 additions & 0 deletions src/binary_search.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
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 input list is not sorted
"""
# Check input type
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")

# Empty list check
if not arr:
return -1

# Binary search implementation
left, right = 0, len(arr) - 1

while left <= right:
mid = (left + right) // 2

# Found the target
if arr[mid] == target:
return mid

# Target is in the left half
elif arr[mid] > target:
right = mid - 1

# Target is in the right half
else:
left = mid + 1

# Target not found
return -1
24 changes: 24 additions & 0 deletions src/rgb_to_hex.py
Original file line number Diff line number Diff line change
@@ -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 (6 characters)

Raises:
ValueError: If any color value is outside the range 0-255
"""
# Validate input values are within the valid range
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 component to a two-digit hex value
return ''.join(f'{c:02X}' for c in (r, g, b))
32 changes: 32 additions & 0 deletions src/string_reversal.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
def reverse_string(s: str) -> str:
"""
Reverses the given string using a manual character-by-character approach.

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

Returns:
str: The reversed string.

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

# Convert string to list of characters for manipulation
chars = list(s)

# Manual reversal using two-pointer technique
left, right = 0, len(chars) - 1
while left < right:
# Swap characters
chars[left], chars[right] = chars[right], chars[left]

# Move pointers
left += 1
right -= 1

# Convert back to string and return
return ''.join(chars)
45 changes: 45 additions & 0 deletions src/url_parser.py
Original file line number Diff line number Diff line change
@@ -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 parsed URL components.

Raises:
ValueError: If the input 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:
# Use urlparse to break down the URL
parsed = urlparse(url)

# Extract query parameters using parse_qs
query_params = parse_qs(parsed.query)
# Flatten single-item lists to their values
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.scheme or '', # Change to empty string if None
'netloc': parsed.netloc or '', # Change to empty string if None
'path': parsed.path or '', # Change to empty string if None
'params': parsed.params or None,
'query': query_params,
'fragment': parsed.fragment or '', # Change to empty string if None
'username': parsed.username,
'password': parsed.password,
'hostname': parsed.hostname,
'port': parsed.port
}
except Exception as e:
# Catch any unexpected parsing errors
raise ValueError(f"Error parsing URL: {str(e)}")
34 changes: 34 additions & 0 deletions tests/test_array_flatten.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import pytest
from src.array_flatten 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]) == [1, 2, 3, 4]

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_multiple_nested_lists():
"""Test flattening multiple nested lists."""
assert flatten_array([[1, 2], [3, [4, 5]], 6]) == [1, 2, 3, 4, 5, 6]

def test_invalid_input_raises_error():
"""Test that non-integer and non-list inputs raise a TypeError."""
with pytest.raises(TypeError):
flatten_array([1, 2, "3"])

with pytest.raises(TypeError):
flatten_array([1, 2, None])

def test_flatten_single_element_list():
"""Test flattening a list with a single nested list."""
assert flatten_array([1, [2], 3]) == [1, 2, 3]
48 changes: 48 additions & 0 deletions tests/test_binary_search.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import pytest
from src.binary_search import binary_search

def test_binary_search_normal_case():
"""Test binary search on a normal sorted list"""
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, 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"""
assert binary_search([5], 5) == 0
assert binary_search([5], 6) == -1

def test_binary_search_invalid_input():
"""Test error handling for invalid inputs"""
# Not a list
with pytest.raises(TypeError):
binary_search(123, 5)

# Unsorted list
with pytest.raises(ValueError):
binary_search([5, 3, 1], 3)

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

def test_binary_search_negative_numbers():
"""Test binary search with negative numbers"""
arr = [-5, -3, 0, 2, 4, 6]
assert binary_search(arr, -3) == 1
assert binary_search(arr, 0) == 2
assert binary_search(arr, 6) == 5
47 changes: 47 additions & 0 deletions tests/test_rgb_to_hex.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
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(148, 0, 211) == '9400D3'

def test_zero_values():
"""Test conversion with zero values"""
assert rgb_to_hex(0, 0, 0) == '000000'

def test_max_values():
"""Test conversion with maximum values"""
assert rgb_to_hex(255, 255, 255) == 'FFFFFF'

def test_mixed_values():
"""Test conversion with mixed color values"""
assert rgb_to_hex(123, 45, 67) == '7B2D43'

def test_invalid_low_values():
"""Test handling of values below 0"""
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, -1, 0)
with pytest.raises(ValueError, match="Blue value must be between 0 and 255"):
rgb_to_hex(0, 0, -1)

def test_invalid_high_values():
"""Test handling of values above 255"""
with pytest.raises(ValueError, match="Red value must be between 0 and 255"):
rgb_to_hex(256, 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, 256)

def test_invalid_type():
"""Test handling of non-integer 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, '255', 0)
with pytest.raises(TypeError, match="Blue value must be an integer"):
rgb_to_hex(0, 0, '255')
39 changes: 39 additions & 0 deletions tests/test_string_reversal.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
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 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_special_chars():
"""Test reversing a string with special characters."""
assert reverse_string("h3llo!") == "!oll3h"

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)

def test_reverse_string_unicode():
"""Test reversing unicode strings."""
assert reverse_string("café") == "éfac"

def test_reverse_string_mixed_characters():
"""Test reversing a string with mixed character types."""
assert reverse_string("a1b2c3!@#") == "#@!3c2b1a"
Loading