Programming intro book ch1 and ch2 (Windows/Python 3) - Request For Comments

Alf P. Steinbach alfps at start.no
Fri Dec 18 19:25:48 EST 2009


* Mensanator:
>> The second deviation is that since most names are constants,
> 
> Really? Does that mean you don't use literals, to save the time
> required to convert them to integers? Isn't that done at compile
> time?
> 
> So, instead of doing the Collatz Conjecture as
> 
> while a>1:
>   f = gmpy.scan1(a,0)
>   if f>0:
>     a = a >> f
>   else:
>     a = a*3 + 1
> 
> You would do this?
> 
> zed = 0
> one = 1
> two = 2
> twe = 3
> while a>one:
>   f = gmpy.scan1(a,zed)
>   if f>zed:
>     a = a >> f
>   else:
>     a = a*twe + one

That seems to have no relation to what you quoted / responded to.

On the other hand, if there is some specific rôle played by the 3 above, where 
some other value (like e.g. 5) might be used instead, then a self descriptive 
name for that rôle might be good.

Such reasonable naming (not what you did above) then allows easier modification 
of and makes it easier to understand the code.

That said, and a bit off-tangent to your comment's main thrust, the time spent 
on coding that repeated-division-by-2 optimization would, I think, be better 
spent googling "Collatz Conjecture"  --  avoiding writing /any/ code. ;-)


> Does this really save any time?

If by "it" you mean the silly naming, no it doesn't.

On the contrary, it wastes time, both for writing the code and reading it.

Generally, IMO, think about the clarity of your code. If naming something 
increases clarity, then name the thing. If it doesn't increase clarity, don't.


> Now, it's a different story if you're using the gmpy module.
> You DON'T want to use literals in loops involving gmpy, because
> they would have to be coerced to .mpz's on every pass through the
> loop.
> 
> In that case, you DO want to use constants as opposed to literals:
> 
> ZED = gmpy.mpz(0)
> ONE = gmpy.mpz(1)
> TWO = gmpy.mpz(2)
> TWE = gmpy.mpz(3)
> while a>ONE:
>   f = gmpy.scan1(a,0) # int used here, so it can be a literal
>   if f>ZED:
>     a = a >> f
>   else:
>     a = a*TWE + ONE
> 
> And yes, the time savings can be tremendous, especially when 'a'
> has over 50,000 decimal digits.

Yeah, good point. Few languages have compile time evaluation of logically 
constant expressions. C++0x will have that feature (called 'constexpr' IIRC) but 
in Python, current C++ etc. it's just a good idea to precompute values, and name 
them, rather than computing them again and again where they're needed.


> . I do not follow PEP
>> 8's recommendation to use uppercase names of constants. In fact almost no Python
>> code does,
> 
> Mine does when I use gmpy. Otherwise, the notion that "most names
> are constants" is generally false.

No, it depends on what you mean by "constant". The problem with Python, as 
Google noted, is that the language is so excessively dynamic: even names of 
routines are variables, and there /are/ no named user defined constants except 
logically, in the programmer's mind. And logically (that is, at the "in the 
programmer's mind" level), if you define "constant" as a name whose value will 
not change after initialization, then routine names are constants.

However, if you define "constant" as only a global scope (that is, module scope) 
name that denotes a boolean, numerical or string or Null value and that doesn't 
change after initialization, then your statement about the scarcity of constants 
appears to be true, but using a practically useless definition.

I think for such constants exported by modules it's a good idea to at least 
provide uppercase names so as conform to very firmly established convention. 
There might even be tools that rely on that convention. But for application code 
the uppercase names are just distracting, and they don't help you...


Cheers & hth.,

- Alf



More information about the Python-list mailing list