Proposal: function which simulates C ?: operator

Discussion in 'Python' started by Adal Chiriliuc, Jul 11, 2004.

I think a function similar to the one below should be added to the
builtin module:

def boolselect(condition, trueresult, falseresult):
if condition:
return trueresult
else:
return falseresult

--- WITH

scalewidth = boolselect(self.__vertical, _scalew, _scaleh)

a1 = 0
a4 = boolselect(self.__vertical, self.__width, self.__height)
a2 = (a4 - scalewidth) // 2
a3 = a2 + scalewidth

self.__meterwidth = self.__meterrect[0].Width()
self.__meterheight = self.__meterrect[0].Height()
self.__meterlength = boolselect(self.__vertical, self.__meterheight, self.__meterwidth)

t = boolselect(self.__range >= 18, -18, -12)
redzone = self.__dBToOffset(-6)
yellowzone = self.__dBToOffset(t)

--- WITHOUT

if self.__vertical:
scalewidth = _scalew
else:
scalewidth = _scaleh

a1 = 0
if self.__vertical:
a4 = self.__width
else:
a4 = self.__height
a2 = (a4 - scalewidth) // 2
a3 = a2 + scalewidth

self.__meterwidth = self.__meterrect[0].Width()
self.__meterheight = self.__meterrect[0].Height()
if self.__vertical:
self.__meterlength = self.__meterheight
else:
self.__meterlength = self.__meterwidth

if self.__range >= 18:
t = -18
else:
t = -12
redzone = self.__dBToOffset(-6)
yellowzone = self.__dBToOffset(t)

---

What do you think?

PS: maybe a better name than boolselect could be found.

2. Mel WilsonGuest

In article <>,
>I think a function similar to the one below should be added to the
>builtin module:
>
>def boolselect(condition, trueresult, falseresult):
> if condition:
> return trueresult
> else:
> return falseresult
>
>[ ... ]
>What do you think?
>
>PS: maybe a better name than boolselect could be found.

Some poeple might be disturbed by what it would do with

this_line = boolselect (dummy_flag, "Dummy line\n", infile.readline())

Side-effects are the main reason that a simple function
can't generally replace a full conditional ternary operator.
See google for the ternary operator debate, and see the other
discussion in clp right now.

Regards. Mel.

Mel Wilson, Jul 11, 2004

3. MitjaGuest

(news:) wrote:
> I think a function similar to the one below should be
> builtin module:
>
> def boolselect(condition, trueresult, falseresult):
> if condition:
> return trueresult
> else:
> return falseresult
>
> --- WITH
>
> scalewidth = boolselect(self.__vertical, _scalew, _scaleh)
>
> --- WITHOUT
>
> if self.__vertical:
> scalewidth = _scalew
> else:
> scalewidth = _scaleh

> What do you think?

Here's a nifty workaround I figured out myself but am sure others use it as
well:
scalewidth=(_scaleh,_scalew)[__self.vertical]

HTH

It's not as readable as the "if cond ? true_expr : false_expr", but I think
introducing syntax like this is far from needed and pretty complicated.

Mitja, Jul 11, 2004
4. Paul RubinGuest

> I think a function similar to the one below should be added to the
> builtin module:
>
> def boolselect(condition, trueresult, falseresult):
> if condition:
> return trueresult
> else:
> return falseresult

That doesn't work because both results get evaluated either way. E.g.

boolselect(x==0, f(x), g(x))

calls both f and g. You need something like

(lambda: g(x), lambda: f(x))[bool(condition)]()

Paul Rubin, Jul 11, 2004
5. Erik Max FrancisGuest

> I think a function similar to the one below should be added to the
> builtin module:
>
> def boolselect(condition, trueresult, falseresult):
> if condition:
> return trueresult
> else:
> return falseresult

This doesn't simulate the conditional operator; it doesn't do
short-circuiting. See PEP 308; this kind of construct was explicitly
rejected (but then, so is the whole PEP).

--
__ Erik Max Francis && && http://www.alcyone.com/max/
/ \ San Jose, CA, USA && 37 20 N 121 53 W && AIM erikmaxfrancis
\__/ Forever we / Infinitely
-- Sandra St. Victor

Erik Max Francis, Jul 11, 2004
6. Tor Iver WilhelmsenGuest

Paul Rubin <http://> writes:

> (lambda: g(x), lambda: f(x))[bool(condition)]()

Since you call the object afterwards, you don't need the lambdas
(which add a layer of indirection), just the function references:

(g, f)[bool(condition)]()

