Michael F. Stemper wrote:
I have a program that does some calculations for multiple
different values of a certain quantity. I wanted to either
write a second program that would hold the first quantity
fixed and loop over a different one, or to extend the
first to do either of those based on a command-line option.
While noodling around, I thought "what about --" and came up
with the following idea:
============================================================
if options.angle:
angles = [0.05*k for k in range(7)]
else:
comps = [0.1*k for k in range(6)]
for variable in angles if options.angle else comps:
The `angles if options.angle else comps` part evaluates to either
`angles` or `comps` depending on the value of `options.angle`. It's
sometimes called a "ternary operator" because it operates on three
values (the condition and two possible results). If you're familiar
with C or Java, it's similar to `options.angle ? angles : comps` (don't
worry if you're not familiar with C/Java; just though that might help
explain if you do happen to be).
The `for` loop then iterates over whichever of `angles` or `comps` is
the result. With parentheses to clarify, it's equivalent to:
```
for variable in (angles if options.angle else comps):
```
Or similar to doing:
```
values = angles if options.angle else comps
for variable in values:
```
Personally, if I were going to use a loop like this, I'd probably write
it in one or other of those two forms so that it's clearer what it does
for someone reading it. Stephan noted that it at least needs the
parentheses to work in a list comprehension which is probably because,
in comprehensions, `if` is used (without an `else`) to select which
items yielded by `for` are to be included.
if options.angle:
angle = variable
else:
X_C = variable * -X_L
As far as I can see, depending on `options.angle`, either `angle` or
`X_C` is not defined. Unless they're each set to an initial/default
value somewhere earlier, the next line is bound to fail.
junk = sys.stdout.write( "%4.2f %4.3f\n" % (angle,X_C) )
Is there a reason not to just use `print("%4.2f %4.3f" % (angle,X_C))?
Unless `junk` is actually used later, you shouldn't need to assign the
return value to anything.
# Hard part elided for clarity
============================================================
I was surprised to see that one could actually write a
for-loop like that, although it tickled my inner hacker.
What I'd like to know is: Is this an egregious abuse of the
language, or is it perfectly pythonic?
Opinions, and even violent disagreement, are solicited.
Given the number of places different code is needed depending on
`options.angle`, I'd probably split the "hard part" (and that
stdout.write/print) out into a separate function and do something like:
```
if options.angle:
angles = [0.05*k for k in range(7)]
# X_C = something
for angle in angles:
hard_part(angle, X_C)
else:
# angle = something
comps = [0.1*k for k in range(6)]
for X_C in comps:
hard_part(angle, X_C)
def hard_part(angle, X_C):
sys.stdout.write("%4.2f %4.3f\n" % (angle, X_C))
# or:
# print("%4.2f %4.3f" % (angle, X_C))
# Hard part elided for clarity
```
--
Mark.
--
https://mail.python.org/mailman3//lists/python-list.python.org