Proposal: min(None, x) and max(None, x) return x

John Hunter jdhunter at ace.bsd.uchicago.edu
Fri Nov 22 12:15:17 EST 2002


>>>>> "Eric" == Eric Brunel <eric.brunel at pragmadev.com> writes:

    Eric> Okay, it only saves 3 lines, but I personally find it quite
    Eric> natural... In addition, today, min(None, x) and max(None, x)
    Eric> work, but have strange results: as far as I can see,
    Eric> min(None, x) is always None and max(None, x) is always x,
    Eric> but this behaviour isn't documented.

This case comes up for me a lot too, and I was annoyed by the extra
syntax to handle it so I wrote a helper class CmpTrue, which enables
you to save some typing

xMax =CmpTrue()
for -whatever-:
  # big calculation leading to x
  if xMax<x: xMax = x


CmpTrue overloads all comparison operators to return true for the
first comparison.  After that, the name xMax is assigned to a new
object, so the CmpTrue weirdness is only used in the first pass.

I also overloaded the binary arithmetic operators to just return self
so I could so things like

    storedVal = CmpTrue()
    for x in y:
      thisVal = func(x)
      if 2*thisVal-1 < storedVal: storedVal = thisVal

But I'm not sure I'm comfortable with this.  I probably ought to add a
default init value so this class can be used to either CmpTrue or
CmpFalse on the first pass, and then rename it.

John Hunter

class CmpTrue:
    """
    Return true on any comparison.  This is useful when you want to
    set a default variable at initialization that will be overridden
    on first comparison, as in

    minVal = None
    for seq in allSeqs:
      minSeq = min(seq)
      if minVal is None:
        minVal = minSeq
        break
      if minSeq < minVal: minVal = minSeq

    This song and dance can be simplified in CmpTrue to
    minVal = CmpTrue()
    for seq in allSeqs:
      minSeq = min(seq)
      if minSeq < minVal: minVal = minSeq

    With the arithmetic functions defined to return a CmpTrue object,
    you can do things like

    minVal = CmpTrue()
    for seq in allSeqs:
      minSeq = min(seq)
      if 2*minSeq-1 < minVal: minVal = minSeq

    Use with caution!
    
    """

    __returnTrue = ['__lt__', '__le__', '__eq__', '__ne__', '__gt__',
                    '__ge__', '__cmp__', '__rcmp__']



    __returnSelf = ['__add__', '__sub__', '__mul__', '__div__',
                    '__mod__', '__divmod__', '__pow__', '__lshift__',
                    '__rshift__', '__rsub__', '__rmul__', '__rdiv__',
                    '__rmod__', '__rdivmod__', '__rpow__',
                    '__rlshift__', '__rrshift__']


    def __init__(self):

        for func in self.__returnTrue:
            self.__dict__[func] = self.__return_true

        for func in self.__returnSelf:
            self.__dict__[func] = self.__return_self

    def __return_self(self, arg=None):
        return self

    def __return_true(self, arg=None):
        return 1

    def __str__(self):
        return "It's true, really"









More information about the Python-list mailing list