2
\$\begingroup\$

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.

\$\endgroup\$
  • \$\begingroup\$ @Morwenn Python 3 \$\endgroup\$ – wannik Aug 20 '15 at 10:18
3
\$\begingroup\$

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.

\$\endgroup\$
3
\$\begingroup\$

Bug

I see no justification for or half - start < eps. With that, you no longer guarantee that the return value is a root of f.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.