(a==b) ? 'Yes' : 'No'

S

Steve Holden

kj said:
In said:
John said:
Chris Rebert wrote:
Hi, how can I write the popular C/JAVA syntax in Python?

Java example:
return (a==b) ? 'Yes' : 'No'

My first idea is:
return ('No','Yes')[bool(a==b)]

Is there a more elegant/common python expression for this?
Yes, Python has ternary operator-like syntax:
return ('Yes' if a==b else 'No')

Note that this requires a recent version of Python.
Who let the dogs in? That's awful syntax.
Yes, that's deliberately awful syntax. Guido designed it that way to
ensure that people didn't aver-use it, thereby reducing the readability
of Python applications.

Is that for real??? It's the QWERTY rationale all over again. Swell.
I may be misrepresenting Guido here. Unlike Tim Peters I have never
claimed to be able to channel him.
"Let's preserve readability by making the syntax so ugly that people
won't use it."??? That's just perverse. (It would have been more
reassuring if the reason had been simply that Guido has an inexplicable
dislike of ternary expressions just like one may have an inexplicable
dislike of Broadway musicals.)
I don't think his dislike of them is inexplicable. They do, when
over-used, lead to the most impenetrable code, which as a bonus is
frequently buggy.
First, I don't understand why ternary expressions are inherently
hard to read, and therefore must be discouraged in the name of
overall code readability. Sure, one can write impenetrable ternary
expressions, but one can write impenetrable binary expressions or
impenetrable anything else, even in Python. That the expression
is ternary has nothing to do with it.
I think it does - the scope of the expressions is inherently longer when
three terms are involved rather than just tow.
Second, sticking the test between the two alternatives goes against
a vast tradition in programming languages. This tradition inevitably
fosters habits and expectations when reading code, so going against
it automatically makes code less readable to all who were educated
in that tradition. Consider, for example, the readability of the
following if statement in some hypothetical language:

begin:
# this branch will be executed if test() (see below) evaluates
# to true
x = y + z
a = b * x + c
i = j - k
p = log(q)
if test() else:
x = -(y + z)
a = b * x + 2 * c
i = j + k
p = -log(q)

If you find this hard to read (I do), the quetion is "why?". For
me it's because, maybe through years of reading code, I've developed
a habit that says: when you run into a fork in the logic, first
understand what the decision hinges on. Therefore, my brain will
start hunting for that test, and it sucks to have to find it buried
somewhere in the middle. (Sure, one could justify this horrible
syntax with an argument reminiscent of the one you gave for "A if
X else B". It goes like this: long blocks of code should be avoided
in the name of readability; this syntax discourages long blocks of
code because one doesn't want to skip too far ahead to find that
test. Ergo the end result is improved readability. That's just
nuts.)
It's precisely to avoid that kind of lunacy that the chosen form was
adopted. Conditional expressions aren't *meant* to be complex enough to
leave any doubt about their meaning. If you require such complexity
that's perfectly OK - just use an "if" statement.
Anyway, I don't know of any other language that puts the test
between the alternatives. No doubt there's one out there, with
emphasis on "out there"...
I understand you don't like it. The message handing down the decision is at

http://mail.python.org/pipermail/python-dev/2005-September/056846.html

and consideration of many applicable points in the standard library is at

http://mail.python.org/pipermail/python-dev/2005-September/056803.html

Disagree with the decision as you might, you can't argue that it was
made with insufficient consideration of the possible alternatives or the
merits of the solution.

regards
Steve
 
P

Patrick Maupin

Is that for real???  It's the QWERTY rationale all over again.  Swell..

Well, bearing in mind that everybody seems to have an agenda, so you
can't (or shouldn't, anyway) take all your news from a single source,
it may be that the common wisdom about the QWERTY thing is incorrect:

http://reason.com/archives/1996/06/01/typing-errors

I have to confess that I haven't done any real deep research on the
subject, but yet again, we find there is more than one side to a
story.

Regards,
Pat
 
E

Ethan Furman

kj said:
In said:
John said:
Chris Rebert wrote:
Hi, how can I write the popular C/JAVA syntax in Python?

Java example:
return (a==b) ? 'Yes' : 'No'

My first idea is:
return ('No','Yes')[bool(a==b)]

Is there a more elegant/common python expression for this?
Yes, Python has ternary operator-like syntax:
return ('Yes' if a==b else 'No')

Note that this requires a recent version of Python.
Who let the dogs in? That's awful syntax.
Yes, that's deliberately awful syntax. Guido designed it that way to
ensure that people didn't aver-use it, thereby reducing the readability
of Python applications.

