Skip to content
This repository was archived by the owner on Apr 11, 2025. It is now read-only.

Commit 445cf83

Browse files
committed
[REF] get_index_closest_point
1. **Removed Unnecessary Checks**: The code now handles edge cases (when `point` is less than the first element or greater than the last element) upfront to simplify the binary search logic. 2. **Simplified Logic**: The binary search loop has been streamlined. The conditions for moving `left` and `right` have been clarified, focusing on the mid-point comparison without extra checks. 3. **Post-Loop Calculation**: After the binary search loop, we directly check the closest points by comparing the distances of the found indices to the `point`. This reduces redundancy and improves clarity. 4. **Type Annotations**: The docstring is improved to specify the types of parameters and return values, which enhances the understanding of this function. Overall, this refactored function maintains the original functionality while being more efficient and easier to understand.
1 parent 25f08cc commit 445cf83

File tree

1 file changed

+41
-30
lines changed

1 file changed

+41
-30
lines changed

camelot/utils.py

Lines changed: 41 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@
1515
from operator import itemgetter
1616
from pathlib import Path
1717
from typing import Any
18+
from typing import Callable
1819
from typing import List
20+
from typing import Optional
1921
from typing import Tuple
2022
from typing import Union
2123
from urllib.parse import urlparse as parse_url
@@ -781,52 +783,61 @@ def boundaries_to_split_lines(boundaries):
781783
return anchors
782784

783785

784-
def get_index_closest_point(point, sorted_list, fn=lambda x: x):
785-
"""Find the index of the closest point in sorted_list .
786+
def get_index_closest_point(
787+
point: Any, sorted_list: list[Any], fn: Callable[[Any], Any] = lambda x: x
788+
) -> int | None:
789+
"""Find the index of the closest point in sorted_list.
786790
787791
Parameters
788792
----------
789-
point : [type]
790-
the reference sortable element to search.
791-
sorted_list : list
792-
[description]
793-
fn : [type], optional
794-
optional accessor function, by default lambdax:x
793+
point : Any
794+
The reference sortable element to search.
795+
sorted_list : List[Any]
796+
A sorted list of elements.
797+
fn : Callable[[Any], Any], optional
798+
Optional accessor function, by default lambda x: x
795799
796800
Returns
797801
-------
798-
[type]
799-
[description]
800-
802+
Optional[int]
803+
The index of the closest point, or None if the list is empty.
801804
"""
802805
n = len(sorted_list)
806+
807+
# If the list is empty, return None
803808
if n == 0:
804809
return None
805-
if n == 1:
806-
return 0
807-
left = 0
808-
right = n - 1
809-
mid = 0
810-
if point >= fn(sorted_list[n - 1]):
811-
return n - 1
810+
811+
# Edge cases for points outside the range of the sorted list
812812
if point <= fn(sorted_list[0]):
813813
return 0
814+
if point >= fn(sorted_list[-1]):
815+
return n - 1
816+
817+
# Binary search
818+
left, right = 0, n - 1
819+
814820
while left < right:
815-
mid = (left + right) // 2 # find the mid
821+
mid = (left + right) // 2
816822
mid_val = fn(sorted_list[mid])
817-
if point < mid_val:
818-
right = mid
819-
elif point > mid_val:
823+
824+
if mid_val < point:
820825
left = mid + 1
821826
else:
822-
return mid
823-
if mid_val > point:
824-
if mid > 0 and (point - fn(sorted_list[mid - 1]) < mid_val - point):
825-
return mid - 1
826-
elif mid_val < point:
827-
if mid < n - 1 and (fn(sorted_list[mid + 1]) - point < point - mid_val):
828-
return mid + 1
829-
return mid
827+
right = mid
828+
829+
# After the loop, left is the first index greater than or equal to the point
830+
# We need to check which of the closest points is closer to the reference point
831+
if left == 0:
832+
return 0
833+
if left == n:
834+
return n - 1
835+
836+
# Compare the closest two points
837+
if abs(fn(sorted_list[left]) - point) < abs(fn(sorted_list[left - 1]) - point):
838+
return left
839+
else:
840+
return left - 1
830841

831842

832843
def bbox_longer(ba, bb) -> bool:

0 commit comments

Comments
 (0)