Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #25341 > unrolled thread

Implicit conversion to boolean in if and while statements

Started byAndrew Berg <bahamutzero8825@gmail.com>
First post2012-07-15 03:34 -0500
Last post2012-07-17 00:26 -0700
Articles 20 on this page of 74 — 17 participants

Back to article view | Back to comp.lang.python


Contents

  Implicit conversion to boolean in if and while statements Andrew Berg <bahamutzero8825@gmail.com> - 2012-07-15 03:34 -0500
    Re: Implicit conversion to boolean in if and while statements Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2012-07-15 10:56 +0000
      Re: Implicit conversion to boolean in if and while statements Ian Kelly <ian.g.kelly@gmail.com> - 2012-07-15 10:19 -0600
        Re: Implicit conversion to boolean in if and while statements Rick Johnson <rantingrickjohnson@gmail.com> - 2012-07-15 09:50 -0700
          Re: Implicit conversion to boolean in if and while statements Ian Kelly <ian.g.kelly@gmail.com> - 2012-07-15 12:01 -0600
            Re: Implicit conversion to boolean in if and while statements Rick Johnson <rantingrickjohnson@gmail.com> - 2012-07-15 11:56 -0700
              Re: Implicit conversion to boolean in if and while statements Chris Angelico <rosuav@gmail.com> - 2012-07-16 07:53 +1000
                Re: Implicit conversion to boolean in if and while statements Ranting Rick <rantingrickjohnson@gmail.com> - 2012-07-15 18:21 -0700
                  Re: Implicit conversion to boolean in if and while statements Chris Angelico <rosuav@gmail.com> - 2012-07-16 11:51 +1000
                    Re: Implicit conversion to boolean in if and while statements Ranting Rick <rantingrickjohnson@gmail.com> - 2012-07-15 19:31 -0700
                      Re: Implicit conversion to boolean in if and while statements Albert van der Horst <albert@spenarnc.xs4all.nl> - 2012-07-16 17:57 +0000
                        Re: Implicit conversion to boolean in if and while statements Dennis Lee Bieber <wlfraed@ix.netcom.com> - 2012-07-17 00:44 -0400
                  Re: Implicit conversion to boolean in if and while statements Devin Jeanpierre <jeanpierreda@gmail.com> - 2012-07-15 22:15 -0400
                    Re: Implicit conversion to boolean in if and while statements Ranting Rick <rantingrickjohnson@gmail.com> - 2012-07-15 19:58 -0700
                    Re: Implicit conversion to boolean in if and while statements Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2012-07-16 04:03 +0000
                      Re: Implicit conversion to boolean in if and while statements Ranting Rick <rantingrickjohnson@gmail.com> - 2012-07-15 21:53 -0700
                        Re: Implicit conversion to boolean in if and while statements Chris Angelico <rosuav@gmail.com> - 2012-07-16 15:57 +1000
                        Re: Implicit conversion to boolean in if and while statements alex23 <wuwei23@gmail.com> - 2012-07-16 00:21 -0700
                      Re: Implicit conversion to boolean in if and while statements Devin Jeanpierre <jeanpierreda@gmail.com> - 2012-07-17 00:18 -0400
                        Re: Implicit conversion to boolean in if and while statements Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2012-07-17 06:25 +0000
                          Re: Implicit conversion to boolean in if and while statements Devin Jeanpierre <jeanpierreda@gmail.com> - 2012-07-17 05:38 -0400
                  Re: Implicit conversion to boolean in if and while statements Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2012-07-16 02:58 +0000
                    Re: Implicit conversion to boolean in if and while statements Chris Angelico <rosuav@gmail.com> - 2012-07-16 13:05 +1000
                    Re: Implicit conversion to boolean in if and while statements Ranting Rick <rantingrickjohnson@gmail.com> - 2012-07-15 20:21 -0700
                      Re: Implicit conversion to boolean in if and while statements Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2012-07-16 04:20 +0000
                        Re: Implicit conversion to boolean in if and while statements Ranting Rick <rantingrickjohnson@gmail.com> - 2012-07-15 22:03 -0700
                          Re: Implicit conversion to boolean in if and while statements Chris Angelico <rosuav@gmail.com> - 2012-07-16 16:00 +1000
                          Re: Implicit conversion to boolean in if and while statements alex23 <wuwei23@gmail.com> - 2012-07-16 00:27 -0700
                          Re: Implicit conversion to boolean in if and while statements Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2012-07-16 07:52 +0000
                          Re: Implicit conversion to boolean in if and while statements Laszlo Nagy <gandalf@shopzeus.com> - 2012-07-16 23:26 +0200
                        Re: Implicit conversion to boolean in if and while statements Laszlo Nagy <gandalf@shopzeus.com> - 2012-07-16 23:17 +0200
                    Re: Implicit conversion to boolean in if and while statements Mark Lawrence <breamoreboy@yahoo.co.uk> - 2012-07-16 07:30 +0100
                    Re: Implicit conversion to boolean in if and while statements Albert van der Horst <albert@spenarnc.xs4all.nl> - 2012-07-16 18:03 +0000
            Re: Implicit conversion to boolean in if and while statements Rick Johnson <rantingrickjohnson@gmail.com> - 2012-07-15 11:56 -0700
          Re: Implicit conversion to boolean in if and while statements Serhiy Storchaka <storchaka@gmail.com> - 2012-07-16 16:01 +0300
          Re: Implicit conversion to boolean in if and while statements rusi <rustompmody@gmail.com> - 2012-07-16 18:45 -0700
        Re: Implicit conversion to boolean in if and while statements Rick Johnson <rantingrickjohnson@gmail.com> - 2012-07-15 09:50 -0700
        Re: Implicit conversion to boolean in if and while statements Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2012-07-16 02:13 +0000
          Re: Implicit conversion to boolean in if and while statements Ranting Rick <rantingrickjohnson@gmail.com> - 2012-07-15 19:41 -0700
            Re: Implicit conversion to boolean in if and while statements Chris Angelico <rosuav@gmail.com> - 2012-07-16 12:58 +1000
            Re: Implicit conversion to boolean in if and while statements Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2012-07-16 08:05 +0000
          Re: Implicit conversion to boolean in if and while statements Ethan Furman <ethan@stoneleaf.us> - 2012-07-16 11:13 -0700
            Re: Implicit conversion to boolean in if and while statements Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2012-07-17 06:14 +0000
      Re: Implicit conversion to boolean in if and while statements Andrew Berg <bahamutzero8825@gmail.com> - 2012-07-15 12:02 -0500
        Re: Implicit conversion to boolean in if and while statements Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2012-07-16 02:38 +0000
          Re: Implicit conversion to boolean in if and while statements Dennis Lee Bieber <wlfraed@ix.netcom.com> - 2012-07-16 13:28 -0400
            Re: Implicit conversion to boolean in if and while statements Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2012-07-17 01:12 +0000
              Re: Implicit conversion to boolean in if and while statements Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2012-07-17 01:13 +0000
          Re: Implicit conversion to boolean in if and while statements Andrew Berg <bahamutzero8825@gmail.com> - 2012-07-16 15:33 -0500
          Re: Implicit conversion to boolean in if and while statements Ethan Furman <ethan@stoneleaf.us> - 2012-07-16 13:54 -0700
            Re: Implicit conversion to boolean in if and while statements Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2012-07-17 00:43 +0000
              Re: Implicit conversion to boolean in if and while statements Andrew Berg <bahamutzero8825@gmail.com> - 2012-07-16 20:57 -0500
                Re: Implicit conversion to boolean in if and while statements Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2012-07-17 04:39 +0000
                  Re: Implicit conversion to boolean in if and while statements Andrew Berg <bahamutzero8825@gmail.com> - 2012-07-17 00:19 -0500
                    Re: Implicit conversion to boolean in if and while statements Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2012-07-17 07:08 +0000
                      Re: Implicit conversion to boolean in if and while statements Andrew Berg <bahamutzero8825@gmail.com> - 2012-07-17 03:23 -0500
                        Re: Implicit conversion to boolean in if and while statements alex23 <wuwei23@gmail.com> - 2012-07-17 18:35 -0700
                      Re: Implicit conversion to boolean in if and while statements Chris Angelico <rosuav@gmail.com> - 2012-07-17 18:32 +1000
                      Re: Implicit conversion to boolean in if and while statements Laszlo Nagy <gandalf@shopzeus.com> - 2012-07-17 14:43 +0200
                      Re: Implicit conversion to boolean in if and while statements Laszlo Nagy <gandalf@shopzeus.com> - 2012-07-17 14:59 +0200
                      Re: Implicit conversion to boolean in if and while statements Terry Reedy <tjreedy@udel.edu> - 2012-07-17 13:57 -0400
                  Re: Implicit conversion to boolean in if and while statements Ethan Furman <ethan@stoneleaf.us> - 2012-07-17 05:35 -0700
              Re: Implicit conversion to boolean in if and while statements Chris Angelico <rosuav@gmail.com> - 2012-07-17 12:13 +1000
      Re: Implicit conversion to boolean in if and while statements Andrew Berg <bahamutzero8825@gmail.com> - 2012-07-15 12:16 -0500
      Re: Implicit conversion to boolean in if and while statements Ian Kelly <ian.g.kelly@gmail.com> - 2012-07-15 11:45 -0600
      Re: Implicit conversion to boolean in if and while statements Terry Reedy <tjreedy@udel.edu> - 2012-07-15 16:09 -0400
      Re: Implicit conversion to boolean in if and while statements Terry Reedy <tjreedy@udel.edu> - 2012-07-15 16:28 -0400
      Re: Implicit conversion to boolean in if and while statements Andrew Berg <bahamutzero8825@gmail.com> - 2012-07-16 20:22 -0500
        Re: Implicit conversion to boolean in if and while statements Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2012-07-17 04:11 +0000
          Re: Implicit conversion to boolean in if and while statements Ranting Rick <rantingrickjohnson@gmail.com> - 2012-07-16 21:18 -0700
            Re: Implicit conversion to boolean in if and while statements Chris Angelico <rosuav@gmail.com> - 2012-07-17 14:24 +1000
          Re: Implicit conversion to boolean in if and while statements Andrew Berg <bahamutzero8825@gmail.com> - 2012-07-16 23:44 -0500
      Re: Implicit conversion to boolean in if and while statements Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2012-07-17 04:47 +0000
    Re: Implicit conversion to boolean in if and while statements John Nagle <nagle@animats.com> - 2012-07-17 00:26 -0700

