# Root-finding by iterated bisection

Both of the following code give the same result. But I'm not sure where should I put the raise statement.

def bisection(f, start, stop, eps = 1e-5, max_iteration = 100):
for __ in range(max_iteration):
half = start + (stop - start)/2
if abs(f(half)) < eps or half - start < eps:
return half
if f(half) * f(start) > 0:
start = half
else:
stop = half
else:
raise ValueError('Cannot find root in the given range')


Or

def bisection(f, start, stop, eps = 1e-5, max_iteration = 100):
for __ in range(max_iteration):
half = start + (stop - start)/2
if abs(f(half)) < eps or half - start < eps:
return half
if f(half) * f(start) > 0:
start = half
else:
stop = half

raise ValueError('Cannot find root in the given range')


P.S. I asked this question Stack Overflow and someone there suggested to ask it here.

• @Morwenn Python 3 – wannik Aug 20 '15 at 10:18

The two versions work exactly the same way, because the end of the loop will only be reached if the return is not executed.
However, the for ... else construct can be confusing. Everything else being equal, it's best to use the simplest technique that is unambiguous, perfectly clear to everyone, without further questions asked. So, go with the 2nd version, no need for the "clever" but potentially confusing for ... else construct here.
I see no justification for or half - start < eps. With that, you no longer guarantee that the return value is a root of f.