brennerm/PyTricks

`<true> if <predicate> else <false>` vs. `<predicate> and <true> or <false>`

Closed this issue · 3 comments

Why not use the <true> if <predicate> else <false> structure instead?
It is a designed feature of the language, not a hack of the type system.

print(a < 0 and 'negative' or 'positive')

<true> if <predicate> else <false>is shown off in conditionalassignment.py. I agree that the and-or way is more of a hack. Nevertheless it's a possible way of a conditional assignment.

and/or also feels pretty questionable to me. It feels like it needs a clear disclaimer saying "just because you can do something doesn't mean you should" and indicating the tradeoffs between the two options:

  • In general, if/else is more common, therefore more readable and has the same assignment properties.
  • There are some subtle differences in execution path, but there might be a (rare) case where you actually want and/or.

Check this out:

# Just naming these to be clear which values are being tested
false_value = False
true_value = True

print('# and/or execution paths:')
true_value and print('true_value truthy') or print('true_value falsey')
false_value and print('false_value truthy') or print('false_value falsey')

print('# if/else execution paths:')
print('true_value truthy') if true_value else print('true_value falsey')
print('false_value truthy') if false_value else print('false_value falsey')

What do you expect the output to be? Here it is:

# and/or execution paths:                                                                                                                                                                                                                     
true_value truthy                                                                                                                                                                                                                             
true_value falsey                                                                                                                                                                                                                             
false_value falsey                                                                                                                                                                                                                            
# if/else execution paths:                                                                                                                                                                                                                    
true_value truthy                                                                                                                                                                                                         
false_value falsey 

Didn't expect this output :o
I'll remove it.