Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
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 index of 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 if input is a list
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

# Decide which half to search
if arr[mid] < target:
left = mid + 1
else:
right = mid - 1

# Target not found
return -1
42 changes: 42 additions & 0 deletions tests/test_binary_search.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import pytest
from src.binary_search import binary_search

def test_binary_search_found():
"""Test finding an existing element in the 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 searching for elements not in the list"""
arr = [1, 3, 5, 7, 9, 11, 13]
assert binary_search(arr, 0) == -1
assert binary_search(arr, 14) == -1
assert binary_search(arr, 6) == -1

def test_binary_search_empty_list():
"""Test searching in an empty list"""
assert binary_search([], 5) == -1

def test_binary_search_single_element():
"""Test searching in a list with a single element"""
assert binary_search([5], 5) == 0
assert binary_search([5], 6) == -1

def test_binary_search_invalid_input():
"""Test error handling for invalid inputs"""
# Test non-list input
with pytest.raises(TypeError, match="Input must be a list"):
binary_search("not a list", 5)

# Test unsorted list
with pytest.raises(ValueError, match="Input list must be sorted in ascending order"):
binary_search([5, 3, 1], 3)

def test_binary_search_duplicates():
"""Test behavior with lists containing duplicates"""
arr = [1, 2, 2, 3, 3, 3, 4, 4, 5]
# Note: with multiple matches, it returns the first (lowest) index
assert binary_search(arr, 3) in [3, 4, 5]
assert binary_search(arr, 4) in [6, 7]