Page 3 of 4 — ← Prev page 1 2 [3] 4  Next page →


#25401

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2012-07-16 08:05 +0000
Message-ID<5003cb3c$0$1527$c3e8da3$76491128@news.astraweb.com>
In reply to#25385
On Sun, 15 Jul 2012 19:41:34 -0700, Ranting Rick wrote:

> Short circuitry is a powerful tool! But why the heck would your
> sequences ever be None? Are you using None as a default? And if so, why
> not use an empty sequence instead ([], {}, "")?


Mostly for explicitness. I want to be able to say that there is 
*explicitly* no seq, not merely that it happens to be a list which right 
now is empty but later might not be. Using None for missing values is 
idiomatic Python.

You should approve, if only for the sake of consistency: None is meant to 
be used as "no such value", and that's exactly how I am using it, even at 
the cost of my convenience when writing the code.


-- 
Steven

[toc] | [prev] | [next] | [standalone]


#25433

FromEthan Furman <ethan@stoneleaf.us>
Date2012-07-16 11:13 -0700
Message-ID<mailman.2185.1342461607.4697.python-list@python.org>
In reply to#25381
Steven D'Aprano wrote:
> On Sun, 15 Jul 2012 10:19:16 -0600, Ian Kelly wrote:
>> On Sun, Jul 15, 2012 at 4:56 AM, Steven D'Aprano wrote:
>>> (For the record, I can only think of one trap for the unwary: time
>>> objects are false at *exactly* midnight.)
 >>
