Jason Swails wrote:
On Wed, Feb 9, 2011 at 8:16 PM, Ethan Furman wrote:
    while n:  is plenty readable.  n is either something or nothing, and
    something evaluates to True, nothing to False.

Sure it's readable. But then you have to make sure that the loop will eventually take n down to 0.

Sure, but the same holds true with 'while n != 0' -- you have to make sure the loop will eventually take n down to 0.

You can always *assume* that the programmer knew what they were doing (not an assumption I'm typically willing to make on code that's not my own).

Hopefully not something you have to deal with unless you're debugging...

How is "while n != 0:" any worse? (or abs(n) < tolerance). It has exactly the same effect without adding any code while at the same time directly communicates the intended conditional. IMO it makes reading the code easier to read barring effective documentation (my experience with people documenting their code is that they don't; at least in my field). "while n != 0" makes my life easier.

In that instance (a bunch of mathematical functions), I can easily see using that construct.

The fact that the proposed loop finished with *nothing* was coincidental. What if he had been doing some type of prime factorization or something where each iteration reduced the number until eventually all you were left with was the multiplicative identity? You'd say (correctly) that obviously the same approach won't work, but in some lines of thought it's a logical extension to use the same construct (especially to those that don't fully understand why the original loop exits in the first place). Expanding the conditional a little can only help IMO.

Thank you for making my argument for me -- you have to understand the tool you are using to make the best use of it.

        def num_digits(n):
          return len(str(n).replace('-','').replace('.',''))

        Or typecast to an int if you want to neglect decimals before
        converting to a string, etc.

        Or use recursion!

         >>> def num_digits(n):
        ...    if n == 0:
        ...       return 0
        ...    else:
        ...       return num_digits(n//10) + 1
        ...
         >>> num_digits(1)
        1
         >>> num_digits(0)
        0


    0 is still one digit.  ;)


Well that is something; yet only nothing evaluates to False. We seem to be at an impasse :).

I fail to see how a faulty algorithm puts us at an impasse. To tweak your code:

--> def num_digits(n, _first_pass=True):
-->     if n == 0:
-->         return int(_first_pass)
-->     else:
-->         return num_digits(n//10, _first_pass=False) + 1

correctly handles the special case of zero. To use my style, it would look like:

--> def num_digits(n, _first_pass=True):
-->     if n:
-->         return num_digits(n//10, _first_pass=False) + 1
-->     else:
-->         return int(_first_pass)

And, of course, this only works for non-negative integers. (I'll leave the discussion of whether zero is non-negative to others. ;) As I said earlier, I can see using the 'if n == 0' construct in certain situations, and if the non-zero branch were lengthy I would stick with the first version here.

~Ethan~
--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to