Tor Iver Wilhelmsen, Jul 11, 2004
7. Erik Max FrancisGuest

Tor Iver Wilhelmsen wrote:

> Paul Rubin <http://> writes:
>
> > (lambda: g(x), lambda: f(x))[bool(condition)]()

>
> Since you call the object afterwards, you don't need the lambdas
> (which add a layer of indirection), just the function references:
>
> (g, f)[bool(condition)]()

Well, you meant:

(g, f)[bool(condition)](x)

but that was taking his example too literally; he was just using f(x)
and g(x) to expressions that you wanted laziy evaluated.

--
__ Erik Max Francis && && http://www.alcyone.com/max/
/ \ San Jose, CA, USA && 37 20 N 121 53 W && AIM erikmaxfrancis
\__/ Forever we / Infinitely
-- Sandra St. Victor

Erik Max Francis, Jul 11, 2004
8. Paul RubinGuest

Tor Iver Wilhelmsen <> writes:
> > (lambda: g(x), lambda: f(x))[bool(condition)]()

>
> Since you call the object afterwards, you don't need the lambdas
> (which add a layer of indirection), just the function references:
>
> (g, f)[bool(condition)]()

Good catch, for that particular example. The lambdas are needed for
more general cases, e.g. (x > 0 ? (f(x)+g(y)) : (h(x)-z(y)))

There's been various proposals floated for macros in Python. If
something like that becomes real, that can solve this whole problem.

Paul Rubin, Jul 11, 2004

I didn't know this was discussed so much in the past. I should have
searched before.

Most of you objected that this is a bad solution because it evaluates
both variants. That's true if you want a real ternary operator. I now
think I gave a bad title to this thread. It shouldn't have mentioned
?:

I've searched through the C++ sources I'm now porting to Python
(450 KB) and found 44 uses of ?: and from these only 4 needed short
circuit evaluation (to avoid dereferencing NULL pointers or zero
division).

I now suggest that this function be added without implying that it's
the Python equivalent of ?: and with the docs clearly explaining that
it's not ?: and how it differs. It will be like Python private vars,
almost but not quite (of course, Python private vars are a lot more
close to the ideal than this is).

Anyway, I suggested this because the function I have is actually named
Util.BoolSelect, and this is kind of long

10. Peter HansenGuest

> I didn't know this was discussed so much in the past. I should have
> searched before.

And if you read all of it, you probably wouldn't be making
the following suggestion, either.

> I now suggest that this function be added without implying that it's
> the Python equivalent of ?: and with the docs clearly explaining that
> it's not ?: and how it differs.

It won't happen because (a) it's a trivial function to write
on-demand, and (b) there are already several different ways of
spelling it with current Python syntax if you don't want a
function, and (c) I suspect that the requirement for short-circuit
evaluation would actually be *more* common in Python than it
appears it is in C++ based on your very limited sample population.

-Peter

Peter Hansen, Jul 12, 2004
11. Dan BishopGuest

"Mitja" <> wrote in message news:<LAbIc.6518\$>...
> (news:) wrote:
> > I think a function similar to the one below should be
> > builtin module:
> >
> > def boolselect(condition, trueresult, falseresult):
> > if condition:
> > return trueresult
> > else:
> > return falseresult
> >
> > --- WITH
> >
> > scalewidth = boolselect(self.__vertical, _scalew, _scaleh)
> >
> > --- WITHOUT
> >
> > if self.__vertical:
> > scalewidth = _scalew
> > else:
> > scalewidth = _scaleh

>
> > What do you think?

>
> Here's a nifty workaround I figured out myself but am sure others use it as
> well:
> scalewidth=(_scaleh,_scalew)[__self.vertical]

If you're going to use the "(F, T)[C]" syntax, it would be better to
write it as "(F, T)[bool(C)]" to ensure that the array index is 0 or
1.

However, a better alternative is "(C and [T] or [F])[0]", which
short-circuits and also has the advantage of having the same order as
"if".

If you're absolutely certain that T will never be false, you can
simplify this to "C and T or F".

Dan Bishop, Jul 12, 2004
12. Erik Max FrancisGuest

Dan Bishop wrote:

> However, a better alternative is "(C and [T] or [F])[0]", which
> short-circuits and also has the advantage of having the same order as
> "if".

It's got the same order, but it's completely opaque. It's hardly better

--
__ Erik Max Francis && && http://www.alcyone.com/max/
/ \ San Jose, CA, USA && 37 20 N 121 53 W && AIM erikmaxfrancis
\__/ Performing in front of a live audience is like a feeling of shock.