>> Ugh, that's irritating.  I can't think of any scenario where I would
>> ever want the semantics "if timeval (is not midnight):".
> 
> Yes, it is a genuine gotcha. Time values are numbers, and zero is falsey, 
> so midnight is falsey even though it shouldn't be.
> 
> There's no good solution here, since we have a conflict between treating 
> time values as time values ("midnight is nothing special") and as numbers 
> ("midnight == 0 which is falsey"). 

--> import datetime
--> mn = datetime.time(0)
--> mn
datetime.time(0, 0)
--> mn == 0
False

Apparently, midnight does not equal zero.  Possibly because it should be 
truthy.  ;)

~Ethan~

[toc] | [prev] | [next] | [standalone]


#25462

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2012-07-17 06:14 +0000
Message-ID<500502b1$0$30002$c3e8da3$5496439d@news.astraweb.com>
In reply to#25433
On Mon, 16 Jul 2012 11:13:33 -0700, Ethan Furman wrote:

> Steven D'Aprano wrote:
>> On Sun, 15 Jul 2012 10:19:16 -0600, Ian Kelly wrote:
>>> On Sun, Jul 15, 2012 at 4:56 AM, Steven D'Aprano wrote:
>>>> (For the record, I can only think of one trap for the unwary: time
>>>> objects are false at *exactly* midnight.)
>  >>
>>> Ugh, that's irritating.  I can't think of any scenario where I would
>>> ever want the semantics "if timeval (is not midnight):".
>> 
>> Yes, it is a genuine gotcha. Time values are numbers, and zero is
>> falsey, so midnight is falsey even though it shouldn't be.
>> 
>> There's no good solution here, since we have a conflict between
>> treating time values as time values ("midnight is nothing special") and
>> as numbers ("midnight == 0 which is falsey").
> 
> --> import datetime
> --> mn = datetime.time(0)
> --> mn
> datetime.time(0, 0)
> --> mn == 0
> False
> 
> Apparently, midnight does not equal zero.

My mistake.



-- 
Steven

[toc] | [prev] | [next] | [standalone]


#25359

FromAndrew Berg <bahamutzero8825@gmail.com>
Date2012-07-15 12:02 -0500
Message-ID<mailman.2144.1342371768.4697.python-list@python.org>
In reply to#25346
On 7/15/2012 5:56 AM, Steven D'Aprano wrote:
> 3) Rather than distinguishing "true" from "false", a more useful 
> dichotomy is between "something" and "nothing". Python includes a number 
> of ways of spelling "nothing" of various types, such as:
> 
>     None, 0, 0.0, '', [], {}, set()
> 
> and nearly everything else is "something".
Okay, I see the value in this, but I don't understand why None has a
truth value. I would expect None to mean "doesn't exist" or "unknown" or
something like that - e.g., a value of 0 means 0 jelly beans in the jar
and None means there isn't a jar.

