• Hack or beauty?

    From Michael F. Stemper@3:633/10 to All on Wed May 13 13:58:50 2026
    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:
    if options.angle:
    angle = variable
    else:
    X_C = variable * -X_L

    junk = sys.stdout.write( "%4.2f %4.3f\n" % (angle,X_C) )
    # 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.

    --
    Michael F. Stemper
    Always use apostrophe's and "quotation marks" properly.

    --- PyGate Linux v1.5.14
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Mark Bourne@3:633/10 to All on Wed May 13 21:52:27 2026
    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.

    --- PyGate Linux v1.5.14
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Lawrence D?Oliveiro@3:633/10 to All on Wed May 13 21:37:55 2026
    On Wed, 13 May 2026 13:58:50 -0500, Michael F. Stemper wrote:

    for variable in angles if options.angle else comps:

    The ?®true-part¯ if ®cond¯ else ®false-part¯? conditional expression
    syntax in Python is something I consider to be one of the few real
    mistakes in the design of the language. Every other language adopts
    the C-style syntax ?®cond¯ ? ®true-part¯ : ®false-part¯?, but Python
    had to be different, just for the sake of being different.

    --- PyGate Linux v1.5.14
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Lawrence D?Oliveiro@3:633/10 to All on Thu May 14 01:06:51 2026
    On 13 May 2026 21:04:59 GMT, Stefan Ram wrote:

    Just today, I wrote something similar:

    if mode == "file":
    storage_context = FileStorage()
    elif mode == "database":
    storage_context = DatabaseStorage( server )

    FYI, the ?match? statement is now a standard part of all supported
    versions of Python.

    --- PyGate Linux v1.5.14
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Michael F. Stemper@3:633/10 to All on Thu May 14 08:06:06 2026
    On 13/05/2026 15.52, Mark Bourne wrote:
    Michael F. Stemper wrote:

    ============================================================
    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).

    I'm familiar with that notation from C. I didn't know that it was also in
    Java, but that's due to my low level of Java knowledge. But, this comparison certainly helps.

    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):
    ```

    Yeah, I should probably at least parenthesize it.

    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.

    I only pasted the tiny portion of the program that was relevant to
    my question. I skipped the first 140+ lines, including getting both
    of those (and a bunch of other stuff) from an xml file.


    ÿÿ 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.

    No, junk is just that -- junk. I adopted this idiom a few weeks after
    the write() function started returning a value. I often paste some
    code into REPL for test/debug. Having the function value output,
    interleaved with real output was quite confusing -- especially in
    cases where at program has multiple invocations of write() to produce
    a single line of output. Assigning the function output to a variable
    nicely supresses its display in REPL.

    Thanks,
    --
    Michael F. Stemper
    If you take cranberries and stew them like applesauce they taste much
    more like prunes than rhubarb does.


    --- PyGate Linux v1.5.14
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)
  • From Michael F. Stemper@3:633/10 to All on Thu May 14 13:25:01 2026
    On 13/05/2026 14.33, Stefan Ram wrote:
    "Michael F. Stemper" <michael.stemper@gmail.com> wrote or quoted:
    for variable in angles if options.angle else comps:

    , is fine, but I think what would be a bit clearer might be,

    variables = angles if options.angle else comps
    for variable in variables:

    I ended up going with something quite similar:

    #####################################################
    if options.angle:
    junk = sys.stdout.write( "0.00 " )
    variables = [pi/20*k for k in range(1,8)]
    else:
    junk = sys.stdout.write( " 0% " )
    variables = [0.1*k for k in range(1,8)]

    # ...

    # Loop over a range of angle or compensation values
    for variable in variables:
    # Do stuff
    ####################################################


    Much clearer and less "cute".

    (Yes, the range of angles changed from my prototype.)

    --
    Michael F. Stemper
    What happens if you play John Cage's "4'33" at a slower tempo?


    --- PyGate Linux v1.5.14
    * Origin: Dragon's Lair, PyGate NNTP<>Fido Gate (3:633/10)