Skip to content

Commit 5378088

Browse files
authored
Merge pull request #6 from SergeyTsaplin/bin-search-pythonic
Bin search refactored pythonic way
2 parents 4c2c3c5 + ec6b64a commit 5378088

File tree

2 files changed

+129
-30
lines changed

2 files changed

+129
-30
lines changed

Diff for: BinarySeach.py

-30
This file was deleted.

Diff for: binary_seach.py

+129
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
"""
2+
This is pure python implementation of binary search algorithm
3+
4+
For doctests run following command:
5+
python -m doctest -v selection_sort.py
6+
or
7+
python3 -m doctest -v selection_sort.py
8+
9+
For manual testing run:
10+
python binary_search.py
11+
"""
12+
from __future__ import print_function
13+
import bisect
14+
15+
16+
def assert_sorted(collection):
17+
"""Check if collection is sorted. If not raises :py:class:`ValueError`
18+
19+
:param collection: collection
20+
:return: True if collection is sorted
21+
:raise: :py:class:`ValueError` if collection is not sorted
22+
23+
Examples:
24+
>>> assert_sorted([0, 1, 2, 4])
25+
True
26+
27+
>>> assert_sorted([10, -1, 5])
28+
Traceback (most recent call last):
29+
...
30+
ValueError: Collection must be sorted
31+
"""
32+
if collection != sorted(collection):
33+
raise ValueError('Collection must be sorted')
34+
return True
35+
36+
37+
def binary_search(sorted_collection, item):
38+
"""Pure implementation of binary search algorithm in Python
39+
40+
:param sorted_collection: some sorted collection with comparable items
41+
:param item: item value to search
42+
:return: index of found item or None if item is not found
43+
44+
Examples:
45+
>>> binary_search([0, 5, 7, 10, 15], 0)
46+
0
47+
48+
>>> binary_search([0, 5, 7, 10, 15], 15)
49+
4
50+
51+
>>> binary_search([0, 5, 7, 10, 15], 5)
52+
1
53+
54+
>>> binary_search([0, 5, 7, 10, 15], 6)
55+
56+
>>> binary_search([5, 2, 1, 5], 2)
57+
Traceback (most recent call last):
58+
...
59+
ValueError: Collection must be sorted
60+
"""
61+
assert_sorted(sorted_collection)
62+
left = 0
63+
right = len(sorted_collection) - 1
64+
65+
while left <= right:
66+
midpoint = (left + right) // 2
67+
current_item = sorted_collection[midpoint]
68+
if current_item == item:
69+
return midpoint
70+
else:
71+
if item < current_item:
72+
right = midpoint - 1
73+
else:
74+
left = midpoint + 1
75+
return None
76+
77+
78+
def binary_search_std_lib(sorted_collection, item):
79+
"""Pure implementation of binary search algorithm in Python using stdlib
80+
81+
:param sorted_collection: some sorted collection with comparable items
82+
:param item: item value to search
83+
:return: index of found item or None if item is not found
84+
85+
Examples:
86+
>>> binary_search_std_lib([0, 5, 7, 10, 15], 0)
87+
0
88+
89+
>>> binary_search_std_lib([0, 5, 7, 10, 15], 15)
90+
4
91+
92+
>>> binary_search_std_lib([0, 5, 7, 10, 15], 5)
93+
1
94+
95+
>>> binary_search_std_lib([0, 5, 7, 10, 15], 6)
96+
97+
>>> binary_search_std_lib([5, 2, 1, 5], 2)
98+
Traceback (most recent call last):
99+
...
100+
ValueError: Collection must be sorted
101+
"""
102+
assert_sorted(sorted_collection)
103+
index = bisect.bisect_left(sorted_collection, item)
104+
if index != len(sorted_collection) and sorted_collection[index] == item:
105+
return index
106+
return None
107+
108+
109+
if __name__ == '__main__':
110+
import sys
111+
# For python 2.x and 3.x compatibility: 3.x has not raw_input builtin
112+
# otherwise 2.x's input builtin function is too "smart"
113+
if sys.version_info.major < 3:
114+
input_function = raw_input
115+
else:
116+
input_function = input
117+
118+
user_input = input_function('Enter numbers separated by coma:\n')
119+
collection = [int(item) for item in user_input.split(',')]
120+
121+
target_input = input_function(
122+
'Enter a single number to be found in the list:\n'
123+
)
124+
target = int(target_input)
125+
result = binary_search(collection, target)
126+
if result is not None:
127+
print('{} found at positions: {}'.format(target, result))
128+
else:
129+
print('Not found')

0 commit comments

Comments
 (0)