FWIW, I have, for a reason I forget, gotten into the habit of writing
"if x is not None" when testing for None. However, I have not been
writing "if x is True: ..."/"elif x is False: ..."/"else: 'ruh-roh'"
when testing for True (in cases where a value of True or False makes
sense, but any other value would not). Should I?

-- 
CPython 3.3.0b1 | Windows NT 6.1.7601.17803

[toc] | [prev] | [next] | [standalone]


#25384

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2012-07-16 02:38 +0000
Message-ID<50037eab$0$29995$c3e8da3$5496439d@news.astraweb.com>
In reply to#25359
On Sun, 15 Jul 2012 12:02:37 -0500, Andrew Berg wrote:

> On 7/15/2012 5:56 AM, Steven D'Aprano wrote:
>> 3) Rather than distinguishing "true" from "false", a more useful
>> dichotomy is between "something" and "nothing". Python includes a
>> number of ways of spelling "nothing" of various types, such as:
>> 
>>     None, 0, 0.0, '', [], {}, set()
>> 
>> and nearly everything else is "something".
> Okay, I see the value in this, but I don't understand why None has a
> truth value.

And this is exactly the sort of mental confusion that Laura Crichton 
warned about (see the link I included earlier).

Thinking about "truth values" is harmful, since that's arbitrary. That 
way goes to Javascript, PHP, Ruby etc. that seem to arbitrary pick 
whatever things are truthy or falsey according to some random whim, or 
according to some implementation detail that is meaningless outside of 
the implementation, such as Javascript insisting that while false is 
falsey, if you box it in an object it becomes truthy.

It's crap like that which gives duck-typing bools a bad name.

The distinction you should consider is:

- is it something, or nothing?

(relative to the type in question, of course)

Python (at least the built-ins, third-party code can do any old crap they 
want) is consistent in this. Instances which represent something/non-
emptiness are true, those which represent nothing/emptiness are false.

0? That's the int that represents nothing, so it's false.

23.723? That's one of many floats that represents something, so it's true.

'spam'? That's one of many non-empty strings, so it's true.

''? That's an empty string, that it, it contains nothing, so it is false.

None? That represents a lack of a thing, that is, nothing, so it's false.

(Please don't get into a great philosophical debate over whether 
nothingness is itself something. That impressed me when I was 15. But now 
I know about reification: just because we have a name for a concept 
doesn't mean that the concept is something concrete. None is an object, 
but it *represents* the lack of an object.)


> I would expect None to mean "doesn't exist" or "unknown" or
> something like that - e.g., a value of 0 means 0 jelly beans in the jar
> and None means there isn't a jar.

How you interpret some_variable = None depends on what some_variable 
represents. If some_variable represents "number of jelly beans in a jar", 
then that should be 0 if there is no jar.

If you want to create a language with ternary truth values (yes, no, mu) 
or some larger number (yes, no, maybe, mu, contradiction, unknowable, 
...) be my guest. Just do everyone a favour and do some research on the 
large literature on non-boolean logic systems first.


> FWIW, I have, for a reason I forget, gotten into the habit of writing
> "if x is not None" when testing for None. However, I have not been
> writing "if x is True: ..."/"elif x is False: ..."/"else: 'ruh-roh'"
> when testing for True (in cases where a value of True or False makes
> sense, but any other value would not). Should I?

Only if you want people to laugh at you.

If you *genuinely* want to implement Java in Python, then be explicit 
about your type-testing:

if isinstance(x, bool) and x: ...  

or even 

if type(x) is bool and x: ... # disallow subclasses

Otherwise, where do you stop?

if x is True is True is True is True is True is ... 


Or you could just write idiomatic Python code, including duck-typing, and 
that includes duck-typing bools. Why do you care if somebody calls your 
function with flag=1 instead of flag=True?



-- 
Steven

[toc] | [prev] | [next] | [standalone]


#25431

FromDennis Lee Bieber <wlfraed@ix.netcom.com>
Date2012-07-16 13:28 -0400
Message-ID<mailman.2183.1342459699.4697.python-list@python.org>
In reply to#25384
On 16 Jul 2012 02:38:35 GMT, Steven D'Aprano
<steve+comp.lang.python@pearwood.info> declaimed the following in
gmane.comp.python.general:

> On Sun, 15 Jul 2012 12:02:37 -0500, Andrew Berg wrote:
> 

> > Okay, I see the value in this, but I don't understand why None has a
> > truth value.
> 
> And this is exactly the sort of mental confusion that Laura Crichton 
> warned about (see the link I included earlier).
>

	Would one rather have the behavior seen in SQL for Null?
http://www.firebirdsql.org/file/documentation/reference_manuals/user_manuals/Firebird-Null-Guide.pdf

	Hey, let's turn the IF statement into tri-state logic...

	if cond:
		#true branch
	else:
		#false branch
	unknown:
		#when cond includes a None term that was NOT explicitly
		#part of a "... is {not} None" clause
-- 
	Wulfraed                 Dennis Lee Bieber         AF6VN
        wlfraed@ix.netcom.com    HTTP://wlfraed.home.netcom.com/