Erik Max Francis, Jul 12, 2004
13. Reinhold BirkenfeldGuest

Peter Hansen wrote:
>
>> I didn't know this was discussed so much in the past. I should have
>> searched before.

>
> And if you read all of it, you probably wouldn't be making
> the following suggestion, either.
>
>> I now suggest that this function be added without implying that it's
>> the Python equivalent of ?: and with the docs clearly explaining that
>> it's not ?: and how it differs.

>
> It won't happen because (a) it's a trivial function to write
> on-demand,

How do you write this function without lambda in the call?

> and (b) there are already several different ways of
> spelling it with current Python syntax if you don't want a
> function

One uglier than the other.

> and (c) I suspect that the requirement for short-circuit
> evaluation would actually be *more* common in Python than it
> appears it is in C++ based on your very limited sample population.

ACK.

Reinhold

--
Wenn eine Linuxdistribution so wenig brauchbare Software wie Windows
mitbrächte, wäre das bedauerlich. Was bei Windows der Umfang eines
"kompletten Betriebssystems" ist, nennt man bei Linux eine Rescuedisk.
-- David Kastrup in de.comp.os.unix.linux.misc

Reinhold Birkenfeld, Jul 12, 2004
14. Peter HansenGuest

Reinhold Birkenfeld wrote:

> Peter Hansen wrote:
>>It won't happen because (a) it's a trivial function to write
>>on-demand,

>
> How do you write this function without lambda in the call?

Basically, you use if/then like you are "supposed" to.
the trivial fully evaluated function approach.

>>and (b) there are already several different ways of
>>spelling it with current Python syntax if you don't want a
>>function

>
> One uglier than the other.

Agreed. Use if/then and save the sanity of your maintenance
programmers.

>>and (c) I suspect that the requirement for short-circuit
>>evaluation would actually be *more* common in Python than it
>>appears it is in C++ based on your very limited sample population.

>
> ACK.

Ironic that Bill the Cat changed the meaning of that from
positive to negative. (Or did he always use mixed-case,
so that all-caps ACK is still uniquely ASCII?)

-Peter

Peter Hansen, Jul 12, 2004
15. Reinhold BirkenfeldGuest

Peter Hansen wrote:
> Reinhold Birkenfeld wrote:
>
>> Peter Hansen wrote:
>>>It won't happen because (a) it's a trivial function to write
>>>on-demand,

>>
>> How do you write this function without lambda in the call?

>
> Basically, you use if/then like you are "supposed" to.
> the trivial fully evaluated function approach.

Granted. This or (x and y or z) without y being false...

>>>and (b) there are already several different ways of
>>>spelling it with current Python syntax if you don't want a
>>>function

>>
>> One uglier than the other.

>
> Agreed. Use if/then and save the sanity of your maintenance
> programmers.
>
>>>and (c) I suspect that the requirement for short-circuit
>>>evaluation would actually be *more* common in Python than it
>>>appears it is in C++ based on your very limited sample population.

>>
>> ACK.

>
> Ironic that Bill the Cat changed the meaning of that from
> positive to negative. (Or did he always use mixed-case,
> so that all-caps ACK is still uniquely ASCII?)

Well, I don't know Bill the Cat, should I?

Reinhold

--
Wenn eine Linuxdistribution so wenig brauchbare Software wie Windows
mitbrächte, wäre das bedauerlich. Was bei Windows der Umfang eines
"kompletten Betriebssystems" ist, nennt man bei Linux eine Rescuedisk.
-- David Kastrup in de.comp.os.unix.linux.misc

Reinhold Birkenfeld, Jul 13, 2004
16. Peter HansenGuest

Reinhold Birkenfeld wrote:

> Peter Hansen wrote:
>>Reinhold Birkenfeld wrote:
>>>ACK.

>>
>>Ironic that Bill the Cat changed the meaning of that from
>>positive to negative. (Or did he always use mixed-case,
>>so that all-caps ACK is still uniquely ASCII?)

>
> Well, I don't know Bill the Cat, should I?

Probably not. It was a comic strip called "Bloom County"
which featured among many other things a cat named Bill who
was, uh, just a tad incoherent, and given to mutterings like
"Ack! Pthft!"

See http://encyclopedia.thefreedictionary.com/Bill the Cat
for background, and the following for a nice pic:
http://www.premier.net/~cspedale/opus/images/bill2.jpg

-Peter

Peter Hansen, Jul 13, 2004