Easy function, please help.
Ethan Furman
ethan at stoneleaf.us
Thu Feb 10 17:52:38 CET 2011
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~
More information about the Python-list
mailing list