[toc] | [prev] | [next] | [standalone]


#25447

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2012-07-17 01:12 +0000
Message-ID<5004bc0f$0$29978$c3e8da3$5496439d@news.astraweb.com>
In reply to#25431
On Mon, 16 Jul 2012 13:28:14 -0400, Dennis Lee Bieber wrote:

> On 16 Jul 2012 02:38:35 GMT, Steven D'Aprano
> <steve+comp.lang.python@pearwood.info> declaimed the following in
> gmane.comp.python.general:
> 
>> On Sun, 15 Jul 2012 12:02:37 -0500, Andrew Berg wrote:
>> 
>> 
>> > Okay, I see the value in this, but I don't understand why None has a
>> > truth value.
>> 
>> And this is exactly the sort of mental confusion that Laura Crichton
>> warned about (see the link I included earlier).
>>
>>
> 	Would one rather have the behavior seen in SQL for Null?
> http://www.firebirdsql.org/file/documentation/reference_manuals/
user_manuals/Firebird-Null-Guide.pdf


That's a 51 page document. I'm not sure I know which behaviour you are 
referring to.

Seems to me that the Firebird NULL object is closer to a float NaN than 
to Python's None, except that Firebird treats comparisons with NULL as 
returning a NULL, while Python treats comparisons with NaN as True or 
False.

Both behaviours are reasonable, but the Firebird behaviour seems to be 
more error-prone.


> 	Hey, let's turn the IF statement into tri-state logic...
[...]

I'm not sure if you're being sarcastic here or not. Ternary logic is 
perfectly reasonable, although I expect that it would be error-prone 
because programmers would forget the "unknown" clause all the time. It 
looks like Firebird implements the variety of ternary logical called 
"Keene logic".

Of course, ternary logic can always be re-written in binary terms. 
Assuming that UNKNOWN evaluates as false:

if flag:
    true-clause
else:
    if flag is UNKNOWN:
        unknown-clause
    else:
        false-clause



-- 
Steven

[toc] | [prev] | [next] | [standalone]


#25448

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2012-07-17 01:13 +0000
Message-ID<5004bc42$0$29978$c3e8da3$5496439d@news.astraweb.com>
In reply to#25447
On Tue, 17 Jul 2012 01:12:47 +0000, Steven D'Aprano wrote:

> It
> looks like Firebird implements the variety of ternary logical called
> "Keene logic".

Oops, I meant "Kleene".



-- 
Steven

[toc] | [prev] | [next] | [standalone]


#25437

FromAndrew Berg <bahamutzero8825@gmail.com>
Date2012-07-16 15:33 -0500
Message-ID<mailman.2187.1342470794.4697.python-list@python.org>
In reply to#25384
On 7/15/2012 9:38 PM, Steven D'Aprano wrote:
>> I would expect None to mean "doesn't exist" or "unknown" or
>> something like that - e.g., a value of 0 means 0 jelly beans in the jar
>> and None means there isn't a jar.
> 
> How you interpret some_variable = None depends on what some_variable 
> represents. If some_variable represents "number of jelly beans in a jar", 
> then that should be 0 if there is no jar.
What is None supposed to mean then, and what should I do when I have to
make a distinction between "doesn't exist" and "empty"? Sure, if I need
to count the total number of jelly beans in all my stores, the
distinction is meaningless, but if I need to find out which stores sell
jelly beans so I know which stores need to be restocked, the distinction
is quite important.
-- 
CPython 3.3.0b1 | Windows NT 6.1.7601.17803

[toc] | [prev] | [next] | [standalone]


#25439

FromEthan Furman <ethan@stoneleaf.us>
Date2012-07-16 13:54 -0700
Message-ID<mailman.2189.1342471591.4697.python-list@python.org>
In reply to#25384
Andrew Berg wrote:
> On 7/15/2012 9:38 PM, Steven D'Aprano wrote:
>>> I would expect None to mean "doesn't exist" or "unknown" or
>>> something like that - e.g., a value of 0 means 0 jelly beans in the jar
>>> and None means there isn't a jar.
 >>
>> How you interpret some_variable = None depends on what some_variable 
>> represents. If some_variable represents "number of jelly beans in a jar", 
>> then that should be 0 if there is no jar.
 >
> What is None supposed to mean then, and what should I do when I have to
> make a distinction between "doesn't exist" and "empty"? Sure, if I need
> to count the total number of jelly beans in all my stores, the
> distinction is meaningless, but if I need to find out which stores sell
> jelly beans so I know which stores need to be restocked, the distinction
> is quite important.

I'm not sure what Steven was trying to say there, but for me:

jar with no jellybeans == 0

no jar == None

~Ethan~

[toc] | [prev] | [next] | [standalone]


#25446

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2012-07-17 00:43 +0000
Message-ID<5004b543$0$29978$c3e8da3$5496439d@news.astraweb.com>
In reply to#25439
On Mon, 16 Jul 2012 13:54:32 -0700, Ethan Furman wrote:

