Next / Previous / Contents / TCC Help System / NM Tech homepage

10.2. MixedUnits.mixToSingle(): Convert to a single value

This method converts a value in mixed units to a single value in the largest unit.

sidereal.py
# - - -   M i x e d U n i t s . m i x T o S i n g l e

    def mixToSingle ( self, coeffs ):
        """Convert mixed units to a single value.

          [ coeffs is a sequence of numbers not longer than
            len(self.factors)+1 ->
              return the equivalent single value in self's system ]
        """

First let's work out the math. Consider the days-hours-minutes-seconds system: the factor list is (24, 60, 60). So there are 24 hours in a day; 24×60 or 1440 minutes in a day; and 24×60×60 or 86,400 seconds in a day.

The formula we use for conversion depends on how many elements are in the coeffs sequence. If there is only one value, it is treated as days. Two values are treated as days and hours; three values are treated as days, hours, and minutes; and so on. Here are the equations for converting coeffs values of one, two, three, and four elements, respectively:

For example, the expression for reducing 38° 52′ 30.7″ to decimal degrees is ((30.7/60)+52)/60+38 or about 38.875194 degrees.

Note the way we rewrite the expressions to form a sequence of alternating divide and add operations, starting with the smallest units and working toward the largest. This suggests the form of the evaluation loop: we will work through the factor list from right to left, adding to the total a value from coeffs, and then dividing the total by the corresponding factor in turn. Finally we add the first element of coeffs, unweighted.

In order to simplify the logic that matches elements of coeffs to their corresponding elements of the factor list, if coeffs is shorter than the maximum length, we'll make a copy of coeffs with zero elements added on the right if necessary to pad it to the standard length. See Section 10.3, “MixedUnits.__pad(): Pad short coefficient lists to standard length”, which may raise ValueError if there are too many elements.

sidereal.py
        #-- 1 --
        total  =  0.0

        #-- 2 --
        # [ if  len(coeffs) <= len(self.factors)+1 ->
        #     coeffList  :=  a copy of coeffs, right-padded to length
        #         len(self.factors)+1 with zeroes if necessary ]
        coeffList  =  self.__pad ( coeffs )

At this point, we use Python's negative indexing convention to work through the coefficients from right to left, adding each coefficient, then dividing by the factor list element at the same position. The range() expression here generates the sequence [-1, -2, …, -len(self.factors)].

sidereal.py
        #-- 3 --
        # [ total  +:=  (coeffList[-1] * 
        #        (product of all elements of self.factors)) +
        #       (coeffList[-2] *
        #        (product of all elements of self.factors[:-1])) +
        #       (coeffList[-3] *
        #        (product of all elements of self.factors[:-2]))
        #        ... ]
        for  i in range ( -1, -len(self.factors)-1, -1):
            total  +=  coeffList[i]
            total  /=  self.factors[i]

That takes care of all elements of coeffList but the first; we add that one in, unweighted.

sidereal.py
        #-- 4 --
        total  +=  coeffList[0]

        #-- 5 --
        return total