Is that for real??? It's the QWERTY rationale all over again. Swell.

The rationale I remember is that it's intended primarily where the
condition is usually true, with the false only being once in a while.

[snip]
Second, sticking the test between the two alternatives goes against
a vast tradition in programming languages. This tradition inevitably
fosters habits and expectations when reading code, so going against
it automatically makes code less readable to all who were educated
in that tradition.

So you're saying that new languages can't change anything already well
established? So much for break-through innovations.

And what about the programmers? It is good to learn to think in
different ways.

At any rate, I far prefer it over C's syntax.

~Ethan~
 
S

Steven D'Aprano

In <[email protected]> Steve Holden


Is that for real??? It's the QWERTY rationale all over again. Swell.

Not according to the PEP. No fewer than 16 alternatives were put to a
vote, and with no clear winner (but many obvious losers) Guido made the
final decision.

http://www.python.org/dev/peps/pep-0308/

Although the results of the voting are given, unaccountably no final
tally was given. Possibly because nobody could agree on how to tally the
votes. Using a simple counting procedure (I give 3 votes for a rank1
vote, 2 votes for a rank2 and 1 for a rank3, signed according to whether
it was an Accept or Reject vote) I find the top four candidates were:

C. (if C: x else: y) 27%
D. C ? x : y 20%
B. if C then x else y 13%
A. x if C else y 11%

with everything else an order of magnitude smaller (6% or less). If you
choose a different voting scheme, no doubt you will get different results.

Since no candidate syntax got a majority of the vote, it came down to the
only vote that really mattered: Guido's.

Ankh-Morpork had dallied with many forms of government
and had ended up with that form of democracy known as
One Man, One Vote. The Patrician was the Man; he had the
Vote. -- (T. Pratchett, "Mort")


Guido did say "Note that all these are intentionally ugly" but this was
followed by a smiley and was obviously tongue-in-cheek.

http://mail.python.org/pipermail/python-dev/2005-September/056846.html

"Let's preserve readability by making the syntax so ugly that people
won't use it."??? That's just perverse. (It would have been more
reassuring if the reason had been simply that Guido has an inexplicable
dislike of ternary expressions just like one may have an inexplicable
dislike of Broadway musicals.)

"Inexplicable"? They're musicals, and they're on Broadway. Surely that's
two good reasons to dislike them *wink*

Second, sticking the test between the two alternatives goes against a
vast tradition in programming languages.

As I've pointed out before, it is natural syntax in English. Not
necessarily the most common, but common enough to be completely
unexceptional:

"I'll be there in ten minutes, if I can find a parking space close by,
otherwise you should start without me."
 
S

Steve Howell

As I've pointed out before, it is natural syntax in English. Not
necessarily the most common, but common enough to be completely
unexceptional:

"I'll be there in ten minutes, if I can find a parking space close by,
otherwise you should start without me."

To Steven's example, the ternary statement is a nice idiom when it
emphasizes the most common results:

wait_time = 10 if parking_space_close_by else
expected_wait_time_in_congested_area()

Or:

qoutient = m / n if n else None

In languages like Ruby/Perl the inverted if statement is also a useful
idiom to emphasize concisely that code is exceptional in nature:

def quotient(m, n)
# guard code
return None if n == 0

# happy path
return m / n
end


Or:

raise 'Armegeddon' if locusts_flying()
useful_intelligible_happy_path_code_here()
 
J

John Bokma

Steve Howell said:
In languages like Ruby/Perl the inverted if statement is also a useful
idiom to emphasize concisely that code is exceptional in nature:

def quotient(m, n)
# guard code
return None if n == 0

# happy path
return m / n
end

Still, in Perl I prefer:

sub quotient {

my ( $m, $n ) = @_;
$n != 0 or return;

return $m / $n;
}

but I guess it depends a lot on what you're used to read.
 
S

Steven D'Aprano

But you can “abolutely knowâ€â€”it’s all spelled out here
<http://docs.python.org/reference/expressions.html>. Just keep that page
open every time you write Python code.

Or, when in doubt, you can add redundant parentheses. It makes no
difference to the runtime, and vanishingly small difference to the
compile-time, and sometimes it aids readability.

Writing the absolutely minimal code necessary to do what you want is not
necessarily the best approach in all cases. I find, for instance, that
redundant parentheses aid readability of complex logical and arithmetic
expressions, especially if you include whitespace.
 
G

Gregory Ewing

Steven said:
Not according to the PEP. No fewer than 16 alternatives were put to a
vote, and with no clear winner (but many obvious losers) Guido made the
final decision.

