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