> Andrew Berg wrote:
>> On 7/15/2012 9:38 PM, Steven D'Aprano wrote:
>>>> I would expect None to mean "doesn't exist" or "unknown" or something
>>>> like that - e.g., a value of 0 means 0 jelly beans in the jar and
>>>> None means there isn't a jar.
>  >>
>>> How you interpret some_variable = None depends on what some_variable
>>> represents. If some_variable represents "number of jelly beans in a
>>> jar", then that should be 0 if there is no jar.
>  >
>> What is None supposed to mean then, and what should I do when I have to
>> make a distinction between "doesn't exist" and "empty"? Sure, if I need
>> to count the total number of jelly beans in all my stores, the
>> distinction is meaningless, but if I need to find out which stores sell
>> jelly beans so I know which stores need to be restocked, the
>> distinction is quite important.
> 
> I'm not sure what Steven was trying to say there, but for me:
> 
> jar with no jellybeans == 0
> 
> no jar == None

The existence of a jar or no jar is irrelevant to the question of how 
many jellybeans there are. They are two different things, and therefore 
need two different values. There are many ways to implement this.

# One way
jar_exists = True  # or possibly False
jellybeans = 42  # or whatever the number is, possibly 0

# Another way
jar = Jar(number_of_beans=jellybeans) if jar_exists else None
jellybeans = jar.jellybeans if jar is not None else 0

If you have many jars, and you want to count the total number of 
jellybeans:

total = sum(jar.jellybeans for jar in jars if jar is not None)


Strictly speaking, the "is not None" is redundant, but it expresses the 
intent better than the alternative. Assuming that jar instances follow 
the standard Python API for containers, and is treated as falsey when it 
has a jellybean count of zero:

total = sum(jar.jellybeans for jar in jars if jar)
  # relies on the fact that adding zero to a number makes 
  # no difference, so you can safely leave zeroes out


Here's a case where you *must* distinguish between empty jars and None:

number_of_jars = sum(1 for jar in jars if jar is not None)

and a case where you *shouldn't*:

number_of_nonempty_jars = sum(1 for jar in jars if jar)

Of course you can write this:

number_of_nonempty_jars = sum(
    1 for jar in jars if jar is not None and jar.jellybeans > 1
    )

but that overwhelms the code with incidental implementation details about 
jellybean counts, which is prone to bugs. (Did you spot it?)

Even jar.isempty() would be better, but better still is to *not* invent 
your own container API but to use the standard Python one instead and 
define an appropriate __nonzero__ (Python 2) or __bool__ (Python 3) 
method.

If I insist on making a single object do duty for both the jar and the 
jellybean count, then I need a "null jar object", and I probably end up 
with something like this:

Jar(number_of_beans=None) => null jar object with jar.jellybeans = 0
Jar(number_of_beans=0) => normal jar object with jar.jellybeans = 0
Jar(number_of_beans=42) => normal jar object with jar.jellybeans = 42

and then my code becomes even more complicated and less understandable, 
but hey, it's *my* code and I can do whatever damn-fool thing I like!


-- 
Steven

[toc] | [prev] | [next] | [standalone]


#25451

FromAndrew Berg <bahamutzero8825@gmail.com>
Date2012-07-16 20:57 -0500
Message-ID<mailman.2195.1342490275.4697.python-list@python.org>
In reply to#25446
On 7/16/2012 7:43 PM, Steven D'Aprano wrote:
> The existence of a jar or no jar is irrelevant to the question of how 
> many jellybeans there are. They are two different things, and therefore 
> need two different values. There are many ways to implement this.
I have a better real example, but I opted not to use it before since it
requires some explanation - IRC messages.
A client-to-server message has the basic form of b'COMMAND arguments
:message' (e.g. b'PRIVMSG #channel :hi guys!'). Some commands have no
message part because there is no message associated with it (e.g. b'JOIN
#channel') and there is at least one where there is a big difference
between a blank message (b'') and no message - b'TOPIC #channel' is a
request for the topic while b'TOPIC #channel :' clears the topic since
the part after the b':' is b'' (b'TOPIC #channel :Welcome to #channel'
sets the topic to "Welcome to #channel"). In my code, I would have an
object representing a message rather than parsing it multiple times. If
the message
attribute is not None, I send b'{command} {args} :{message}', otherwise
b'{command} {args}'. If I considered '' falsey, either I would require
all messages to have ":" (which would not actually be part of the
message) or have any request to view the topic as a channel op clear the
topic. This would apply to the server parsing the message as well. A few
other commands have messages optional as well, but they are not as
serious as TOPIC.

I could do:

if has_message:
	send('{command} {args} :{message}')
else:
	send('{command} {args}')

but then I'd have to make sure has_message stays accurate since message
won't necessarily be. Or maybe I could leave message undefined and catch
the appropriate exception. However, using None is the cleanest and most
obvious.

I know Rick likes to troll, but I do agree with him that "if something:"
for arbitrary objects can be ambiguous or confusing. I don't think
if/while must have True or False, but not every object has an obvious
truth value.
-- 
CPython 3.3.0b1 | Windows NT 6.1.7601.17803

[toc] | [prev] | [next] | [standalone]


#25457

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2012-07-17 04:39 +0000
Message-ID<5004ec84$0$11116$c3e8da3@news.astraweb.com>
In reply to#25451
On Mon, 16 Jul 2012 20:57:43 -0500, Andrew Berg wrote:

> I have a better real example, but I opted not to use it before since it
> requires some explanation - IRC messages. A client-to-server message has
> the basic form of b'COMMAND arguments :message' (e.g. b'PRIVMSG #channel
> :hi guys!'). Some commands have no message part because there is no
> message associated with it (e.g. b'JOIN #channel') and there is at least
> one where there is a big difference between a blank message (b'') and no
> message - b'TOPIC #channel' is a request for the topic while b'TOPIC
> #channel :' clears the topic since the part after the b':' is b''
> (b'TOPIC #channel :Welcome to #channel' sets the topic to "Welcome to
> #channel"). 

Okay, so you have two distinct "nothing" states when considering the 
message part of an IRC command: the empty string, and missing.

That's okay. Floats have two zeroes (+0.0 and -0.0); complex numbers have 
four. (Although they try hard to hide that distinction from you.)

There's nothing that says that you can only have a single falsey value in 
a type, or that you might not sometimes wish to distinguish between 
different false-like states. You need to distinguish between the many 
different true-like messages, so you should not be surprised that you 
need to distinguish between two false-like messages.

There are many ways to implement this. Here are just the most obvious:

1) a Command object where the message attribute is optional, but if
   present, it is always a string;

2) a Command object where the message attribute is always present, but
   can be a string or some non-string sentinel value (e.g. None);

3) a string, where the message attribute is determined by the location
   of the colon, if any