As I remember, the decision made on the basis of the vote
was *not* to add a conditional expression at all, because of
the fact that there was no clear winner.

It was some time later that Guido suddenly announced out of
the blue that he was accepting one of the choices that he had
earlier said he didn't like!

The ways of the BDFL are strange indeed. :)
 
S

Steven D'Aprano

As I remember, the decision made on the basis of the vote was *not* to
add a conditional expression at all, because of the fact that there was
no clear winner.

It was some time later that Guido suddenly announced out of the blue
that he was accepting one of the choices that he had earlier said he
didn't like!

The ways of the BDFL are strange indeed. :)


I think what happened was the he got bitten by a subtle bug in the
previous idiom for the ternary operator:

condition and x or y

will return (x if condition else y) *unless* x itself happens to be a
false value. This demonstrated that the and/or idiom was not a suitable
alternative to a short-circuiting ternary operator.
 
A

Albert van der Horst

kj said:
In said:
John Nagle wrote:
Chris Rebert wrote:
Hi, how can I write the popular C/JAVA syntax in Python?

Java example:
return (a==b) ? 'Yes' : 'No'

My first idea is:
return ('No','Yes')[bool(a==b)]

Is there a more elegant/common python expression for this?
Yes, Python has ternary operator-like syntax:
return ('Yes' if a==b else 'No')

Note that this requires a recent version of Python.
Who let the dogs in? That's awful syntax.

Yes, that's deliberately awful syntax. Guido designed it that way to
ensure that people didn't aver-use it, thereby reducing the readability
of Python applications.

Is that for real??? It's the QWERTY rationale all over again. Swell.
I may be misrepresenting Guido here. Unlike Tim Peters I have never
claimed to be able to channel him.
"Let's preserve readability by making the syntax so ugly that people
won't use it."??? That's just perverse. (It would have been more
reassuring if the reason had been simply that Guido has an inexplicable
dislike of ternary expressions just like one may have an inexplicable
dislike of Broadway musicals.)
I don't think his dislike of them is inexplicable. They do, when
over-used, lead to the most impenetrable code, which as a bonus is
frequently buggy.
First, I don't understand why ternary expressions are inherently
hard to read, and therefore must be discouraged in the name of
overall code readability. Sure, one can write impenetrable ternary
expressions, but one can write impenetrable binary expressions or
impenetrable anything else, even in Python. That the expression
is ternary has nothing to do with it.
I think it does - the scope of the expressions is inherently longer when
three terms are involved rather than just tow.
Second, sticking the test between the two alternatives goes against
a vast tradition in programming languages. This tradition inevitably
fosters habits and expectations when reading code, so going against
it automatically makes code less readable to all who were educated
in that tradition. Consider, for example, the readability of the
following if statement in some hypothetical language:

begin:
# this branch will be executed if test() (see below) evaluates
# to true
x = y + z
a = b * x + c
i = j - k
p = log(q)
if test() else:
x = -(y + z)
a = b * x + 2 * c
i = j + k
p = -log(q)

If you find this hard to read (I do), the quetion is "why?". For
me it's because, maybe through years of reading code, I've developed
a habit that says: when you run into a fork in the logic, first
understand what the decision hinges on. Therefore, my brain will
start hunting for that test, and it sucks to have to find it buried
somewhere in the middle. (Sure, one could justify this horrible
syntax with an argument reminiscent of the one you gave for "A if
X else B". It goes like this: long blocks of code should be avoided
in the name of readability; this syntax discourages long blocks of
code because one doesn't want to skip too far ahead to find that
test. Ergo the end result is improved readability. That's just
nuts.)
It's precisely to avoid that kind of lunacy that the chosen form was
adopted. Conditional expressions aren't *meant* to be complex enough to
leave any doubt about their meaning. If you require such complexity
that's perfectly OK - just use an "if" statement.

Let's look at a c-example.
stamp = weight>=1000 ? 120 :
weight>=500 ? 100 :
weight>=250 ? 80 :
weight>=100 ? 60 :
44;

In a glance I see that stamp gets a value.
This wouldn't be so with regular if-statements that defines
numerous path's through the code that each must be tested.
Then I find this eminently suited to compare to a table given
as a specification.

What is akward is the definition of the ternary
operation that is left associative to mean
stamp = weight>=1000 ? 120 :
(
weight>=500 ? 100 :
(
weight>=250 ? 80 :
(
weight>=100 ? 60 :
44
)
)
) ;
And not

