On Mon, 03 Jun 2013 18:37:24 -0700, Rick Johnson wrote: > On Sunday, June 2, 2013 1:58:30 PM UTC-5, Steven D'Aprano wrote: >> On Sun, 02 Jun 2013 10:04:00 -0700, Rick Johnson wrote:
>> > A "wise programmer" may think he's solved the problem by writing a >> > function called "debugprint" that looks like this: >> > > def debugprint(*args): >> > if DEBUG == True: >> > print(*args) >> >> No no no, that's not how you do it. It should be: >> if DEBUG == True == True: >> >> Wait, no, I got that wrong. It should be: >> if DEBUG == True == True == True: >> >> Hang on, I've nearly got it! >> if DEBUG == True == True == True == True: >> >> Or, you could program like a professional, and say: >> if DEBUG: > > Obviously you don't appreciate the value of "explicit enough". > > if VALUE: > > is not explicit enough, however Consider a simple thought experiment. Suppose we start with a sequence of if statements that begin simple and get more complicated: if a == 1: ... if a == 1 and b > 2*c: ... if a == 1 and b > 2*c or d%4 == 1: ... if a == 1 and b > 2*c or d%4 == 1 and not (d**3//7)%3 == 0: ... I don't believe that any of these tests are improved by adding an extraneous "== True" at the end: if (a == 1) == True: ... if (a == 1 and b > 2*c) == True: ... if (a == 1 and b > 2*c or d%4 == 1) == True: ... if (a == 1 and b > 2*c or d%4 == 1 and not (d**3//7)%3 == 0) == True: ... At some point your condition becomes so complicated that you may wish to save it as a separate variable, or perhaps you need to check the flag in a couple of places and so calculate it only once. Moving the flag out into a separate variable doesn't make "== True" any more useful or helpful. flag = a == 1 if flag == True: ... But even if it did, well, you've just entered the Twilight Zone, because of course "flag == True" is just a flag, so it too needs to be tested with "== True": flag = (a == 1) == True if flag == True: ... but that too is just a flag so it needs more "explicitness"... and so on forever. This conclusion is of course nonsense. Adding "== True" to your boolean tests isn't helpful, so there's no need for even one, let alone an infinite series of "== True". "if flag" is as explicit as it needs to be. There's no need to artificially inflate the "explicitness" as if being explicit was good in and of itself. We don't normally write code like this: n += int(1) just to be explicit about 1 being an int. That would be redundant and silly. In Python, 1 *is* an int. [...] > if lst: > > I don't like that because it's too implict. What exactly about the list > are we wanting to test? If you are unfamiliar with Python, then you have to learn what the semantics of "if lst" means. Just as you would have to learn what "if len(lst) > 0" means. > I prefer to be explicit at the cost of a few keystrokes: > > if len(lst) > 0: This line of code is problematic, for various reasons: - you're making assumptions about the object which are unnecessary; - which breaks duck-typing; - and risks doing too much work, or failing altogether. You're looking up the length of the lst object, but you don't really care about the length. You only care about whether there is something there or not, whether lst is empty or not. It makes no difference whether lst contains one item or one hundred million items, and yet you're asking to count them all. Only to throw that count away immediately! Looking at the length of a built-in list is cheap, but why assume it is a built-in list? Perhaps it is a linked list where counting the items requires a slow O(N) traversal of the entire list. Or some kind of lazy sequence that has no way of counting the items remaining, but knows whether it is exhausted or not. The Python way is to duck-type, and to let the lst object decide for itself whether it's empty or not: if lst: ... not to make assumptions about the specific type and performance of the object. > Consider the following: > > What if the symbol `value` is expected to be a list, however, somehow > it accidentally got reassigned to another type. If i choose to be > implicit and use: "if value", the code could silently work for a type i > did not intend, therefore the program could go on for quite some time > before failing suddenly on attribute error, or whatever. `if len(lst) > 0` also works for types you don't intend. Any type that defines a __len__ method which returns an integer will do it. Tuples, sets and dicts are just the most obvious examples of things that support len() but do not necessarily support all the things you might wish to do to a list. > However, if i choose to be explicit and use: > > "if len(VALUE) > 0: > > then the code will fail when it should: at the comparison line. Except of course when it doesn't. > Because > any object that does not provide a __len__ method would cause Python to > raise NameError. TypeError. > By being "explicit enough" i will inject readability and safety into my > code base. Unnecessary verbosity and redundancy, unnecessary restrictions on the type of the object, and unjustifiable assumptions about the cost of calling len(). -- Steven -- http://mail.python.org/mailman/listinfo/python-list