4) a tuple with either two or three fields: (command, channel [,message])



> In my code, I would have an object representing a message
> rather than parsing it multiple times. If the message
> attribute is not None, I send b'{command} {args} :{message}', otherwise
> b'{command} {args}'. 

Clear and obvious. Nothing wrong with that.


> I could do:
> 
> if has_message:
> 	send('{command} {args} :{message}')
> else:
> 	send('{command} {args}')
> 
> but then I'd have to make sure has_message stays accurate since message
> won't necessarily be. 

Yes, keeping a separate variable is a mug's game. Encapsulate it in the 
Command object, and have the Command object responsible for keeping it in 
sync (assuming it is mutable), or just make Command immutable and be done 
with it.


> Or maybe I could leave message undefined and catch
> the appropriate exception. However, using None is the cleanest and most
> obvious.

Yes it is. What's your point?

You've discovered a real-world situation where you can't collapse the 
entire universe of valid values into just two, True and False, without 
losing information. Did you think that this would be surprising?

Python developers often talk about interpreting objects "in a boolean 
context" -- that's a pretty big hint that the semantics are to collapse 
the value into two states. If you need three (or four, or fifty) 
distinguishable states, then obviously boolean context will not solve 
your problem. I never said it would.



-- 
Steven

[toc] | [prev] | [next] | [standalone]


#25461

FromAndrew Berg <bahamutzero8825@gmail.com>
Date2012-07-17 00:19 -0500
Message-ID<mailman.2201.1342502395.4697.python-list@python.org>
In reply to#25457
On 7/16/2012 11:39 PM, Steven D'Aprano wrote:
> If you need three (or four, or fifty) 
> distinguishable states, then obviously boolean context will not solve 
> your problem. I never said it would.
That is the impression I got from this statement:

> How you interpret some_variable = None depends on what some_variable 
> represents. If some_variable represents "number of jelly beans in a jar", 
> then that should be 0 if there is no jar.
But I guess you misunderstood (or were just picking at) the example.

Of course I can (and do) explicitly use "if x is not None" when testing
for None, but I don't want a bug being obscured because "if x" accepts
an erroneous value that it interprets as truthy or falsey. I could be
explicit when testing for things other than None, but apparently that's
un-Pythonic.

To put it in duck-typing terms, why should everything have to quack like
True or False? Sure, I can see why 1 quacks like True or [] quacks like
False, but I don't see why say, a Logger or function should quack like
either. Should a Thread object be True if it's been started and False
otherwise?

If it truly is about something vs. nothing, why is a NameError (or
AttributeError) raised when testing with an undefined variable? Being
undefined quacks like nothing, doesn't it?
-- 
CPython 3.3.0b1 | Windows NT 6.1.7601.17803

[toc] | [prev] | [next] | [standalone]


#25465

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2012-07-17 07:08 +0000
Message-ID<50050f70$0$30002$c3e8da3$5496439d@news.astraweb.com>
In reply to#25461
On Tue, 17 Jul 2012 00:19:48 -0500, Andrew Berg wrote:

> To put it in duck-typing terms, why should everything have to quack like
> True or False? Sure, I can see why 1 quacks like True or [] quacks like
> False, but I don't see why say, a Logger or function should quack like
> either.

