Writing a binary search algorithm is surprisingly error-prone. The solution: trick the built-in bisect module into doing it for you.
The documentation for bisect says that it works on lists, but it really works on anything with a __getitem__ method. You can exploit this fact to make bisect work in ways that you may not have thought of.
Example: Using a library that controls a digital video camera, I wanted to do a poor-man's auto-exposure. The goal is to find the exposure time, in milliseconds, that makes the mean pixel value about 128 (out of 0 to 255).
The trick is to create an object that "looks like" a list to the bisect module.
1 2 3 4 5 6 7 8 9 10 11 12 13
import bisect class AutoExp: def __init__(self, camera): self.camera = camera def __getitem__(self, index): self.camera.setshutter(index) im = cam.getframe() # returns a numarray array return im.mean() def auto_expose(camera, target_mean=128): ms = bisect.bisect(AutoExp(camera), target_mean, 0, 1000) camera.setshutter(ms)