New assignmens ...

Avi Gross avigross at verizon.net
Wed Oct 27 20:06:57 EDT 2021


Dave,

You make me wonder about unintended side effects. Are we allowing the ++ and
--- operations into Python through a side door?

any context that allows you to insert the walrus operator like:

	index := index + 1
	index := index - 1

Is now similar to notations in C/C++ and others like 
	++index
	--index

If you can set or reset a variable this way, it can even look more efficient
that counting by 2 or more which in C would look like:

	++(++index)

Of course we now would get suggestions to just add the pre-increment
operator to Python, and while we are added, for completeness, add the
post-increment version of index++ ...

I mean if cost is no object, and worrying how it may impact current programs
or conflicts is nothing to be concerned about in the interest of some
academic purity ...


-----Original Message-----
From: Python-list <python-list-bounces+avigross=verizon.net at python.org> On
Behalf Of dn via Python-list
Sent: Wednesday, October 27, 2021 4:38 AM
To: python-list at python.org
Subject: Re: New assignmens ...

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
--
https://mail.python.org/mailman/listinfo/python-list



More information about the Python-list mailing list