New assignmens ...

dn PythonList at DancesWithMice.info
Wed Oct 27 04:38:16 EDT 2021


On 24/10/2021 22.23, O365 Dict wrote:
> Well I have the following use case:
> 
>     while (temp_result := calculate_next_couple(a, b))[1]:
>         a, b = temp_result
>         more calculations
> 
> Which IMO would be clearer if I could just write:
> 
>     while ((a, b) := calculate_next_couple(a,b))[1]:
>         more calculations
> 
> Of course it would even more clear if I could write something like:
> 
>     while (a, b) := calculate_next_couple(a, b); b:
>         more calculations
> 
> or
> 
>     do:
>         a, b = calculate_next_couple(a, b)
>     while b:
>         more calculations


Found (all of) the above less-than-obvious to read. Putting it in front
of trainees this morning caused only confusion - even the
currently-legal variation.


Accordingly: is this a job for the walrus operator at all? Let's "talk
of many [other] things"*.


Is this an algorithmic complexity, or a complicated way to look at (and
manipulate) data?

Well, judging from the code (above), use of the walrus certainly
presumes the former. Instead let's review any possibility of the latter
(if only for academic interest)...


What do we want out of the first line? (in no particular order)

1 use calculate_next_couple() to compute (new) a from an (old) a and b
2 use calculate_next_couple() to compute (new) b from an (old) a and b
3 use (new) b to decide if the loop should execute or terminate

The 'problem' then, has been phrased as these three objectives ask too
much of the (current implementation of the) walrus-operator.


NB after one (or more) cycles, when the loop 'returns to the top', what
I've termed 'new' a and b (above), will become (my reference) the 'old'
pair/tuple.


That all looks simple. What is dn complaining about?


Could we use a data structure to continue to keep things straight-forward?

class my_class():
    def __init__( self, a, b )->None;
        self.a = a
        self.b = b

instance = my_class( a, b )


Sorry, you're probably becoming impatient with me. Surely I'm typing
more code than necessary? Maybe, but there are other measures of
code-quality/good-practice/etc, and there's likely more to 'it' than
just these few lines...


First consideration: the algorithm needs us to 'feed' the
while-condition. So let's flesh-out:

    def is_more( self )->bool:
        # you know what goes here - I don't, but that's not the issue
        # the return value is all that matters
        return is_there_any_more_data_to_calculate?

In which case, the loop becomes:

while instance.is_more():
    more calculations

and 'readability' improves immeasurably!

NB for extra credit, turn the boolean function into a "property", and be
able to omit the (unsightly?) parentheses from the 'call'!


But, not so fast - what about the calculation itself, currently embedded
in calculate_next_couple()?

Well, those details are out of my sight, and I'm assuming include
reasonable complexity - otherwise you wouldn't propose this as a
good-example. Allow me to muddle-through with:

    def calculate_next_couple( self )->None:
        self.a = calculation of 'new' a
        self.b = calculation of 'new' b

To avoid an 'extra' call against the instance from the while-loop,
execute the 'calculate' method from either __init__() or is_more(), as
appropriate (given that it likely needs to precede the return from the
latter - particularly if the computation is 'expensive'). The choice may
be subject-dependent ...


Now within "more calculations", one assumes, references to "a" and "b"
will need to be amended to become 'instance.a' and 'instance.b'. More
typing! What about preserving our fingers?


Readability will further improve when "a" and "b" (etc) are replaced by
'real names'.

The processing steps within "more calculations" could be reviewed. Some
may be candidates for inclusion as my_class methods - which would even
enable further simplifications and/or encapsulation of code-suites
relevant to the application, and/or "a" and "b" and the processes around
them.

If the "calculation" of 'next_couple' currently involves looking-up
another data-structure, eg a list of data-points, then combining such
with/into my_class may well yield further simplifications,
encapsulations, and benefits - but all in-theory and complete ignorance
of your application...


Hope the above gives you some ideas/pause for thought!


* this gratuitous and somewhat awkward expression is me claiming to be
clever by quoting Lewis Carroll - if he isn't sick of me
baiting-the-hook, it might earn extra brownie-points (or another groan)
from @Chris...
-- 
Regards,
=dn


More information about the Python-list mailing list