Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
34379a1
Add string reversal function implementation
labrocadabro Apr 21, 2025
bda1af3
Add comprehensive tests for string reversal function
labrocadabro Apr 21, 2025
fa43925
Implement string reversal without slice notation or reverse()
labrocadabro Apr 21, 2025
a9564da
Implement array flattening function
laura-abro Apr 21, 2025
65e0f92
Add comprehensive tests for array flattening function
laura-abro Apr 21, 2025
a8ca451
Add pytest to requirements
laura-abro Apr 21, 2025
3d789d3
Implement binary search function with comprehensive error handling
labrocadabro Apr 21, 2025
7d135bf
Add comprehensive tests for binary search implementation
labrocadabro Apr 21, 2025
0b25fce
Add URL parser function implementation
laura-abro Apr 21, 2025
ab2b1dd
Add comprehensive tests for URL parser function
laura-abro Apr 21, 2025
ee6d3e1
Add pytest to requirements
laura-abro Apr 21, 2025
a7a9168
Add RGB to Hex converter function
labrocadabro Apr 21, 2025
c0284af
Add comprehensive tests for RGB to Hex converter
labrocadabro Apr 21, 2025
5aef55c
Merged branch pr-241-momstrosity-builder-test for PR https://github.c…
momstrosity Apr 21, 2025
97300f2
Merged branch pr-242-momstrosity-builder-test for PR https://github.c…
momstrosity Apr 21, 2025
9b439a2
Merged branch pr-243-momstrosity-builder-test for PR https://github.c…
momstrosity Apr 21, 2025
cf50e9e
Merged branch pr-244-momstrosity-builder-test for PR https://github.c…
momstrosity Apr 21, 2025
e34aa21
Merged branch pr-245-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
37 changes: 37 additions & 0 deletions src/array_flattener.py
Original file line number Diff line number Diff line change
@@ -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
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 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
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 (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}"
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 without using slice notation or reverse().

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

# 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)
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 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)}")
43 changes: 43 additions & 0 deletions tests/test_array_flattener.py
Original file line number Diff line number Diff line change
@@ -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]
39 changes: 39 additions & 0 deletions tests/test_binary_search.py
Original file line number Diff line number Diff line change
@@ -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
35 changes: 35 additions & 0 deletions tests/test_rgb_to_hex.py
Original file line number Diff line number Diff line change
@@ -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])
34 changes: 34 additions & 0 deletions tests/test_string_reversal.py
Original file line number Diff line number Diff line change
@@ -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)
Loading