1
+ #!/usr/bin/env python3
2
+
1
3
"""
2
4
This is pure Python implementation of binary search algorithms
3
5
4
6
For doctests run following command:
5
- python -m doctest -v binary_search.py
6
- or
7
7
python3 -m doctest -v binary_search.py
8
8
9
9
For manual testing run:
10
- python binary_search.py
10
+ python3 binary_search.py
11
11
"""
12
12
import bisect
13
+ from typing import List , Optional
13
14
14
15
15
- def bisect_left (sorted_collection , item , lo = 0 , hi = None ):
16
+ def bisect_left (
17
+ sorted_collection : List [int ], item : int , lo : int = 0 , hi : int = - 1
18
+ ) -> int :
16
19
"""
17
20
Locates the first element in a sorted array that is larger or equal to a given
18
21
value.
@@ -43,7 +46,7 @@ def bisect_left(sorted_collection, item, lo=0, hi=None):
43
46
>>> bisect_left([0, 5, 7, 10, 15], 6, 2)
44
47
2
45
48
"""
46
- if hi is None :
49
+ if hi < 0 :
47
50
hi = len (sorted_collection )
48
51
49
52
while lo < hi :
@@ -56,7 +59,9 @@ def bisect_left(sorted_collection, item, lo=0, hi=None):
56
59
return lo
57
60
58
61
59
- def bisect_right (sorted_collection , item , lo = 0 , hi = None ):
62
+ def bisect_right (
63
+ sorted_collection : List [int ], item : int , lo : int = 0 , hi : int = - 1
64
+ ) -> int :
60
65
"""
61
66
Locates the first element in a sorted array that is larger than a given value.
62
67
@@ -86,7 +91,7 @@ def bisect_right(sorted_collection, item, lo=0, hi=None):
86
91
>>> bisect_right([0, 5, 7, 10, 15], 6, 2)
87
92
2
88
93
"""
89
- if hi is None :
94
+ if hi < 0 :
90
95
hi = len (sorted_collection )
91
96
92
97
while lo < hi :
@@ -99,7 +104,9 @@ def bisect_right(sorted_collection, item, lo=0, hi=None):
99
104
return lo
100
105
101
106
102
- def insort_left (sorted_collection , item , lo = 0 , hi = None ):
107
+ def insort_left (
108
+ sorted_collection : List [int ], item : int , lo : int = 0 , hi : int = - 1
109
+ ) -> None :
103
110
"""
104
111
Inserts a given value into a sorted array before other values with the same value.
105
112
@@ -140,7 +147,9 @@ def insort_left(sorted_collection, item, lo=0, hi=None):
140
147
sorted_collection .insert (bisect_left (sorted_collection , item , lo , hi ), item )
141
148
142
149
143
- def insort_right (sorted_collection , item , lo = 0 , hi = None ):
150
+ def insort_right (
151
+ sorted_collection : List [int ], item : int , lo : int = 0 , hi : int = - 1
152
+ ) -> None :
144
153
"""
145
154
Inserts a given value into a sorted array after other values with the same value.
146
155
@@ -181,7 +190,7 @@ def insort_right(sorted_collection, item, lo=0, hi=None):
181
190
sorted_collection .insert (bisect_right (sorted_collection , item , lo , hi ), item )
182
191
183
192
184
- def binary_search (sorted_collection , item ) :
193
+ def binary_search (sorted_collection : List [ int ] , item : int ) -> Optional [ int ] :
185
194
"""Pure implementation of binary search algorithm in Python
186
195
187
196
Be careful collection must be ascending sorted, otherwise result will be
@@ -219,7 +228,7 @@ def binary_search(sorted_collection, item):
219
228
return None
220
229
221
230
222
- def binary_search_std_lib (sorted_collection , item ) :
231
+ def binary_search_std_lib (sorted_collection : List [ int ] , item : int ) -> Optional [ int ] :
223
232
"""Pure implementation of binary search algorithm in Python using stdlib
224
233
225
234
Be careful collection must be ascending sorted, otherwise result will be
@@ -248,7 +257,9 @@ def binary_search_std_lib(sorted_collection, item):
248
257
return None
249
258
250
259
251
- def binary_search_by_recursion (sorted_collection , item , left , right ):
260
+ def binary_search_by_recursion (
261
+ sorted_collection : List [int ], item : int , left : int , right : int
262
+ ) -> Optional [int ]:
252
263
253
264
"""Pure implementation of binary search algorithm in Python by recursion
254
265
@@ -286,41 +297,12 @@ def binary_search_by_recursion(sorted_collection, item, left, right):
286
297
return binary_search_by_recursion (sorted_collection , item , midpoint + 1 , right )
287
298
288
299
289
- def __assert_sorted (collection ):
290
- """Check if collection is ascending sorted, if not - raises :py:class:`ValueError`
291
-
292
- :param collection: collection
293
- :return: True if collection is ascending sorted
294
- :raise: :py:class:`ValueError` if collection is not ascending sorted
295
-
296
- Examples:
297
- >>> __assert_sorted([0, 1, 2, 4])
298
- True
299
-
300
- >>> __assert_sorted([10, -1, 5])
301
- Traceback (most recent call last):
302
- ...
303
- ValueError: Collection must be ascending sorted
304
- """
305
- if collection != sorted (collection ):
306
- raise ValueError ("Collection must be ascending sorted" )
307
- return True
308
-
309
-
310
300
if __name__ == "__main__" :
311
- import sys
312
-
313
301
user_input = input ("Enter numbers separated by comma:\n " ).strip ()
314
- collection = [int (item ) for item in user_input .split ("," )]
315
- try :
316
- __assert_sorted (collection )
317
- except ValueError :
318
- sys .exit ("Sequence must be ascending sorted to apply binary search" )
319
-
320
- target_input = input ("Enter a single number to be found in the list:\n " )
321
- target = int (target_input )
302
+ collection = sorted (int (item ) for item in user_input .split ("," ))
303
+ target = int (input ("Enter a single number to be found in the list:\n " ))
322
304
result = binary_search (collection , target )
323
- if result is not None :
324
- print (f"{ target } found at positions: { result } " )
305
+ if result is None :
306
+ print (f"{ target } was not found in { collection } . " )
325
307
else :
326
- print ("Not found" )
308
+ print (f" { target } was found at position { result } in { collection } . " )
0 commit comments