The default behaviour is that every object is something, hence true-like, 
unless explicitly coded to be treated as false-like. Since both loggers 
and functions are objects, they are true-like unless the default is 
overridden.

If you don't like that simple, consistent model for truthiness, feel free 
to design your own language with a different model. Or you can use any 
one of the dozens of other existing languages which do what you want.


> Should a Thread object be True if it's been started and False
> otherwise?

If you, the Thread class author, want it to be, you can make it so.


> If it truly is about something vs. nothing, why is a NameError (or
> AttributeError) raised when testing with an undefined variable? Being
> undefined quacks like nothing, doesn't it?

Not really. It doesn't quack like anything.


Are you suggesting that if x doesn't exist, you want this behaviour?


>>> del x  # make sure x doesn't exist
>>> if x: print('cheese')
... else: 
...     print('x is falsy')
...     print(x)
...
x is falsy
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'x' is not defined


OH MAN, that would be SO AWESOME, we should like so do it!!!

(I'm being sarcastic, in case it's not obvious.)



-- 
Steven

[toc] | [prev] | [next] | [standalone]


#25470

FromAndrew Berg <bahamutzero8825@gmail.com>
Date2012-07-17 03:23 -0500
Message-ID<mailman.2203.1342513414.4697.python-list@python.org>
In reply to#25465
On 7/17/2012 2:08 AM, Steven D'Aprano wrote:
> The default behaviour is that every object is something, hence true-like, 
> unless explicitly coded to be treated as false-like. Since both loggers 
> and functions are objects, they are true-like unless the default is 
> overridden.
I am aware of the default behavior, but the reason for it still eludes me.

> Are you suggesting that if x doesn't exist, you want this behaviour?
I don't want that, but I am suggesting that it would be consistent with
the idea of "something or nothing".
-- 
CPython 3.3.0b1 | Windows NT 6.1.7601.17803

[toc] | [prev] | [next] | [standalone]


#25549

Fromalex23 <wuwei23@gmail.com>
Date2012-07-17 18:35 -0700
Message-ID<21fcdb92-20e3-428b-b06b-057065a4ab25@oo8g2000pbc.googlegroups.com>
In reply to#25470
On Jul 17, 6:23 pm, Andrew Berg <bahamutzero8...@gmail.com> wrote:
> On 7/17/2012 2:08 AM, Steven D'Aprano wrote:
> > The default behaviour is that every object is something, hence true-like,
> > unless explicitly coded to be treated as false-like. Since both loggers
> > and functions are objects, they are true-like unless the default is
> > overridden.
>
> I am aware of the default behavior, but the reason for it still eludes me.

Because it makes it simple to distinguish between having an object and
not having one without having to explicitly test for it each time.

    db = connect("my:db") # or None if the connection failed
    if db:
        <do something>

I find that usage to be incredibly intuitive.

[toc] | [prev] | [next] | [standalone]


#25471

FromChris Angelico <rosuav@gmail.com>
Date2012-07-17 18:32 +1000
Message-ID<mailman.2204.1342513982.4697.python-list@python.org>
In reply to#25465
On Tue, Jul 17, 2012 at 6:23 PM, Andrew Berg <bahamutzero8825@gmail.com> wrote:
> On 7/17/2012 2:08 AM, Steven D'Aprano wrote:
>> The default behaviour is that every object is something, hence true-like,
>> unless explicitly coded to be treated as false-like. Since both loggers
>> and functions are objects, they are true-like unless the default is
>> overridden.
> I am aware of the default behavior, but the reason for it still eludes me.

There has to be something. This way, you can use None in place of any
object, in the same way that a null pointer would be used in C; any
object is true, None isn't. What other default makes more sense?

ChrisA

[toc] | [prev] | [next] | [standalone]


#25494

FromLaszlo Nagy <gandalf@shopzeus.com>
Date2012-07-17 14:43 +0200
Message-ID<mailman.2218.1342529001.4697.python-list@python.org>
In reply to#25465
On 2012-07-17 10:23, Andrew Berg wrote:
> I don't want that, but I am suggesting that it would be consistent with
> the idea of "something or nothing".
Don't confuse names and objects. You can only test the truth value of 
objects. If you don't have a name in a namespace, then it means you 
don't have a tool to have a reference to anything (including the False 
object).

Using the same logic you could also say that not giving any condition to 
the "if" statement should be evaluated as False:

if:
     print "This never gets executed"

But  it makes no sense.

[toc] | [prev] | [next] | [standalone]


#25495

FromLaszlo Nagy <gandalf@shopzeus.com>
Date2012-07-17 14:59 +0200
Message-ID<mailman.2219.1342529994.4697.python-list@python.org>
In reply to#25465
> Not really. It doesn't quack like anything.
Actually, there is no "it". So we cannot talk about how it quacks. :-D

[toc] | [prev] | [next] | [standalone]


Page 3 of 4 — ← Prev page 1 2 [3] 4  Next page →

Back to top | Article view | comp.lang.python


csiph-web