Next / Previous / Contents / Shipman's homepage

7.6. BigInfo.__cmp__(): The comparator method

When two instances of the PathInfo base class are compared, the .__cmp__() method in that class orders them by pathname.

In order to get BigInfo objects to sort in descending order by size (with the pathname as a tie-breaker), we redefine that method in this derived class.

bigfiles.py
# - - -   B i g I n f o . _ _ c m p _ _   - - -

    def __cmp__ ( self, other ):
        """Compare two BigInfo objects.

          [ other is a BigInfo object ->
              if self should precede other ->
                return a negative number
              else if self should follow other ->
                return a positive number
              else -> return 0 ]
        """

To make larger files precede smaller ones, we want to return a negative number if self.size is greater than other.size, a positive number if it is less, and zero if their .size attributes are equal. The cmp() function does this comparison, but backwards. So we can implement the comparison we want by inverting the sign of the result of cmp().

We need to consider at more than the file sizes, however. If there are multiple files with the same size, in what order should they be shown? We'll use the pathname as a secondary key. That way, if for example there are a lot of files with length 0, those files will be grouped together but sorted by pathname.

So the first step is to call the cmp() function to compare the sizes, and negate its result so we get descending instead of ascending order. If this result is nonzero, we can return it to the caller.

bigfiles.py
        #-- 1 --
        compare  =  - cmp ( self.size, other.size )

        #-- 2 --
        if compare != 0:
            return compare

If the sizes are equal, we then call cmp() again on the .path attributes, and return that.

bigfiles.py
        #-- 3 --
        return cmp(self.path, other.path)