Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #55786 > unrolled thread
| Started by | Nanderson <mandersonrandersonanderson@gmail.com> |
|---|---|
| First post | 2011-02-08 21:52 -0800 |
| Last post | 2011-02-09 07:08 +0000 |
| Articles | 7 — 6 participants |
Back to article view | Back to comp.lang.python
Easy function, please help. Nanderson <mandersonrandersonanderson@gmail.com> - 2011-02-08 21:52 -0800
Re: Easy function, please help. "Littlefield, Tyler" <tyler@tysdomain.com> - 2011-02-09 17:41 -0700
Re: Easy function, please help. rantingrick <rantingrick@gmail.com> - 2011-02-09 06:51 -0800
Re: Easy function, please help. Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2011-02-11 02:08 +0000
Re: Easy function, please help. alex23 <wuwei23@gmail.com> - 2011-02-10 19:34 -0800
Re: Easy function, please help. rantingrick <rantingrick@gmail.com> - 2011-02-10 11:47 -0800
Re: Easy function, please help. Paul Rudin <paul.nospam@rudin.co.uk> - 2011-02-09 07:08 +0000
| From | Nanderson <mandersonrandersonanderson@gmail.com> |
|---|---|
| Date | 2011-02-08 21:52 -0800 |
| Subject | Easy function, please help. |
| Message-ID | <8e0efff7-4d38-4a85-9653-2178388603d4@y36g2000pra.googlegroups.com> |
def num_digits(n):
count = 0
while n:
count = count + 1
n = n / 10
return count
This is a function that basically says how many digits are in a
number. For example,
>>>print num_digits(44)
2
>>>print num_digits(7654)
4
This function counts the number of decimal digits in a positive
integer expressed in decimal format. I get this function ALMOST
completely. The only thing I don't understand is why it eventually
exits the loop, and goes off to the second branch. "while n" is
confusing me. What I am thinking is that if someone puts "while n" the
loop would be infinite. I get what is happening in the function, and I
understand why this would work, but for some reason it's confusing me
as to how it is exiting the loop after a certain number of times. Help
is appreciated, thanks.
[toc] | [next] | [standalone]
| From | "Littlefield, Tyler" <tyler@tysdomain.com> |
|---|---|
| Date | 2011-02-09 17:41 -0700 |
| Message-ID | <mailman.59.1297298519.1633.python-list@python.org> |
| In reply to | #55786 |
Uh oh, I think we found RR's evil twin: another python to the modern day visionary. >Example 1 is not explicit enough. Too much guessing is required by the >reader! if list is empty, bla. if not, bla. it's not all that hard, and there's no guessing that needs to take place, honest.
[toc] | [prev] | [next] | [standalone]
| From | rantingrick <rantingrick@gmail.com> |
|---|---|
| Date | 2011-02-09 06:51 -0800 |
| Message-ID | <c2cb4f8c-909e-4e47-b610-6d935c0c2ca1@w19g2000yqa.googlegroups.com> |
| In reply to | #55786 |
On Feb 9, 1:08 am, Paul Rudin <paul.nos...@rudin.co.uk> wrote:
> Nanderson <mandersonrandersonander...@gmail.com> writes:
> > loop would be infinite. I get what is happening in the function, and I
> > understand why this would work, but for some reason it's confusing me
> > as to how it is exiting the loop after a certain number of times. Help
> > is appreciated, thanks.
>
> It works because 0 tests false and because integer division yields
> integers... eventually you'll get something like 1/10 giving 0.
It works because of a design flaw in the language! Specifically i am
referring to treating the integer 0 as False and any other integers as
True. There is also the empty vs non empty containers that work this
way besides numeric types.
----------------------------------
Python 3.1.1 Interactive Session
----------------------------------
>>> bool(0)
False
>>> bool(1)
True
>>> bool(-1)
True
>>> bool(-1.0)
True
>>> bool(1.0)
True
>>> bool(0.0)
False
>>> bool([])
False
>>> bool([1])
True
Sure it *seems* like a "bright" idea at first however later you find
out this sort of laziness just induces more subtle bugs in code.
Python3000 fixed a lot of warts in Python2.x HOWEVER, python3000 did
not go near far enough! We need more radical changes (and when i say
radical i mean removing poorly thought out design patterns like this
"boolean emulation"!) to the language before python will be a truly
21st century language.
We should have never written code like this...
------------
Example 1:
------------
# lst = []
if lst:
blah
if not lst:
blah
Example 1 is not explicit enough. Too much guessing is required by the
reader!
-----------
Example 2
-----------
if lst.lengh > 0:
blah
if not lst.empty():
blah
if not empty(lst):
blah
Example 2 is just explicit enough so that the reader knows *exactly*
what is happening! We don't want to be redundantly explicit, however
we sure as *hell* don't want to be implicit! Hmm, believe i read that
somewhere once... import this!
The point is NEVER use an integer in place of a boolean! And i am NOT
blaming the OP here, no! I am blaming who ever came up with this
idiotic "emulation of booleans" crap! And don't tell me... "Well C did
it first we were just following by example"... because you just make
yourself out to be even a bigger idiot!
Here is another example of bad habits passed down from "on high".
def is_foo():
if something:
return 1
return 0
Why the HELL are you retuning integers in an obviously boolean
function? Are you trying to win Pearl hacker of the year award? Please
folks, always remember... NEVER emulate booleans, always use True/
False for boolean behaviors.
def is_foo():
if something:
return True
return False
*school-bell*
[toc] | [prev] | [next] | [standalone]
| From | Steven D'Aprano <steve+comp.lang.python@pearwood.info> |
|---|---|
| Date | 2011-02-11 02:08 +0000 |
| Message-ID | <4d549a25$0$29974$c3e8da3$5496439d@news.astraweb.com> |
| In reply to | #55894 |
On Thu, 10 Feb 2011 12:01:57 -0500, Terry Reedy wrote: > On 2/10/2011 11:52 AM, Ethan Furman wrote: >> Jason Swails wrote: > > >>> How is "while n != 0:" any worse? > > 1. It is redundant, just like 'if bool_value is not False:'. Python > programmers should understand the null value idiom. I find that if statement too implicit for my tastes. I prefer to be explicit about the values returned by comparisons, rather than just assume that the reader understands Python's comparisons. Unfortunately, I never know when to stop. if bool_value is not False is True is True is True is True is ... -- Steven
[toc] | [prev] | [next] | [standalone]
| From | alex23 <wuwei23@gmail.com> |
|---|---|
| Date | 2011-02-10 19:34 -0800 |
| Message-ID | <559d4363-c663-4924-823e-ef5866842985@n16g2000prc.googlegroups.com> |
| In reply to | #55894 |
rantingrick <rantingr...@gmail.com> wrote: > 1. When has 2 bytecode instructions EVER out weighed a solid > readability feature's incorporation into Python? The original point was whether or not the code is identical, which Terry showed it was not. > The load constant should only happen once. The > COMPARE_OP could be called "an extra step" but such a little problem > can easily be optimized away on the CPython side of things. Looking forward to seeing your patch.
[toc] | [prev] | [next] | [standalone]
| From | rantingrick <rantingrick@gmail.com> |
|---|---|
| Date | 2011-02-10 11:47 -0800 |
| Message-ID | <badc5427-8e1e-4d29-930b-4ffaa3a06599@z3g2000prz.googlegroups.com> |
| In reply to | #55894 |
On Feb 10, 11:01 am, Terry Reedy <tjre...@udel.edu> wrote: > On 2/10/2011 11:52 AM, Ethan Furman wrote: > > > Jason Swails wrote: > >> How is "while n != 0:" any worse? > > 1. It is redundant, just like 'if bool_value is not False:'. > Python programmers should understand the null value idiom. > > 2. It does 2 comparisons, 1 unneeded, instead of 1. For CPython, > it adds 2 unnecessary bytecode instructions and takes longer. > > >>> from dis import dis > >>> def f(n): > while n: pass > > >>> dis(f) > 2 0 SETUP_LOOP 10 (to 13) > >> 3 LOAD_FAST 0 (n) > 6 POP_JUMP_IF_FALSE 12 > 9 JUMP_ABSOLUTE 3 > >> 12 POP_BLOCK > >> 13 LOAD_CONST 0 (None) > 16 RETURN_VALUE > >>> def f(n): > while n != 0: pass > > >>> dis(f) > 2 0 SETUP_LOOP 16 (to 19) > >> 3 LOAD_FAST 0 (n) > 6 LOAD_CONST 1 (0) > 9 COMPARE_OP 3 (!=) > 12 POP_JUMP_IF_FALSE 18 > 15 JUMP_ABSOLUTE 3 > >> 18 POP_BLOCK > >> 19 LOAD_CONST 0 (None) > 22 RETURN_VALUE > > >> It has exactly the same effect without adding any code > > Untrue, see above. Overblown. See below! Terry i apologize for saying this but you offer a *really* weak argument here. The load constant should only happen once. The COMPARE_OP could be called "an extra step" but such a little problem can easily be optimized away on the CPython side of things. It is obvious that POP_JUMP_IF_FALSE is optimized for boolean comparisons. And even if you throw out my fine solution... 1. When has 2 bytecode instructions EVER out weighed a solid readability feature's incorporation into Python? 2. How many zillions of iterations would it take to notice even a *microscopic* speed reduction? Remember, Python IS "first and foremost" the language of readability. Why do you think indention is enforced? Why do think the number of built-in methods is kept small? Why do think magic methods are wrapped in leading and trailing double underscores? Why do you think the keyword set is simplistic and small? Why? Why? Why? i could go on all day... Terry, *we* are the shining jewel of coherency in a dark sea polluted with multiplicity which is violently agitated by syntactical asininity.
[toc] | [prev] | [next] | [standalone]
| From | Paul Rudin <paul.nospam@rudin.co.uk> |
|---|---|
| Date | 2011-02-09 07:08 +0000 |
| Message-ID | <87oc6l8z1y.fsf@rudin.co.uk> |
| In reply to | #55786 |
Nanderson <mandersonrandersonanderson@gmail.com> writes: > loop would be infinite. I get what is happening in the function, and I > understand why this would work, but for some reason it's confusing me > as to how it is exiting the loop after a certain number of times. Help > is appreciated, thanks. It works because 0 tests false and because integer division yields integers... eventually you'll get something like 1/10 giving 0. It's not necessarily a good thing to rely on. For example if you try it after "from __future__ import division" - or in python 3 - you'll get a float as the result of the division and it won't test False.
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.python
csiph-web