[Tutor] maxed out

avi.e.gross at gmail.com avi.e.gross at gmail.com
Sat Jul 9 18:08:56 EDT 2022


Now that Alan and Dennis have pointed things out, I want to summarize some
of the perspective I have.

The topic is why the max() (and probably min() and perhaps other) python
functions made the design choices they did and that they are NOT the only
possible choices. It confused me as I saw parts of the elephant without
seeing the entire outline.

So lesson one is READ THE MANUAL PAGE before making often unwarranted
assumptions. https://docs.python.org/3/library/functions.html#max

The problem originally presented was that using max() to measure the maximum
length of multiple instances of 0's interspersed with 1's resulted in what I
considered anomalies. Specifically, it stopped with an error on an empty
list which my algorithm would always  emit if there were no zero's.

My understanding is that in normal use, there are several views.

The practical view is that you should not be calling max() unless you have
multiple things to compare of the same kind. Thus a common use it should
deal with is:

max(5, 3, 2.4, 8.6, -2.3)

This being python, a related use is to hand it a SINGLE argument that is a
collection of it's own with the qualification that the items be compatible
with being compared to each other and are ordered. So tuples, lists and sets
and separately the keys and values of a dictionary come to mind. 

max(1,2,3)
3
max((1,2,3))
3
max([1,2,2])
2
max({1,3,4,3,5,2})
5
max({1:1.1, 2:1.2, 3:1.3}.keys())
3
max({1:1.1, 2:1.2, 3:1.3}.values())
1.3

There may well be tons of other things it can handle albeit I suspect
constructs from numpy or pandas may better be evaluated using their own
versions of functions like max that are built-in.

And it seems max now should handle iterables like this function:

def lowering(starting=100):
    using = int(starting)
    while (using > 0):
        yield(using)
        using //= 2

max(lowering(100))
100

min(lowering(100))
1

import statistics
statistics.mean(lowering(666))
132.7

len(list(lowering(42)))
6

But it is inconsistent as len will not see [lowering(42)] as more than one
argument as it sees an iterable function but does not iterate it.

Back to the point, from a practical point of view, you have to conditions. 

- Everything being measured should be of the same type or perhaps coercible
to the same type easily.
- You either have 2 or more things being asked about directly as in
max(1,2,3) OR you have a single argument that is an iterator.

So the decision they made almost makes sense to me except that it does not!

In a mathematical sense, a maximum also makes perfect sense for a single
value. The maximum for no arguments is clearly undefined. 

Following that logic, the max() function would need to test if the single
object it gets is SIMPLE or more complex (and I do not mean imaginary
numbers. I mean ANYTHING that evaluates to a single value, be it an integer,
floating point, Boolean or character string and maybe more, should return it
as the maximum. If it can be evaluated as a container that ends up holding
NO values, then it should fail unless a default is provided. If it returns a
single value, again, that is the result. If it returns multiple values ALL
OF THE SAME KIND, compare those.

Not sure if that is at all easy to implement, but does that overall design
concept make a tad more sense?

The problem Dennis hinted out is darn TUPLES in Python. They sort of need a
comma after a value if it is alone as in 

a = 1,
a
(1,)

And the darn tuple(function) stupidly has no easy way to make a tuple with a
single argument even if followed by an empty comma. Who designed that? I
mean it works for a string because it is actually a compound object as in
tuple("a") but not for tuple(1) so you need something like tuple([1]) ...

My GUESS from what Dennis wrote is the creators of max(0 may have said that
a singleton argument should be expanded only by coercing it to a tuple and
that makes some singleton arguments FAIL!

I looked at another design element in that this version of max also supports
other kinds of ordering for selected larger collections such as lists
containing objects of the same type:

max( [ 1, 1, 1], [1, 2, 1])
[1, 2, 1]
max( [ 1, 1, 1], [1, 2, 1], [3, 0])
[3, 0]

It won't take my iterator unless I expand it in a list like this:

max(list(lowering(42)), list(lowering(666)))
[666, 333, 166, 83, 41, 20, 10, 5, 2, 1]

So, overall, I understand why max does what it wants BUT I am not happy with
the fact that programs often have no control over the size of a list they
generate as in my case where no 0's means an empty list. So the default=0
argument there helps if used, albeit using the single argument to max()
method fails when used as max([] or 0) and requires something like max([] or
[0]) since the darn thing insists a single argument must be a sort of
container or iterable.

You learn something new every day if you look, albeit I sometimes wish I
hadn't!













-----Original Message-----
From: Tutor <tutor-bounces+avi.e.gross=gmail.com at python.org> On Behalf Of
Dennis Lee Bieber
Sent: Saturday, July 9, 2022 1:23 AM
To: tutor at python.org
Subject: Re: [Tutor] this group and one liners

On Fri, 8 Jul 2022 12:54:02 -0400, <avi.e.gross at gmail.com> declaimed the
following:


>I am not convinced this is fantastic design. The concept of an iterable 
>is very powerful but this brings us back to the question we began with. 
>Why not have a version of max() that accepts numbers like 1,2,3 as 
>individual arguments?
>
>>> max(1, 2, 3)
3
>>> 

	In the absence of keyword arguments, the non-keyword arguments are
gathered up as a tuple -- which is an iterable.

>>> tpl = (1, 2, 3)
>>> max(tpl)
3
>>> max(*tpl)
3
>>> 

	First passes single arg tuple. Second /unpacks/ the tuple, passing
three args, which get gathered back into a tuple by max().


-- 
	Wulfraed                 Dennis Lee Bieber         AF6VN
	wlfraed at ix.netcom.com    http://wlfraed.microdiversity.freeddns.org/

_______________________________________________
Tutor maillist  -  Tutor at python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor



More information about the Tutor mailing list