2004-01-04 12:30:47 -05:00
|
|
|
|
PEP: 326
|
2004-01-06 10:34:49 -05:00
|
|
|
|
Title: A Case for Top and Bottom Values
|
2004-01-04 12:30:47 -05:00
|
|
|
|
Version: $Revision$
|
|
|
|
|
Last-Modified: $Date$
|
2004-01-06 10:34:49 -05:00
|
|
|
|
Author: Josiah Carlson <jcarlson@uci.edu>,
|
|
|
|
|
Terry Reedy <tjreedy@udel.edu>
|
2004-01-04 12:30:47 -05:00
|
|
|
|
Status: Draft
|
|
|
|
|
Type: Standards Track
|
|
|
|
|
Content-Type: text/x-rst
|
|
|
|
|
Created: 20-Dec-2003
|
|
|
|
|
Python-Version: 2.4
|
2004-01-08 21:36:27 -05:00
|
|
|
|
Post-History: 20-Dec-2003, 03-Jan-2004, 05-Jan-2004, 07-Jan-2004
|
2004-01-04 12:30:47 -05:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Abstract
|
|
|
|
|
========
|
|
|
|
|
|
2004-01-08 21:36:27 -05:00
|
|
|
|
This PEP proposes two singleton constants that represent a top and
|
|
|
|
|
bottom [3]_ value: ``Max`` and ``Min`` (or two similarly suggestive
|
|
|
|
|
names [4]_; see `Open Issues`_).
|
2004-01-04 12:30:47 -05:00
|
|
|
|
|
2004-01-08 21:36:27 -05:00
|
|
|
|
As suggested by their names, ``Max`` and ``Min`` would compare higher
|
|
|
|
|
or lower than any other object (respectively). Such behavior results
|
|
|
|
|
in easier to understand code and fewer special cases in which a
|
|
|
|
|
temporary minimum or maximum value is required, and an actual minimum
|
|
|
|
|
or maximum numeric value is not limited.
|
2004-01-04 12:30:47 -05:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Rationale
|
|
|
|
|
=========
|
|
|
|
|
|
2004-01-06 10:34:49 -05:00
|
|
|
|
While ``None`` can be used as an absolute minimum that any value can
|
2004-01-08 21:36:27 -05:00
|
|
|
|
attain [1]_, this may be depreciated [4]_ in Python 3.0, and shouldn't
|
2004-01-06 10:34:49 -05:00
|
|
|
|
be relied upon.
|
2004-01-04 12:30:47 -05:00
|
|
|
|
|
2004-01-06 10:34:49 -05:00
|
|
|
|
As a replacement for ``None`` being used as an absolute minimum, as
|
2004-01-08 21:36:27 -05:00
|
|
|
|
well as the introduction of an absolute maximum, the introduction of
|
|
|
|
|
two singleton constants ``Max`` and ``Min`` address concerns for the
|
|
|
|
|
constants to be self-documenting.
|
2004-01-04 12:30:47 -05:00
|
|
|
|
|
2004-01-06 10:34:49 -05:00
|
|
|
|
What is commonly done to deal with absolute minimum or maximum values,
|
|
|
|
|
is to set a value that is larger than the script author ever expects
|
|
|
|
|
the input to reach, and hope that it isn't reached.
|
2004-01-04 12:30:47 -05:00
|
|
|
|
|
|
|
|
|
Guido has brought up [2]_ the fact that there exists two constants
|
2004-01-06 10:34:49 -05:00
|
|
|
|
that can be used in the interim for maximum values: sys.maxint and
|
|
|
|
|
floating point positive infinity (1e309 will evaluate to positive
|
|
|
|
|
infinity). However, each has their drawbacks.
|
|
|
|
|
|
|
|
|
|
- On most architectures sys.maxint is arbitrarily small (2**31-1 or
|
|
|
|
|
2**63-1) and can be easily eclipsed by large 'long' integers or
|
|
|
|
|
floating point numbers.
|
|
|
|
|
|
|
|
|
|
- Comparing long integers larger than the largest floating point
|
|
|
|
|
number representable against any float will result in an exception
|
|
|
|
|
being raised::
|
2004-01-04 12:30:47 -05:00
|
|
|
|
|
2004-01-06 10:34:49 -05:00
|
|
|
|
>>> cmp(1.0, 10**309)
|
|
|
|
|
Traceback (most recent call last):
|
|
|
|
|
File "<stdin>", line 1, in ?
|
|
|
|
|
OverflowError: long int too large to convert to float
|
2004-01-04 12:30:47 -05:00
|
|
|
|
|
2004-01-06 10:34:49 -05:00
|
|
|
|
Even when large integers are compared against positive infinity::
|
2004-01-04 12:30:47 -05:00
|
|
|
|
|
2004-01-06 10:34:49 -05:00
|
|
|
|
>>> cmp(1e309, 10**309)
|
|
|
|
|
Traceback (most recent call last):
|
|
|
|
|
File "<stdin>", line 1, in ?
|
|
|
|
|
OverflowError: long int too large to convert to float
|
2004-01-04 12:30:47 -05:00
|
|
|
|
|
2004-01-06 10:34:49 -05:00
|
|
|
|
- These same drawbacks exist when numbers are small.
|
|
|
|
|
|
2004-01-08 21:36:27 -05:00
|
|
|
|
Introducing ``Max`` and ``Min`` that work as described above does not
|
|
|
|
|
take much effort. A sample Python `reference implementation`_ of both
|
|
|
|
|
is included.
|
2004-01-04 12:30:47 -05:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Motivation
|
|
|
|
|
==========
|
|
|
|
|
|
|
|
|
|
There are hundreds of algorithms that begin by initializing some set
|
2004-01-06 10:34:49 -05:00
|
|
|
|
of values to a logical (or numeric) infinity or negative infinity.
|
|
|
|
|
Python lacks either infinity that works consistently or really is the
|
2004-01-08 21:36:27 -05:00
|
|
|
|
most extreme value that can be attained. By adding ``Max`` and
|
|
|
|
|
``Min``, Python would have a real maximum and minimum value, and such
|
|
|
|
|
algorithms can become clearer due to the reduction of special cases.
|
|
|
|
|
|
|
|
|
|
``Max`` Examples
|
|
|
|
|
---------------------
|
2004-01-04 12:30:47 -05:00
|
|
|
|
|
|
|
|
|
Take for example, finding the minimum in a sequence::
|
|
|
|
|
|
|
|
|
|
def findmin_Num(seq):
|
|
|
|
|
BIG = 0
|
|
|
|
|
cur = BIG
|
|
|
|
|
for obj in seq:
|
|
|
|
|
if cur == BIG:
|
|
|
|
|
cur = obj
|
|
|
|
|
BIG = max(cur, BIG) + 1
|
|
|
|
|
else:
|
|
|
|
|
cur = min(cur, obj)
|
|
|
|
|
return cur
|
|
|
|
|
|
2004-01-06 10:34:49 -05:00
|
|
|
|
::
|
|
|
|
|
|
2004-01-04 12:30:47 -05:00
|
|
|
|
def findmin_None(seq):
|
|
|
|
|
cur = None
|
|
|
|
|
for obj in seq:
|
|
|
|
|
if obj < cur or (cur is None):
|
|
|
|
|
cur = obj
|
|
|
|
|
if cur is None:
|
|
|
|
|
return cur
|
|
|
|
|
return cur
|
2004-01-06 10:34:49 -05:00
|
|
|
|
|
|
|
|
|
::
|
|
|
|
|
|
2004-01-08 21:36:27 -05:00
|
|
|
|
def findmin_Max(seq):
|
|
|
|
|
cur = Max
|
2004-01-04 12:30:47 -05:00
|
|
|
|
for obj in seq:
|
|
|
|
|
cur = min(obj, cur)
|
|
|
|
|
return cur
|
|
|
|
|
|
2004-01-06 10:34:49 -05:00
|
|
|
|
Please note that there are an arbitrarily large number of ways to find
|
|
|
|
|
the minimum (or maximum) of a sequence, these seek to show a simple
|
2004-01-08 21:36:27 -05:00
|
|
|
|
example where using ``Max`` makes the algorithm easier to understand
|
|
|
|
|
and results in the simplification of code.
|
2004-01-06 10:34:49 -05:00
|
|
|
|
|
2004-01-04 12:30:47 -05:00
|
|
|
|
Guido brought up the idea of just negating everything and comparing
|
|
|
|
|
[2]_. Certainly this does work when using numbers, but it does not
|
|
|
|
|
remove the special case (actually adds one) and results in the code
|
|
|
|
|
being less readable. ::
|
|
|
|
|
|
2004-01-08 21:36:27 -05:00
|
|
|
|
#we have Max available
|
2004-01-04 12:30:47 -05:00
|
|
|
|
a = min(a, b)
|
|
|
|
|
|
2004-01-08 21:36:27 -05:00
|
|
|
|
#we don't have Max available
|
2004-01-04 12:30:47 -05:00
|
|
|
|
if a is not None:
|
|
|
|
|
if b is None:
|
|
|
|
|
a = b
|
|
|
|
|
else:
|
|
|
|
|
a = -max(-a, -b)
|
|
|
|
|
|
2004-01-06 10:34:49 -05:00
|
|
|
|
As another example, in Dijkstra's shortest path algorithm on a graph
|
|
|
|
|
with weighted edges (all positive).
|
|
|
|
|
|
|
|
|
|
1. Set distances to every node in the graph to infinity.
|
|
|
|
|
2. Set the distance to the start node to zero.
|
|
|
|
|
3. Set visited to be an empty mapping.
|
|
|
|
|
4. While shortest distance of a node that has not been visited is less
|
|
|
|
|
than infinity and the destination has not been visited.
|
|
|
|
|
|
|
|
|
|
a. Get the node with the shortest distance.
|
|
|
|
|
b. Visit the node.
|
|
|
|
|
c. Update neighbor distances and parent pointers if necessary for
|
|
|
|
|
neighbors that have not been visited.
|
|
|
|
|
|
|
|
|
|
5. If the destination has been visited, step back through parent
|
|
|
|
|
pointers to find the reverse of the path to be taken.
|
|
|
|
|
|
|
|
|
|
To be complete, below are two versions of the algorithm, one using a
|
|
|
|
|
table (a bit more understandable) and one using a heap (much faster)::
|
|
|
|
|
|
|
|
|
|
def DijkstraSP_table(graph, S, T):
|
|
|
|
|
#runs in O(N^2) time using a table
|
|
|
|
|
#find the shortest path
|
|
|
|
|
table = {}
|
|
|
|
|
for node in graph.iterkeys():
|
|
|
|
|
#(visited, distance, node, parent)
|
2004-01-08 21:36:27 -05:00
|
|
|
|
table[node] = (0, Max, node, None)
|
2004-01-06 10:34:49 -05:00
|
|
|
|
table[S] = (0, 0, S, None)
|
|
|
|
|
cur = min(table.values())
|
2004-01-08 21:36:27 -05:00
|
|
|
|
while (not cur[0]) and cur[1] < Max:
|
2004-01-06 10:34:49 -05:00
|
|
|
|
(visited, distance, node, parent) = cur
|
|
|
|
|
table[node] = (1, distance, node, parent)
|
|
|
|
|
for cdist, child in graph[node]:
|
|
|
|
|
ndist = distance+cdist
|
|
|
|
|
if not table[child][0] and ndist < table[child][1]:
|
|
|
|
|
table[child] = (0, ndist, child, node)
|
|
|
|
|
cur = min(table.values())
|
|
|
|
|
#backtrace through results
|
|
|
|
|
if not table[T][0]:
|
|
|
|
|
return None
|
|
|
|
|
cur = T
|
|
|
|
|
path = [T]
|
|
|
|
|
while table[cur][3] is not None:
|
|
|
|
|
path.append(table[cur][3])
|
|
|
|
|
cur = path[-1]
|
|
|
|
|
path.reverse()
|
|
|
|
|
return path
|
|
|
|
|
|
|
|
|
|
::
|
2004-01-04 12:30:47 -05:00
|
|
|
|
|
2004-01-06 10:34:49 -05:00
|
|
|
|
def DijkstraSP_heap(graph, S, T):
|
|
|
|
|
#runs in O(NlgN) time using a minheap
|
|
|
|
|
#find the shortest path
|
|
|
|
|
import heapq
|
2004-01-08 21:36:27 -05:00
|
|
|
|
Q = [(Max, i, None) for i in graph.iterkeys()]
|
2004-01-06 10:34:49 -05:00
|
|
|
|
heapq.heappush(Q, (0, S, None))
|
|
|
|
|
V = {}
|
2004-01-08 21:36:27 -05:00
|
|
|
|
while Q[0][0] < Max and T not in V:
|
2004-01-06 10:34:49 -05:00
|
|
|
|
dist, node, parent = heapq.heappop(Q)
|
|
|
|
|
if node in V:
|
|
|
|
|
continue
|
|
|
|
|
V[node] = (dist, parent)
|
|
|
|
|
for next, dest in graph[node]:
|
|
|
|
|
heapq.heappush(Q, (next+dist, dest, node))
|
|
|
|
|
#backtrace through results
|
|
|
|
|
if T not in V:
|
|
|
|
|
return None
|
|
|
|
|
cur = T
|
|
|
|
|
path = [T]
|
|
|
|
|
while V[cur][1] is not None:
|
|
|
|
|
path.append(V[cur][1])
|
|
|
|
|
cur = path[-1]
|
|
|
|
|
path.reverse()
|
|
|
|
|
return path
|
|
|
|
|
|
2004-01-08 21:36:27 -05:00
|
|
|
|
Readers should note that replacing ``Max`` in the above code with an
|
|
|
|
|
arbitrarily large number does not guarantee that the shortest path
|
2004-01-06 10:34:49 -05:00
|
|
|
|
distance to a node will never exceed that number. Well, with one
|
|
|
|
|
caveat: one could certainly sum up the weights of every edge in the
|
|
|
|
|
graph, and set the 'arbitrarily large number' to that total. However,
|
|
|
|
|
doing so does not make the algorithm any easier to understand and has
|
2004-01-08 21:36:27 -05:00
|
|
|
|
potential problems with numeric overflows.
|
2004-01-06 10:34:49 -05:00
|
|
|
|
|
|
|
|
|
|
2004-01-08 21:36:27 -05:00
|
|
|
|
A ``Min`` Example
|
|
|
|
|
-----------------
|
2004-01-06 10:34:49 -05:00
|
|
|
|
|
2004-01-08 21:36:27 -05:00
|
|
|
|
An example of usage for ``Min`` is an algorithm that solves the
|
|
|
|
|
following problem [6]_:
|
2004-01-06 10:34:49 -05:00
|
|
|
|
|
|
|
|
|
Suppose you are given a directed graph, representing a
|
|
|
|
|
communication network. The vertices are the nodes in the network,
|
|
|
|
|
and each edge is a communication channel. Each edge ``(u, v)`` has
|
|
|
|
|
an associated value ``r(u, v)``, with ``0 <= r(u, v) <= 1``, which
|
|
|
|
|
represents the reliability of the channel from ``u`` to ``v``
|
|
|
|
|
(i.e., the probability that the channel from ``u`` to ``v`` will
|
|
|
|
|
**not** fail). Assume that the reliability probabilities of the
|
|
|
|
|
channels are independent. (This implies that the reliability of
|
|
|
|
|
any path is the product of the reliability of the edges along the
|
|
|
|
|
path.) Now suppose you are given two nodes in the graph, ``A``
|
|
|
|
|
and ``B``.
|
|
|
|
|
|
|
|
|
|
Such an algorithm is a 7 line modification to the DijkstraSP_table
|
|
|
|
|
algorithm given above::
|
|
|
|
|
|
|
|
|
|
#only showing the changed to lines with the proper indentation
|
2004-01-08 21:36:27 -05:00
|
|
|
|
table[node] = (0, Min, node, None)
|
2004-01-06 10:34:49 -05:00
|
|
|
|
table[S] = (0, 1, S, None)
|
|
|
|
|
cur = max(table.values())
|
2004-01-08 21:36:27 -05:00
|
|
|
|
while (not cur[0]) and cur[1] > Min:
|
2004-01-06 10:34:49 -05:00
|
|
|
|
ndist = distance*cdist
|
|
|
|
|
if not table[child][0] and ndist > table[child][1]:
|
|
|
|
|
cur = max(table.values())
|
|
|
|
|
|
|
|
|
|
Or a 6 line modification to the DijkstraSP_heap algorithm given above
|
|
|
|
|
(if we assume that ``maxheapq`` exists and does what it is supposed
|
|
|
|
|
to)::
|
|
|
|
|
|
|
|
|
|
#only showing the changed to lines with the proper indentation
|
|
|
|
|
import maxheapq
|
2004-01-08 21:36:27 -05:00
|
|
|
|
Q = [(Min, i, None) for i in graph.iterkeys()]
|
2004-01-06 10:34:49 -05:00
|
|
|
|
maxheapq.heappush(Q, (1, S, None))
|
2004-01-08 21:36:27 -05:00
|
|
|
|
while Q[0][0] > Min and T not in V:
|
2004-01-06 10:34:49 -05:00
|
|
|
|
dist, node, parent = maxheapq.heappop(Q)
|
|
|
|
|
maxheapq.heappush(Q, (next*dist, dest, node))
|
|
|
|
|
|
|
|
|
|
Note that there is an equivalent way of translating the graph to
|
|
|
|
|
produce something that can be passed unchanged into the original
|
|
|
|
|
Dijkstra shortest path algorithm.
|
|
|
|
|
|
2004-01-08 21:36:27 -05:00
|
|
|
|
|
|
|
|
|
Other Examples
|
|
|
|
|
--------------
|
|
|
|
|
|
|
|
|
|
Andrew P. Lentvorski, Jr. [7]_ has pointed out that various data
|
|
|
|
|
structures involving range searching have immediate use for ``Max``
|
|
|
|
|
and ``Min`` values. More specifically; Segment trees, Range trees,
|
|
|
|
|
k-d trees and database keys:
|
|
|
|
|
|
|
|
|
|
...The issue is that a range can be open on one side and does not
|
|
|
|
|
always have an initialized case.
|
|
|
|
|
|
|
|
|
|
The solutions I have seen are to either overload None as the
|
|
|
|
|
extremum or use an arbitrary large magnitude number. Overloading
|
|
|
|
|
None means that the built-ins can't really be used without special
|
|
|
|
|
case checks to work around the undefined (or "wrongly defined")
|
|
|
|
|
ordering of None. These checks tend to swamp the nice performance
|
|
|
|
|
of built-ins like max() and min().
|
|
|
|
|
|
|
|
|
|
Choosing a large magnitude number throws away the ability of
|
|
|
|
|
Python to cope with arbitrarily large integers and introduces a
|
|
|
|
|
potential source of overrun/underrun bugs.
|
|
|
|
|
|
|
|
|
|
Further use examples of both ``Max`` and ``Min`` are available in the
|
|
|
|
|
realm of graph algorithms, range searching algorithms, computational
|
|
|
|
|
geometry algorithms, and others.
|
2004-01-06 10:34:49 -05:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Independent Implementations?
|
|
|
|
|
----------------------------
|
|
|
|
|
|
2004-01-08 21:36:27 -05:00
|
|
|
|
Independent implementations of the ``Min``/``Max`` concept by users
|
2004-01-06 10:34:49 -05:00
|
|
|
|
desiring such functionality are not likely to be compatible, and
|
2004-01-08 21:36:27 -05:00
|
|
|
|
certainly will produce inconsistent orderings. The following examples
|
|
|
|
|
seek to show how inconsistent they can be.
|
2004-01-06 10:34:49 -05:00
|
|
|
|
|
|
|
|
|
- Let us pretend we have created proper separate implementations of
|
2004-01-08 21:36:27 -05:00
|
|
|
|
MyMax, MyMin, YourMax and YourMin with the same code as given in
|
2004-01-06 10:34:49 -05:00
|
|
|
|
the sample implementation (with some minor renaming)::
|
|
|
|
|
|
2004-01-08 21:36:27 -05:00
|
|
|
|
>>> lst = [YourMin, MyMin, MyMin, YourMin, MyMax, YourMin, MyMax,
|
|
|
|
|
YourMax, MyMax]
|
2004-01-06 10:34:49 -05:00
|
|
|
|
>>> lst.sort()
|
|
|
|
|
>>> lst
|
2004-01-08 21:36:27 -05:00
|
|
|
|
[YourMin, YourMin, MyMin, MyMin, YourMin, MyMax, MyMax, YourMax,
|
|
|
|
|
MyMax]
|
2004-01-06 10:34:49 -05:00
|
|
|
|
|
2004-01-08 21:36:27 -05:00
|
|
|
|
Notice that while all the "Min"s are before the "Max"s, there is no
|
|
|
|
|
guarantee that all instances of YourMin will come before MyMin, the
|
|
|
|
|
reverse, or the equivalent MyMax and YourMax.
|
2004-01-06 10:34:49 -05:00
|
|
|
|
|
2004-01-08 21:36:27 -05:00
|
|
|
|
- The problem is also evident when using the heapq module::
|
2004-01-06 10:34:49 -05:00
|
|
|
|
|
2004-01-08 21:36:27 -05:00
|
|
|
|
>>> lst = [YourMin, MyMin, MyMin, YourMin, MyMax, YourMin, MyMax,
|
|
|
|
|
YourMax, MyMax]
|
2004-01-06 10:34:49 -05:00
|
|
|
|
>>> heapq.heapify(lst) #not needed, but it can't hurt
|
|
|
|
|
>>> while lst: print heapq.heappop(lst),
|
|
|
|
|
...
|
2004-01-08 21:36:27 -05:00
|
|
|
|
YourMin MyMin YourMin YourMin MyMin MyMax MyMax YourMax MyMax
|
2004-01-06 10:34:49 -05:00
|
|
|
|
|
2004-01-08 21:36:27 -05:00
|
|
|
|
- Furthermore, the findmin_Max code and both versions of Dijkstra
|
2004-01-06 10:34:49 -05:00
|
|
|
|
could result in incorrect output by passing in secondary versions of
|
2004-01-08 21:36:27 -05:00
|
|
|
|
``Max``.
|
2004-01-06 10:34:49 -05:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Reference Implementation
|
|
|
|
|
========================
|
2004-01-04 12:30:47 -05:00
|
|
|
|
|
|
|
|
|
::
|
|
|
|
|
|
2004-01-08 21:36:27 -05:00
|
|
|
|
class _ExtremeType(object):
|
2004-01-04 12:30:47 -05:00
|
|
|
|
|
2004-01-08 21:36:27 -05:00
|
|
|
|
def __init__(self, cmpr, rep):
|
|
|
|
|
object.__init__(self)
|
|
|
|
|
self._cmpr = cmpr
|
|
|
|
|
self._rep = rep
|
2004-01-06 10:34:49 -05:00
|
|
|
|
|
|
|
|
|
def __cmp__(self, other):
|
2004-01-08 21:36:27 -05:00
|
|
|
|
if isinstance(other, self.__class__) and\
|
|
|
|
|
other._cmpr == self._cmpr:
|
2004-01-06 10:34:49 -05:00
|
|
|
|
return 0
|
2004-01-08 21:36:27 -05:00
|
|
|
|
return self._cmpr
|
2004-01-06 10:34:49 -05:00
|
|
|
|
|
|
|
|
|
def __repr__(self):
|
2004-01-08 21:36:27 -05:00
|
|
|
|
return self._rep
|
2004-01-04 12:30:47 -05:00
|
|
|
|
|
2004-01-08 21:36:27 -05:00
|
|
|
|
Max = _ExtremeType(1, "Max")
|
|
|
|
|
Min = _ExtremeType(-1, "Min")
|
2004-01-04 12:30:47 -05:00
|
|
|
|
|
2004-01-08 21:36:27 -05:00
|
|
|
|
Results of Test Run::
|
2004-01-04 12:30:47 -05:00
|
|
|
|
|
2004-01-08 21:36:27 -05:00
|
|
|
|
>>> max(Max, 2**65536)
|
|
|
|
|
Max
|
|
|
|
|
>>> min(Max, 2**65536)
|
2004-01-04 12:30:47 -05:00
|
|
|
|
20035299304068464649790...
|
|
|
|
|
(lines removed for brevity)
|
|
|
|
|
...72339445587895905719156736L
|
2004-01-08 21:36:27 -05:00
|
|
|
|
>>> min(Min, -2**65536)
|
|
|
|
|
Min
|
|
|
|
|
>>> max(Min, -2**65536)
|
2004-01-06 10:34:49 -05:00
|
|
|
|
-2003529930406846464979...
|
|
|
|
|
(lines removed for brevity)
|
|
|
|
|
...072339445587895905719156736L
|
2004-01-04 12:30:47 -05:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Open Issues
|
|
|
|
|
===========
|
|
|
|
|
|
2004-01-08 21:36:27 -05:00
|
|
|
|
Current options for the naming and namespace for ``Min``/``Max``, in
|
|
|
|
|
no particular order:
|
2004-01-06 10:34:49 -05:00
|
|
|
|
|
2004-01-08 21:36:27 -05:00
|
|
|
|
1. Give the built-in ``max`` and ``min`` appropriate ``__cmp__``
|
|
|
|
|
methods to allow them to double as ``Min``/``Max``.
|
|
|
|
|
2. Attach them to attributes of the ``cmp()`` built-in.
|
|
|
|
|
3. Attach them to attributes of an appropriate type object.
|
|
|
|
|
4. Make them an appropriate module object.
|
|
|
|
|
5. Create two new built-ins with appropriate names.
|
2004-01-04 12:30:47 -05:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
References
|
|
|
|
|
==========
|
|
|
|
|
|
|
|
|
|
.. [1] RE: [Python-Dev] Re: Got None. Maybe Some?, Peters, Tim
|
|
|
|
|
(http://mail.python.org/pipermail/python-dev/2003-December/041374.html)
|
|
|
|
|
|
|
|
|
|
.. [2] Re: [Python-Dev] Got None. Maybe Some?, von Rossum, Guido
|
|
|
|
|
(http://mail.python.org/pipermail/python-dev/2003-December/041352.html)
|
|
|
|
|
|
2004-01-08 21:36:27 -05:00
|
|
|
|
.. [3] RE: [Python-Dev] Got None. Maybe Some?, Peters, Tim
|
2004-01-06 10:34:49 -05:00
|
|
|
|
(http://mail.python.org/pipermail/python-dev/2003-December/041332.html)
|
|
|
|
|
|
2004-01-08 21:36:27 -05:00
|
|
|
|
.. [4] [Python-Dev] Re: PEP 326 now online, Reedy, Terry
|
2004-01-06 10:34:49 -05:00
|
|
|
|
(http://mail.python.org/pipermail/python-dev/2004-January/041685.html)
|
|
|
|
|
|
2004-01-08 21:36:27 -05:00
|
|
|
|
.. [5] [Python-Dev] PEP 326 now online, Chermside, Michael
|
2004-01-06 10:34:49 -05:00
|
|
|
|
(http://mail.python.org/pipermail/python-dev/2004-January/041704.html)
|
|
|
|
|
|
2004-01-08 21:36:27 -05:00
|
|
|
|
.. [6] Homework 6, Problem 7, Dillencourt, Michael
|
2004-01-06 10:34:49 -05:00
|
|
|
|
(link may not be valid in the future)
|
|
|
|
|
(http://www.ics.uci.edu/~dillenco/ics161/hw/hw6.pdf)
|
|
|
|
|
|
2004-01-08 21:36:27 -05:00
|
|
|
|
.. [7] RE: [Python-Dev] PEP 326 now online, Lentvorski, Andrew P., Jr.
|
|
|
|
|
(http://mail.python.org/pipermail/python-dev/2004-January/041727.html)
|
|
|
|
|
|
|
|
|
|
.. [8] Re: It's not really Some is it?, Ippolito, Bob
|
|
|
|
|
(http://www.livejournal.com/users/chouyu_31/138195.html?thread=274643#t274643)
|
2004-01-04 12:30:47 -05:00
|
|
|
|
|
|
|
|
|
Changes
|
|
|
|
|
=======
|
|
|
|
|
|
2004-01-06 10:34:49 -05:00
|
|
|
|
- Added this section.
|
|
|
|
|
|
|
|
|
|
- Added Motivation_ section.
|
|
|
|
|
|
|
|
|
|
- Changed markup to reStructuredText.
|
|
|
|
|
|
2004-01-08 21:36:27 -05:00
|
|
|
|
- Concept gets a possible name and location. [5]_
|
2004-01-06 10:34:49 -05:00
|
|
|
|
|
|
|
|
|
- Clarified Abstract_, Motivation_, `Reference Implementation`_ and
|
2004-01-08 21:36:27 -05:00
|
|
|
|
`Open Issues`_ based on the simultaneous concepts of ``Max`` and
|
|
|
|
|
``Min``.
|
2004-01-04 12:30:47 -05:00
|
|
|
|
|
2004-01-06 10:34:49 -05:00
|
|
|
|
- Added two implementations of Dijkstra's Shortest Path algorithm that
|
2004-01-08 21:36:27 -05:00
|
|
|
|
show where ``Max`` can be used to remove special cases.
|
|
|
|
|
|
|
|
|
|
- Added an example of use for ``Min`` to Motivation_.
|
2004-01-04 12:30:47 -05:00
|
|
|
|
|
2004-01-08 21:36:27 -05:00
|
|
|
|
- Added some `Open Issues`_ and clarified some others.
|
2004-01-04 12:30:47 -05:00
|
|
|
|
|
2004-01-08 21:36:27 -05:00
|
|
|
|
- Added an example and `Other Examples`_ subheading.
|
2004-01-04 12:30:47 -05:00
|
|
|
|
|
2004-01-08 21:36:27 -05:00
|
|
|
|
- Modified `Reference Implementation`_ to instantiate both items from
|
|
|
|
|
a single class/type.
|
2004-01-04 12:30:47 -05:00
|
|
|
|
|
2004-01-08 21:36:27 -05:00
|
|
|
|
- Removed a large number of open issues that are not within the scope
|
|
|
|
|
of this PEP.
|
2004-01-04 12:30:47 -05:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Copyright
|
|
|
|
|
=========
|
|
|
|
|
|
|
|
|
|
This document has been placed in the public domain.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
..
|
|
|
|
|
Local Variables:
|
|
|
|
|
mode: indented-text
|
|
|
|
|
indent-tabs-mode: nil
|
|
|
|
|
sentence-end-double-space: t
|
2004-01-06 10:34:49 -05:00
|
|
|
|
fill-column: 70
|
2004-01-04 12:30:47 -05:00
|
|
|
|
End:
|