return ''.join(map(lambda h: '%02x' % ord(h), x))
+def bisect(fset, limits=[0.0, 1.0], dgmin=None):
+ """Given a one-input function fset and list of limits, interactively bisect
+ the range by sending fset(guess) and asking to go (u)p or (d)own for the
+ next step. Each stepsize is progressively halved and optionally limited to
+ dgmin if given."""
+ xmin = min(limits)
+ xmax = max(limits)
+ g = (xmax - xmin) / 2 + xmin
+ dg = (xmax - xmin) / 4
+ last = xmin
+
+ guess = [xmin, xmax]
+
+ quit = False
+ while quit == False:
+ print 'sending guess:', g, dg
+ guess.append(g)
+ fset(g)
+
+ a = raw_input('q, [u,k], [d,j] ? ').lower()
+ if a == 'q':
+ quit = True
+ return guess[2:]
+
+ if a in 'dj':
+ g = g - dg
+ elif a in 'uk':
+ g = g + dg
+ else:
+ print 'OOPS, expecting u or d only'
+
+ dg = dg / 2
+ # for ints, step size stops at 1
+ if isinstance(xmin, int):
+ dg = max(dg, 1)
+ elif dgmin is not None and dg < dgmin:
+ dg = dgmin
+
+
##############################################################################
# Setup FTDI serial ports