stamp = ((((( weight>=1000 ? 120 : weight>=500 ) ? 100 : weight>=250 )
? 80 ...

Now Python

stamp =( 120 if weight>=1000 else
100 if weight>=500 else
80 if weight>=250 else
60 if weight>=100 else
44 )

This has the same advantage as c, plus :
- the prices line up
- there is no way to misinterpret associativity
(anyway you put the brackets don't change meaning)

So I like it!
Old hands would have ...
stamp =( weight>=1000 and 120 or
weight>=500 and 100 or
weight>=250 and 80 or
weight>=100 and 60 or
44 )

(Kind of a brain twister, I think, inferior to C, once the c-construct
is accepted as idiomatic.)

regards
Steve

Groetjes Albert
 
L

Lie Ryan

Pierre said:
I'm surprised nobody proposed a solution with itertools ;-)

next(itertools.takewhile(lambda _: a == b, ["yes"]), "no")

I could learn something here, if you explain it?

The signature for next() is:
next(iterator[, default])

In particular, pay attention the `default` parameter.

next() returns `default` if StopIteration is raised else it returns
iterator.__next__().

takewhile(predicate, ["yes"]).__next__() return the string "yes" if
predicate("yes") returns True else it raises StopIteration.

The predicate (lambda _: a == b) returns True if (a == b) is True
otherwise it returns False.

Put the next(), takewhile(), and the predicate together and you get an a
monster that returns `default` if a == b is False else "yes".
 
S

Steven D'Aprano

Albert van der Horst said:
Old hands would have ...
stamp =( weight>=1000 and 120 or
weight>=500 and 100 or
weight>=250 and 80 or
weight>=100 and 60 or
44 )

(Kind of a brain twister, I think, inferior to C, once the c-construct
is accepted as idiomatic.)

I doubt many old hands would try to join multiple and/or operators that
way. Most old hands would (IMHO) write the if statements out in full,
though some might remember that Python comes 'batteries included':

from bisect import bisect
WEIGHTS = [100, 250, 500, 1000]
STAMPS = [44, 60, 80, 100, 120]

...
stamp = STAMPS[bisect(WEIGHTS,weight)]


Isn't that an awfully heavyweight and obfuscated solution for choosing
between five options? Fifty-five options, absolutely, but five?
 
E

Emile van Sebille

On 4/6/2010 9:20 PM Steven D'Aprano said...
Most old hands would (IMHO) write the if statements out in full,
though some might remember that Python comes 'batteries included':

from bisect import bisect
WEIGHTS = [100, 250, 500, 1000]
STAMPS = [44, 60, 80, 100, 120]

...
stamp = STAMPS[bisect(WEIGHTS,weight)]


Isn't that an awfully heavyweight and obfuscated solution for choosing
between five options? Fifty-five options, absolutely, but five?

Would it be easier to digest as:

from bisect import bisect as selectindex #

WEIGHTLIMITS = [100, 250, 500, 1000]
POSTAGEAMOUNTS = [44, 60, 80, 100, 120]

postage = POSTAGEAMOUNTS[selectindex(WEIGHTLIMITS, weight)]

---

I've used bisect this way for some time -- I think Tim may have pointed
it out -- and it's been handy ever since.

Emile
 
A

Aahz

It exists because people nagged Guido mercilessly until, against his
better judgment, he capitulated.

No, the ternary exists because he became convinced that it was the
lesser evil compared with letting the abomination of

A and B or C

remain the "Pythonic" ternary and someone came up with a syntax that
wasn't completely painful.
 
S

Steven D'Aprano

No, the ternary exists because he became convinced that it was the
lesser evil compared with letting the abomination of

A and B or C

remain the "Pythonic" ternary and someone came up with a syntax that
wasn't completely painful.



As I recall, Guido himself got bitten by a subtle bug in the A and B or C
idiom for ternary operator. Namely, if B is a false value, you get C even
if A is true.
 
D

Dotan Cohen

Hi, how can I write the popular C/JAVA syntax in Python?

Java example:
   return (a==b) ? 'Yes' : 'No'

My first idea is:
   return ('No','Yes')[bool(a==b)]

Is there a more elegant/common python expression for this?

I'm a little late to the party, but I just saw this in Dive Into Python:
multiple = 1024 if a_kilobyte_is_1024_bytes else 1000

It's kind of sloppy as the condition is between the possible values,
but it works.

--
Dotan Cohen

http://bido.com
http://what-is-what.com

Please CC me if you want to be sure that I read your message. I do not
read all list mail.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,780
Messages
2,569,607
Members
45,240
Latest member
pashute

Latest Threads

Top