Exemplo n.º 1
0
    def convertIncompatibleUnit( self, other ):
        if isinstance( other, list ):
            otherUnit = '[ ' + ', '.join( [ unit.getUnitString( ) for unit in other ] ) + ' ]'
        else:
            otherUnit = other.getUnitName( )

        # last chance check, some units are reciprocals of each other
        unit = self.getUnitName( )

        try:
            baseUnit1 = g.basicUnitTypes[ getUnitType( unit ) ].baseUnit
            baseUnit2 = g.basicUnitTypes[ getUnitType( otherUnit ) ].baseUnit
        except:
            inverted = self.getInverted( )

            try:
                return inverted.convert( other )
            except:
                raise ValueError( 'incompatible units cannot be converted: ' + self.getUnitName( ) + ' and ' + otherUnit )

        if ( baseUnit1, baseUnit2 ) in specialUnitConversionMatrix:
            debugPrint( '----->', self.getUnitName( ), baseUnit1, baseUnit2, otherUnit )
            result = RPNMeasurement( self )

            if ( unit != baseUnit1 ):
                result = self.convert( baseUnit1 )

            result = RPNMeasurement( specialUnitConversionMatrix[ ( baseUnit1, baseUnit2 ) ]( result.value ), baseUnit2 )

            if ( baseUnit2 != otherUnit ):
                result = result.convert( otherUnit )

            return result

        raise ValueError( 'incompatible units cannot be converted: ' + self.getUnitName( ) + ' and ' + otherUnit )
Exemplo n.º 2
0
    def convertToPrimitiveUnits(self):
        debugPrint()
        debugPrint('convertToPrimitiveUnits:', self.value, self.units)

        if not g.unitConversionMatrix:
            loadUnitConversionMatrix()

        value = self.value
        units = RPNUnits()

        debugPrint('value', value)

        for unit in self.units:

            if self.units[unit] == 0:
                continue

            newUnits = g.basicUnitTypes[getUnitType(unit)].primitiveUnit

            debugPrint('unit', unit, 'newUnits', newUnits)

            if unit != newUnits:
                debugPrint('unit vs newUnits:', unit, newUnits)

                if (unit, newUnits) in g.unitConversionMatrix:
                    value = fmul(
                        value,
                        power(mpf(g.unitConversionMatrix[(unit, newUnits)]),
                              self.units[unit]))
                elif (unit, newUnits) in specialUnitConversionMatrix:
                    value = power(
                        specialUnitConversionMatrix[(unit, newUnits)](value),
                        self.units[unit])
                else:
                    if unit == '1' and newUnits == '_null_unit':
                        reduced = RPNMeasurement(value, units)
                        debugPrint('convertToPrimitiveUnits 2:', reduced.value,
                                   reduced.units)
                        return reduced

                    raise ValueError('cannot find a conversion for ' + unit +
                                     ' and ' + newUnits)

            newUnits = RPNUnits(newUnits)

            for newUnit in newUnits:
                newUnits[newUnit] *= self.units[unit]

            units.update(newUnits)

            debugPrint('value', value)

        baseUnits = RPNMeasurement(value, units)
        debugPrint('convertToPrimitiveUnits 3:', baseUnits.value,
                   baseUnits.units)
        debugPrint()
        return baseUnits
Exemplo n.º 3
0
    def convertIncompatibleUnit(self, other):
        if isinstance(other, list):
            otherUnit = '[ ' + ', '.join(
                [unit.getUnitString() for unit in other]) + ' ]'
        else:
            otherUnit = other.getUnitName()

        # last chance check, some units are reciprocals of each other
        unit = self.getUnitName()

        try:
            baseUnit1 = g.basicUnitTypes[getUnitType(unit)].baseUnit
            baseUnit2 = g.basicUnitTypes[getUnitType(otherUnit)].baseUnit
        except ValueError:
            inverted = self.getInverted()

            if inverted.isCompatible(other):
                return inverted.convert(other)
            else:
                raise ValueError('incompatible units cannot be converted: ' +
                                 self.getUnitName() + ' and ' + otherUnit)

        if (baseUnit1, baseUnit2) in specialUnitConversionMatrix:
            # debugPrint( '----->', self.getUnitName( ), baseUnit1, baseUnit2, otherUnit )
            result = RPNMeasurement(self)

            if unit != baseUnit1:
                result = self.convert(baseUnit1)

            result = RPNMeasurement(
                specialUnitConversionMatrix[(baseUnit1,
                                             baseUnit2)](result.value),
                baseUnit2)

            if baseUnit2 != otherUnit:
                result = result.convert(otherUnit)

            return result

        raise ValueError('incompatible units cannot be converted: ' +
                         self.getUnitName() + ' and ' + otherUnit)
Exemplo n.º 4
0
    def convertToBaseUnits( self ):
        debugPrint( )
        debugPrint( 'convertToBaseUnits:', self.value, self.units )

        if not g.unitConversionMatrix:
            loadUnitConversionMatrix( )

        value = self.value
        units = RPNUnits( )

        debugPrint( 'value', value )

        for unit in self.units:
            newUnits = g.basicUnitTypes[ getUnitType( unit ) ].primitiveUnit

            debugPrint( 'unit', unit, 'newUnits', newUnits )

            if unit != newUnits:
                debugPrint( 'unit vs newUnits:', unit, newUnits )

                if ( unit, newUnits ) in g.unitConversionMatrix:
                    value = fmul( value, power( mpf( g.unitConversionMatrix[ ( unit, newUnits ) ] ), self.units[ unit ] ) )
                elif ( unit, newUnits ) in specialUnitConversionMatrix:
                    value = power( specialUnitConversionMatrix[ ( unit, newUnits ) ]( value ), self.units[ unit ] )
                else:
                    if unit == '1' and newUnits == '_null_unit':
                        reduced = RPNMeasurement( value, units )
                        debugPrint( 'convertToBaseUnits 2:', reduced.value, reduced.units )
                        return reduced
                    else:
                        raise ValueError( 'cannot find a conversion for ' + unit + ' and ' + newUnits )

            newUnits = RPNUnits( newUnits )

            for newUnit in newUnits:
                newUnits[ newUnit ] *= self.units[ unit ]

            units.update( newUnits )

            debugPrint( 'value', value )

        baseUnits = RPNMeasurement( value, units )
        debugPrint( 'convertToBaseUnits 3:', baseUnits.value, baseUnits.units )
        debugPrint( )
        return baseUnits
Exemplo n.º 5
0
    def getUnitTypes(self):
        types = RPNUnits()

        for unit in self.units:
            if unit == '1':
                continue

            if unit not in g.unitOperators:
                raise ValueError('1 undefined unit type \'{}\''.format(unit))

            unitType = getUnitType(unit)

            if unitType in types:
                types[unitType] += self.units[unit]
            elif self.units[unit] != 0:
                types[unitType] = self.units[unit]

        return types
Exemplo n.º 6
0
    def getUnitTypes( self ):
        types = RPNUnits( )

        for unit in self.units:
            if unit == '1':
                continue

            if unit not in g.unitOperators:
                raise ValueError( 'undefined unit type \'{}\''.format( unit ) )

            unitType = getUnitType( unit )

            if unitType in types:
                types[ unitType ] += self.units[ unit ]
            elif self.units[ unit ] != 0:
                types[ unitType ] = self.units[ unit ]

        return types
Exemplo n.º 7
0
    def convertValue(self, other):
        if not isinstance(other, (RPNUnits, RPNMeasurement, str, list)):
            raise ValueError(
                'convertValue must be called with an RPNUnits object, '
                'an RPNMeasurement object, a string or a list of RPNMeasurement'
            )

        if isinstance(other, (str, RPNUnits)):
            other = RPNMeasurement(1, other)

        if not self.isCompatible(other):
            # We can try to convert incompatible units.
            return self.convertIncompatibleUnit(other)

        if not g.unitConversionMatrix:
            loadUnitConversionMatrix()

        # handle list conversions like [ year, day, minute, hour ]
        if isinstance(other, list):
            # a list of length one is treated the same as a single measurement
            if len(other) == 1:
                return self.convertValue(other[0])
            else:
                listToConvert = []

                for i in other:
                    if isinstance(i, str):
                        listToConvert.append(RPNMeasurement(1, i))
                    elif isinstance(i, RPNMeasurement):
                        listToConvert.append(i)
                    else:
                        raise ValueError('we\'ve got something else')

                return self.convertUnitList(listToConvert)

        conversions = []

        value = self.value  # This is what we'll return down below

        # let's look for straightforward conversions
        units1 = self.units
        units2 = other.units

        unit1String = units1.getUnitString()
        unit2String = units2.getUnitString()

        if unit1String == unit2String:
            return value

        exponents = {}

        # look for a straight-up conversion
        if (unit1String, unit2String) in g.unitConversionMatrix:
            value = fmul(
                value,
                mpmathify(g.unitConversionMatrix[(unit1String, unit2String)]))
        elif (unit1String, unit2String) in specialUnitConversionMatrix:
            value = specialUnitConversionMatrix[(unit1String,
                                                 unit2String)](value)
        else:
            # TODO:  Should we just convert to base units regardless?  It would be safer...
            if other.doDimensionsCancel():
                other = other.convertToPrimitiveUnits()
                units2 = other.units
                value = fdiv(value, other.value)

            # otherwise, we need to figure out how to do the conversion
            conversionValue = value

            # if that isn't found, then we need to do the hard work and break the units down
            newUnits1 = RPNUnits(units1)
            newUnits2 = RPNUnits(units2)

            debugPrint('newUnits1:', newUnits1)
            debugPrint('newUnits2:', newUnits2)

            debugPrint()
            debugPrint('iterating through units to match for conversion:')

            for unit1 in newUnits1:
                foundConversion = False

                for unit2 in newUnits2:
                    debugPrint('units 1:', unit1, newUnits1[unit1],
                               getUnitType(unit1))
                    debugPrint('units 2:', unit2, newUnits2[unit2],
                               getUnitType(unit2))

                    if getUnitType(unit1) == getUnitType(unit2):
                        debugPrint('found a conversion:', unit1, unit2)
                        conversions.append((unit1, unit2))
                        exponents[(unit1, unit2)] = units1[unit1]
                        foundConversion = True
                        break

                if not foundConversion:
                    debugPrint()
                    debugPrint('didn\'t find a conversion, try reducing')
                    debugPrint()
                    reduced = self.convertToPrimitiveUnits()

                    debugPrint('reduced:', self.units, 'becomes',
                               reduced.units)

                    reducedOther = other.convertToPrimitiveUnits()

                    reduced.value = fdiv(reduced.value, reducedOther.value)

                    debugPrint('reduced other:', other.units, 'becomes',
                               reducedOther.units)

                    # check to see if reducing did anything and bail if it didn't... bail out
                    if (reduced.units == self.units) and (reducedOther.units
                                                          == other.units):
                        debugPrint('reducing didn\'t help')
                        break

                    return reduced.convertValue(reducedOther)

            debugPrint()

            value = conversionValue

            debugPrint('Iterating through conversions...')

            for conversion in conversions:
                if conversion[0] == conversion[1]:
                    continue  # no conversion needed

                debugPrint('----> conversion', conversion)

                conversionIndex = tuple(conversion)

                if conversionIndex in g.unitConversionMatrix:
                    debugPrint('unit conversion:',
                               g.unitConversionMatrix[tuple(conversion)])
                    debugPrint('exponents', exponents)

                    conversionValue = mpmathify(
                        g.unitConversionMatrix[conversionIndex])
                    conversionValue = power(conversionValue,
                                            exponents[conversionIndex])
                    debugPrint('conversion: ', conversion, conversionValue)

                    debugPrint('value before', value)
                    value = fmul(value, conversionValue)
                    debugPrint('value after', value)
                else:
                    # we're ignoring the exponents, but this works for dBm<->milliwatt, etc.
                    baseUnit = g.basicUnitTypes[getUnitType(
                        conversion[0])].baseUnit

                    conversion1 = (conversion[0], baseUnit)
                    conversion2 = (baseUnit, conversion[1])

                    debugPrint('conversion1', conversion1)
                    debugPrint('conversion2', conversion2)

                    debugPrint('value0', value)

                    if conversion1 in g.unitConversionMatrix:
                        debugPrint('standard conversion 1')
                        value = fmul(
                            value,
                            mpmathify(g.unitConversionMatrix[conversion1]))
                    else:
                        debugPrint('special conversion 1')
                        value = specialUnitConversionMatrix[conversion1](value)

                    debugPrint('value1', value)

                    if conversion2 in g.unitConversionMatrix:
                        debugPrint('standard conversion 2')
                        value = fmul(
                            value,
                            mpmathify(g.unitConversionMatrix[conversion2]))
                    else:
                        debugPrint('special conversion 2')
                        value = specialUnitConversionMatrix[conversion2](value)

                    debugPrint('value2', value)

        debugPrint('convertValue final', value)
        return value
Exemplo n.º 8
0
    def normalizeUnits(self):
        units = self.units.normalizeUnits()

        debugPrint()
        debugPrint('normalize', units)

        if units == RPNUnits():
            return self.value

        # look for units that cancel between the numerator and denominator
        numerator, denominator = units.splitUnits()

        # if we don't have a numerator or denominator, we're done
        if not numerator or not denominator:
            return RPNMeasurement(self.value, units)

        if not g.basicUnitTypes:
            loadUnitData()

        debugPrint('numerator', numerator)
        debugPrint('denominator', denominator)

        nOriginalElements = sorted(list(numerator.elements()))
        dOriginalElements = sorted(list(denominator.elements()))

        changed = False

        nElements = []

        for nUnit in numerator:
            for i in range(min(numerator[nUnit], 3)):
                nElements.append(nUnit)

        dElements = []

        for dUnit in denominator:
            for i in range(min(denominator[dUnit], 3)):
                dElements.append(dUnit)

        debugPrint('nOriginalElements', nOriginalElements)
        debugPrint('nElements', nElements)

        debugPrint('dOriginalElements', dOriginalElements)
        debugPrint('dElements', dElements)

        matchFound = True  # technically not true yet, but it gets us into the loop

        conversionsNeeded = []

        while matchFound:
            matchFound = False

            for nSubset in getPowerSet(nElements):
                for dSubset in getPowerSet(dElements):
                    #debugPrint( '))) nSubset', list( nSubset ) )
                    #debugPrint( '))) dSubset', list( dSubset ) )

                    nSubsetUnit = RPNUnits('*'.join(sorted(list(nSubset))))
                    dSubsetUnit = RPNUnits('*'.join(sorted(list(dSubset))))

                    #debugPrint( '1 nSubset', dSubsetUnit )
                    #debugPrint( '2 dSubset', dSubsetUnit )

                    if nSubsetUnit.getDimensions(
                    ) == dSubsetUnit.getDimensions():
                        debugPrint('dimensions matched',
                                   dSubsetUnit.getDimensions())
                        newNSubset = []
                        newDSubset = []

                        for nUnit in nSubset:
                            baseUnit = g.basicUnitTypes[getUnitType(
                                nUnit)].baseUnit

                            if nUnit != baseUnit:
                                debugPrint('conversion added:', nUnit,
                                           baseUnit)
                                conversionsNeeded.append((nUnit, baseUnit))

                            newNSubset.append(baseUnit)

                        for dUnit in dSubset:
                            baseUnit = g.basicUnitTypes[getUnitType(
                                dUnit)].baseUnit

                            if dUnit != baseUnit:
                                debugPrint('conversion added:', dUnit,
                                           baseUnit)
                                conversionsNeeded.append((dUnit, baseUnit))

                            newDSubset.append(baseUnit)

                        # This maybe isn't quite what we want.
                        debugPrint('conversions added',
                                   '*'.join(sorted(newNSubset)),
                                   '*'.join(sorted(newDSubset)))
                        conversionsNeeded.append(
                            ('*'.join(sorted(newNSubset)),
                             '*'.join(sorted(newDSubset))))
                        matchFound = True

                        for nUnit in nSubset:
                            #print( 'nOriginalElements', nOriginalElements, 'n', nUnit )
                            nOriginalElements.remove(nUnit)
                            changed = True

                        for dUnit in dSubset:
                            #print( 'dOriginalElements', dOriginalElements, 'd', dUnit )
                            dOriginalElements.remove(dUnit)
                            changed = True

                        break

                if matchFound:
                    break

            if matchFound:
                break

        debugPrint('final nElements', nOriginalElements)
        debugPrint('final dElements', dOriginalElements)

        # convert the value based on all the conversions we queued up
        convertedValue = self.value

        if not g.unitConversionMatrix:
            loadUnitConversionMatrix()

        for i in conversionsNeeded:
            if i in g.unitConversionMatrix:
                convertedValue = fmul(convertedValue,
                                      g.unitConversionMatrix[i])
            else:
                convertedValue = fmul(
                    convertedValue,
                    RPNMeasurement(1, i[0]).convertValue(i[1]))

        # build up the resulting units
        units = RPNUnits('*'.join(nOriginalElements))
        denominator = RPNUnits('*'.join(dOriginalElements))

        for dUnit in denominator:
            units[dUnit] += denominator[dUnit] * -1

        debugPrint('normalizeUnits final units', units)
        debugPrint()

        if units and units != RPNUnits():
            result = RPNMeasurement(convertedValue, units)

            if changed:
                return result.normalizeUnits()

            return result

        return convertedValue
Exemplo n.º 9
0
def runConvertTests():
    # pylint:disable=too-many-statements
    # unit types... make sure every unit can be converted to every other unit
    if not g.unitOperators:
        loadUnitData()

    if not g.unitConversionMatrix:
        loadUnitConversionMatrix()

    for unit in g.unitOperators:
        unitInfo = g.unitOperators[unit]

        baseUnit = g.basicUnitTypes[getUnitType(unit)].baseUnit

        if unit != baseUnit:
            if unitInfo.unitType == 'constant':
                if (unit, baseUnit) not in g.unitConversionMatrix:
                    raise ValueError(
                        '( ' + unit + ', ' + baseUnit +
                        ' ) is not found in the unit conversion matrix.')
                if (baseUnit, unit) not in g.unitConversionMatrix:
                    raise ValueError(
                        '( ' + unit + ', ' + baseUnit +
                        ' ) is not found in the unit conversion matrix.')
            else:
                testOperator(unit + ' ' + baseUnit + ' convert')

    # compound units
    testOperator('ampere coulomb/second convert')
    testOperator('candela meter sqr / lambert convert')
    testOperator('clausius joule/kelvin convert')
    testOperator('coulomb/farad volt convert')
    testOperator('coulomb/kilogram roentgen convert')
    testOperator('coulomb/volt farad convert')
    testOperator('footcandle lumen square_foot / convert')
    testOperator('footlambert candela square_meter / convert')
    testOperator('galileo meter second sqr / convert')
    testOperator('gauss maxwell centimeter sqr / convert')
    testOperator('gray joule/kilogram convert')
    testOperator('henry weber/ampere convert')
    testOperator('joule kilogram meter sqr * second sqr / convert')
    testOperator('joule pascal meter cubed * convert')
    testOperator('joule/second watt convert')
    testOperator('kine meter/second convert')
    testOperator('lux lumen meter sqr / convert')
    testOperator('mach meter/second convert')
    testOperator('maxwell gauss centimeter sqr * convert')
    testOperator('meter*newton newton meter * convert')
    testOperator('nat joule/kelvin convert')
    testOperator('newton joule/meter convert')
    testOperator('newton kilogram meter * second sqr / convert')
    testOperator('newton meter sqr / pascal convert')
    testOperator('newton second * meter sqr / pascal-second convert')
    testOperator('nit candela meter sqr / convert')
    testOperator('oc1 bit/second convert')
    testOperator('oersted ampere/meter convert')
    testOperator('ohm joule second * coulomb sqr / convert')
    testOperator(
        'ohm kilogram meter sqr * second cubed ampere sqr * / convert')
    testOperator('ohm second/farad convert')
    testOperator('ohm volt/ampere convert')
    testOperator('ohm watt ampere sqr / convert')
    testOperator('pascal kilogram meter second sqr * / convert')
    testOperator('pascal second * kilogram meter second * / convert')
    testOperator('second watt * watt-second convert')
    testOperator('siemens ampere/volt convert')
    testOperator(
        'siemens second cubed ampere sqr * kilogram meter sqr * / convert')
    testOperator('stilb candela meter sqr / convert')
    testOperator('tesla kilogram ampere second sqr * / convert')
    testOperator('tesla volt second * meter sqr / convert')
    testOperator('tesla weber meter sqr / convert')
    testOperator('watt erg/second convert')
    testOperator('watt joule/second convert')
    testOperator('watt kilogram meter sqr * second cubed / convert')
    testOperator('watt newton meter * second / convert')
    testOperator('watt second * watt-second convert')
    testOperator('watt-second second watt * convert')
    testOperator('watt-second watt second * convert')
    testOperator('weber tesla meter sqr * convert')
    testOperator('lumen candela*steradian convert')
    testOperator('candela*steradian lumen convert')

    # additional test cases
    testOperator('16800 mA hours * 5 volts * joule convert')
    testOperator('1/coulomb 1/ampere*second convert')
    testOperator('kilogram/meter*second^2 joule/meter^3 convert')
    testOperator('34000 square_miles 8 feet 9 mph * / ydhms')
    testOperator('second hertz convert')
    testOperator('day hertz convert')
    testOperator('second daily convert')
    testOperator('day daily convert')
    testOperator('30 N 100 m * kWh convert')
    testOperator('1 20 range dBm watt convert')
    testOperator('0 100 10 range2 dBm watt convert -s1')
    testOperator('60 dBm kilowatt convert')
    testOperator('barn gigaparsec * cubic_inch convert')
    testOperator('cubic_inch barn gigaparsec * convert')
    testOperator('earth_radius 2 pi * * miles convert')
    testOperator('gallon cup convert')
    testOperator('marathon miles convert')
    testOperator('marathon [ miles feet ] convert')
    testOperator('mph miles hour / convert')
    testOperator('miles hour / mph convert')
    testOperator('65 miles hour / furlongs fortnight / convert')
    testOperator('1 watt dBm convert')
    testOperator('coulomb^3/ampere^2*second^2 coulomb convert')
    testOperator('mph miles hourly * convert')
    testOperator('ohm/hertz', 'second/siemens')
    testOperator(
        'elementary_charge sqr [ 4 pi e0 electron_mass c sqr ] product / meter convert'
    )
    testOperator('coulomb^2 ampere^2*second^2 convert')
    testOperator('h eV second * convert')
    testOperator('h_bar c * MeV fm * convert')
    testOperator('h foot*pound-force*second convert')
    testOperator('400 W/m^2 stefan_boltzmann / 4 root')
    testOperator('second^2/henry farad convert')
    testOperator('farad second^2/henry convert')
    testOperator('second^2/farad henry convert')
    testOperator('henry second^2/farad convert')
    testOperator('coulomb/volt farad convert')
    testOperator('farad coulomb/volt convert')
    testOperator('ampere*second/volt farad convert')
    testOperator('farad ampere*second/volt convert')
    testOperator('farad 1/hertz*ohm convert')
    testOperator('farad joule/volt^2 convert')
    testOperator('farad meter*newton/volt^2 convert')
    testOperator('farad second*watt/volt^2 convert')
    testOperator('farad second/ohm convert')
    testOperator('1/hertz*ohm farad convert')
    testOperator('joule/volt^2 farad convert')
    testOperator('meter*newton/volt^2 farad convert')
    testOperator('second*watt/volt^2 farad convert')
    testOperator('second/ohm farad convert')
    testOperator('coulomb ampere*second convert')
    testOperator('coulomb farad*volt convert')
    testOperator('coulomb joule/volt convert')
    testOperator('ampere*second coulomb convert')
    testOperator('farad*volt coulomb convert')
    testOperator('joule/volt coulomb convert')
    testOperator('coulomb/second ampere convert')
    testOperator('ampere coulomb/second convert')
    testOperator('watt/volt ampere convert')
    testOperator('ampere watt/volt convert')
    testOperator('siemens ampere/volt convert')
    testOperator('siemens coulomb^2*second/kilogram*meter^2 convert')
    testOperator('ampere/volt siemens convert')
    testOperator('coulomb^2*second/kilogram*meter^2 siemens convert')
    testOperator('coulomb/farad volt convert')
    testOperator('joule/coulomb volt convert')
    testOperator('watt/ampere volt convert')
    testOperator('volt coulomb/farad convert')
    testOperator('volt joule/coulomb convert')
    testOperator('volt watt/ampere convert')
    testOperator('watt meter*newton/second convert')
    testOperator('meter*newton/second watt convert')
    testOperator('watt ampere*volt convert')
    testOperator('ampere*volt watt convert')
    testOperator('erg/second watt convert')
    testOperator('joule/second watt convert')
    testOperator('watt erg/second convert')
    testOperator('watt joule/second convert')
    testOperator('joule*second/coulomb^2 ohm convert')
    testOperator('joule/ampere^2*second ohm convert')
    testOperator('second/farad ohm convert')
    testOperator('volt/ampere ohm convert')
    testOperator('watt/ampere^2 ohm convert')
    testOperator('ohm joule*second/coulomb^2 convert')
    testOperator('ohm joule/ampere^2*second convert')
    testOperator('ohm second/farad convert')
    testOperator('ohm volt/ampere convert')
    testOperator('ohm watt/ampere^2 convert')
    testOperator('kilogram/meter*second pascal*second convert')
    testOperator('newton*second/meter^2 pascal*second convert')
    testOperator('pascal*second kilogram/meter*second convert')
    testOperator('pascal*second newton*second/meter^2 convert')
    testOperator('newton/meter^2 pascal convert')
    testOperator('pascal newton/meter^2 convert')
    testOperator('ampere*second*volt joule convert')
    testOperator('joule ampere*second*volt convert')
    testOperator('meter*newton joule convert')
    testOperator('meter^3*pascal joule convert')
    testOperator('joule meter*newton convert')
    testOperator('joule meter^3*pascal convert')
    testOperator('coulomb*volt joule convert')
    testOperator('second*watt joule convert')
    testOperator('joule coulomb*volt convert')
    testOperator('joule second*watt convert')
    testOperator('horsepower*second joule convert')
    testOperator('joule horsepower*second convert')
    testOperator('lux lumen/foot^2 convert')
    testOperator('lumen/foot^2 lux convert')
    testOperator('joule/ampere^2 henry convert')
    testOperator('ohm*second henry convert')
    testOperator('ohm/hertz henry convert')
    testOperator('weber/ampere henry convert')
    testOperator('henry joule/ampere^2 convert')
    testOperator('henry ohm*second convert')
    testOperator('henry ohm/hertz convert')
    testOperator('henry weber/ampere convert')
    testOperator('joule/kilogram meter^2/second^2 convert')
    testOperator('meter^2/second^2 joule/kilogram convert')
    testOperator('joule/kilogram gray convert')
    testOperator('gray joule/kilogram convert')
    testOperator('meter^2/second^2 gray convert')
    testOperator('gray meter^2/second^2 convert')
    testOperator('kilogram/second^3 watt/meter^2 convert')
    testOperator('watt/meter^2 kilogram/second^3 convert')
    testOperator('tesla kilogram/coulomb*second convert')
    testOperator('tesla joule/ampere*meter^2 convert')
    testOperator('tesla ampere*henry/meter^2 convert')
    testOperator('tesla maxwell/centimeter^2 convert')
    testOperator('tesla newton/ampere*meter convert')
    testOperator('tesla newton*second/coulomb*meter convert')
    testOperator('tesla second*volt/meter^2 convert')
    testOperator('tesla weber/meter^2 convert')
    testOperator('kilogram/coulomb*second tesla convert')
    testOperator('joule/ampere*meter^2 tesla convert')
    testOperator('ampere*henry/meter^2 tesla convert')
    testOperator('maxwell/centimeter^2 tesla convert')
    testOperator('newton/ampere*meter tesla convert')
    testOperator('newton*second/coulomb*meter tesla convert')
    testOperator('second*volt/meter^2 tesla convert')
    testOperator('weber/meter^2 tesla convert')
    testOperator('second*volt weber convert')
    testOperator('meter^2*tesla weber convert')
    testOperator('centimeter^2*gauss weber convert')
    testOperator('weber second*volt convert')
    testOperator('weber meter^2*tesla convert')
    testOperator('weber centimeter^2*gauss convert')
    testOperator('newton ampere*weber/meter convert')
    testOperator('newton joule/meter convert')
    testOperator('ampere*weber/meter newton convert')
    testOperator('joule/meter newton convert')
    testOperator('poise pascal*second convert')
    testOperator('pascal*second poise convert')

    # let's check some answers
    expectEqual('1/hertz', '1 second')
    expectEqual('1 1 hertz /', '1 second')
    expectEqual('1/ohm siemens convert', '1 siemens')
    expectEqual('1/second hertz convert', '1 hertz')
    expectEqual('1/siemens ohm convert', '1 ohm')
    expectEqual('12 inches foot convert', '1 foot')
    expectEqual('1 foot inches convert', '12 inches')
    expectEqual('newton*day kilonewton*second convert',
                '86.4 kilonewton*second')
    expectEqual('3 cups/second gallons/minute convert', '11.25 gallon/minute')
    expectEqual('coulomb/ampere*second', '1')
    expectEqual('16800 mA hours * 5 volts * joule convert', '302400 joules')
    expectEqual('2 ampere 100 ohms * volts convert', '200 volts')
    expectEqual('120 volt 100 ohm / ampere convert', '1.2 amperes')
    expectEqual('day second convert', '86400 seconds')
    expectEqual('120 coulombs 10 ampere / second convert', '12 seconds')
    expectEqual('1 kilowatt 1 decavolt / ampere convert', '100 amperes')
    expectEqual('1 watt 1 ohm / ampere sqr convert', '1 ampere^2')
    expectEqual('50 watts 5 amperes^2 / ohm convert', '10 ohms')
    expectEqual('120 volts^2 50 watts / ohms convert', '2.4 ohms')
    expectEqual('200 ohms 4 watts * volts^2 convert', '800 volts^2')
    expectEqual('1 kilowatt 10 ohms / sqrt', '10 amperes')
    expectEqual('volt meter / newton coulomb / convert', '1 newton coulomb /')
    expectEqual('Wb Hz/V convert', '1 Hz/V')
    expectEqual('decameter meters convert', '10 meters')
    expectEqual('hectare ares convert', '100 ares')
    expectEqual('kilogram gram convert', '1000 grams')
    expectEqual('1 volt millivolt convert', '1000 millivolts')
    expectEqual('1 petabyte bit convert', '8e15 bits')
    expectEqual('mile^2 acre convert', '640 acres')
    expectEqual('gallon cubic_inches convert', '231 cubic_inches')

    expectEqual('newton meter *', 'joule')
    expectEqual('newton*meter', 'joule')
    expectEqual('meter*newton', 'joule')
    expectEqual('coulomb^2 ampere^2*second^2 convert', 'ampere^2*second^2')
    expectEqual('ampere^2*second^2 coulomb^2 convert', 'coulomb^2')
    expectEqual('volt ampere /', 'ohm')
    expectEqual('1/siemens ohm convert', 'ohm')
    expectEqual('1 1 siemens /', 'ohm')
    expectEqual('watt ampere^2 /', 'ohm')
    expectEqual('volt^2 watt /', 'ohm')
    expectEqual('second farad /', 'ohm')
    expectEqual('henry second /', 'ohm')
    expectEqual('joule second * coulomb^2 /', 'ohm')
    expectEqual('kilogram meter sqr * second coulomb sqr * /', 'ohm')
    expectEqual('kilogram*meter^2/second*coulomb^2', 'ohm')
    expectEqual('kg*m^2/s*C^2', 'ohm')
    expectEqual('joule second ampere sqr * /', 'ohm')
    expectEqual('kilogram meter meter * * second 3 ** ampere 2 ** * /', 'ohm')
    expectEqual('ampere ohm *', 'volt')
    expectEqual('weber second /', 'volt')
    expectEqual('watt ampere /', 'volt')
    expectEqual('joule coulomb /', 'volt')
    expectEqual('electron-volt joule convert electron_charge /', 'volt')
    expectEqual('coulomb second /', 'ampere')
    expectEqual('ampere second *', 'coulomb')
    expectEqual('farad volt *', 'coulomb')
    expectEqual('coulomb volt /', 'farad')
    expectEqual('ampere second * volt /', 'farad')
    expectEqual('joule volt 2 ** /', 'farad')
    expectEqual('watt second * volt volt * /', 'farad')
    expectEqual('newton meter * volt^2 /', 'farad')
    expectEqual('coulomb^2 joule /', 'farad')
    expectEqual('coulomb^2 newton meter * /', 'farad')
    expectEqual('second^2*coulomb^2/meter^2*kilogram', 'farad')
    expectEqual('second^4*ampere^2/meter^2*kilogram', 'farad')
    expectEqual('second ohm /', 'farad')
    expectEqual('1 1 ohm hertz * /', 'farad')
    expectEqual('second^2/henry', 'farad')
    expectEqual('kilogram*meter^2/second^2*ampere^2 henry convert', 'henry')
    expectEqual('kilogram*meter^2/coulomb^2', 'henry')
    expectEqual('joule ampere sqr /', 'henry')
    expectEqual('tesla meter sqr * ampere /', 'henry')
    expectEqual('weber ampere /', 'henry')
    expectEqual('volt second * ampere /', 'henry')
    expectEqual('second^2/farad', 'henry')
    expectEqual('ohm hertz /', 'henry')
    expectEqual('ohm second *', 'henry')
    expectEqual('volt second * meter^2 /', 'tesla')
    expectEqual('newton ampere meter * /', 'tesla')
    expectEqual('joule ampere meter^2 * / ', 'tesla')
    expectEqual('henry ampere * meter^2 /', 'tesla')
    expectEqual('weber meter^2 /', 'tesla')
    expectEqual('kilogram coulomb second * /', 'tesla')
    expectEqual('newton second * coulomb meter * /', 'tesla')
    expectEqual('kilogram ampere second^2 * /', 'tesla')
    expectEqual('ohm coulomb *', 'weber')
    expectEqual('volt second *', 'weber')
    expectEqual('henry ampere *', 'weber')
    expectEqual('tesla meter^2 *', 'weber')
    expectEqual('joule ampere /', 'weber')
    expectEqual('kg*m^2/second^2', 'joule')
    expectEqual('newton meter *', 'joule')
    expectEqual('pascal meter^3 *', 'joule')
    expectEqual('watt second *', 'joule')
    expectEqual('coulomb volt *', 'joule')

    # unit exponentiation
    testOperator('8 floz inch 3 ** convert')
    testOperator('foot 4 power square_inch sqr convert')

    # lists of units
    testOperator(
        '0 5000 284 range2 seconds [ hour minute second ] convert -s1')

    # let's try to break it
    expectException('cup foot convert')
    expectException('foot-lambert candela square_meter / convert')
    expectException('75 kg G * 1 m/s * watt convert')
Exemplo n.º 10
0
    def convertValue( self, other ):
        if not isinstance( other, ( RPNUnits, RPNMeasurement, str, list ) ):
            raise ValueError( 'convertValue must be called with an RPNUnits object, an RPNMeasurement object, a string or a list of RPNMeasurement' )

        if isinstance( other, ( str, RPNUnits ) ):
            other = RPNMeasurement( 1, other )

        if not self.isCompatible( other ):
            # We can try to convert incompatible units.
            return self.convertIncompatibleUnit( other )

        if not g.unitConversionMatrix:
            loadUnitConversionMatrix( )

        # handle list conversions like [ year, day, minute, hour ]
        if isinstance( other, list ):
            # a list of length one is treated the same as a single measurement
            if len( other ) == 1:
                return convertValue( other[ 0 ] )
            else:
                listToConvert = [ ]

                for i in other:
                    if isinstance( i, str ):
                        listToConvert.append( RPNMeasurement( 1, i ) )
                    elif isinstance( i, RPNMeasurement ):
                        listToConvert.append( i )
                    else:
                        raise ValueError( 'we\'ve got something else' )

                return self.convertUnitList( listToConvert )

        conversions = [ ]

        value = self.value    # This is what we'll return down below

        # let's look for straightforward conversions
        units1 = self.units
        units2 = other.units

        unit1String = units1.getUnitString( )
        unit2String = units2.getUnitString( )

        if unit1String == unit2String:
            return value

        exponents = { }

        # look for a straight-up conversion
        if ( unit1String, unit2String ) in g.unitConversionMatrix:
            value = fmul( value, mpmathify( g.unitConversionMatrix[ ( unit1String, unit2String ) ] ) )
        elif ( unit1String, unit2String ) in specialUnitConversionMatrix:
            value = specialUnitConversionMatrix[ ( unit1String, unit2String ) ]( value )
        else:
            # TODO:  Should we just convert to base units regardless?  It would be safer...
            if other.doDimensionsCancel( ):
                other = other.convertToBaseUnits( )
                units2 = other.units
                value = fdiv( value, other.value )

            # otherwise, we need to figure out how to do the conversion
            conversionValue = value

            # if that isn't found, then we need to do the hard work and break the units down
            newUnits1 = RPNUnits( units1 )
            newUnits2 = RPNUnits( units2 )

            debugPrint( 'newUnits1:', newUnits1 )
            debugPrint( 'newUnits2:', newUnits2 )

            debugPrint( )
            debugPrint( 'iterating through units to match for conversion:' )

            for unit1 in newUnits1:
                foundConversion = False

                for unit2 in newUnits2:
                    debugPrint( 'units 1:', unit1, newUnits1[ unit1 ], getUnitType( unit1 ) )
                    debugPrint( 'units 2:', unit2, newUnits2[ unit2 ], getUnitType( unit2 ) )

                    if getUnitType( unit1 ) == getUnitType( unit2 ):
                        debugPrint( 'found a conversion:', unit1, unit2 )
                        conversions.append( ( unit1, unit2 ) )
                        exponents[ ( unit1, unit2 ) ] = units1[ unit1 ]
                        foundConversion = True
                        break

                skip = False

                if not foundConversion:
                    debugPrint( )
                    debugPrint( 'didn\'t find a conversion, try reducing' )
                    debugPrint( )
                    reduced = self.convertToBaseUnits( )

                    debugPrint( 'reduced:', self.units, 'becomes', reduced.units )

                    reducedOther = other.convertToBaseUnits( )

                    reduced.value = fdiv( reduced.value, reducedOther.value )

                    debugPrint( 'reduced other:', other.units, 'becomes', reducedOther.units )

                    # check to see if reducing did anything and bail if it didn't... bail out
                    if ( reduced.units == self.units ) and ( reducedOther.units == other.units ):
                        debugPrint( 'reducing didn\'t help' )
                        break

                    return reduced.convertValue( reducedOther )

            debugPrint( )

            value = conversionValue

            debugPrint( 'Iterating through conversions...' )

            for conversion in conversions:
                if conversion[ 0 ] == conversion[ 1 ]:
                    continue  # no conversion needed

                debugPrint( '----> conversion', conversion )

                conversionIndex = tuple( conversion )

                if conversionIndex in g.unitConversionMatrix:
                    debugPrint( 'unit conversion:', g.unitConversionMatrix[ tuple( conversion ) ] )
                    debugPrint( 'exponents', exponents )

                    conversionValue = mpmathify( g.unitConversionMatrix[ conversionIndex ] )
                    conversionValue = power( conversionValue, exponents[ conversionIndex ] )
                    debugPrint( 'conversion: ', conversion, conversionValue )

                    debugPrint( 'value before', value )
                    value = fmul( value, conversionValue )
                    debugPrint( 'value after', value )
                else:
                    # we're ignoring the exponents, but this works for dBm<->milliwatt, etc.
                    baseUnit = g.basicUnitTypes[ getUnitType( conversion[ 0 ] ) ].baseUnit

                    conversion1 = ( conversion[ 0 ], baseUnit )
                    conversion2 = ( baseUnit, conversion[ 1 ] )

                    debugPrint( 'conversion1', conversion1 )
                    debugPrint( 'conversion2', conversion2 )

                    debugPrint( 'value0', value )

                    if conversion1 in g.unitConversionMatrix:
                        debugPrint( 'standard conversion 1' )
                        value = fmul( value, mpmathify( g.unitConversionMatrix[ conversion1 ] ) )
                    else:
                        debugPrint( 'special conversion 1' )
                        value = specialUnitConversionMatrix[ conversion1 ]( value )

                    debugPrint( 'value1', value )

                    if conversion2 in g.unitConversionMatrix:
                        debugPrint( 'standard conversion 2' )
                        value = fmul( value, mpmathify( g.unitConversionMatrix[ conversion2 ] ) )
                    else:
                        debugPrint( 'special conversion 2' )
                        value = specialUnitConversionMatrix[ conversion2 ]( value )

                    debugPrint( 'value2', value )

        debugPrint( 'convertValue final', value )
        return value
Exemplo n.º 11
0
    def normalizeUnits( self ):
        units = self.units.normalizeUnits( )

        debugPrint( )
        debugPrint( 'normalize', units )

        # look for units that cancel between the numerator and denominator
        numerator, denominator = units.splitUnits( )

        # if we don't have a numerator or denominator, we're done
        if not numerator or not denominator:
            return RPNMeasurement( self.value, units )

        if not g.basicUnitTypes:
            loadUnitData( )

        debugPrint( 'numerator', numerator )
        debugPrint( 'denominator', denominator )

        nOriginalElements = sorted( list( numerator.elements( ) ) )
        dOriginalElements = sorted( list( denominator.elements( ) ) )

        changed = False

        nElements = [ ]

        for n in numerator:
            for i in range( min( numerator[ n ], 3 ) ):
                nElements.append( n )

        dElements = [ ]

        for d in denominator:
            for i in range( min( denominator[ d ], 3 ) ):
                dElements.append( d )

        debugPrint( 'nOriginalElements', nOriginalElements )
        debugPrint( 'nElements', nElements )

        debugPrint( 'dOriginalElements', dOriginalElements )
        debugPrint( 'dElements', dElements )

        matchFound = True   # technically not true yet, but it gets us into the loop

        conversionsNeeded = [ ]

        while matchFound:
            matchFound = False

            for nSubset in getPowerset( nElements ):
                for dSubset in getPowerset( dElements ):
                    #debugPrint( '))) nSubset', list( nSubset ) )
                    #debugPrint( '))) dSubset', list( dSubset ) )

                    nSubsetUnit = RPNUnits( '*'.join( sorted( list( nSubset ) ) ) )
                    dSubsetUnit = RPNUnits( '*'.join( sorted( list( dSubset ) ) ) )

                    #debugPrint( '1 nSubset', dSubsetUnit )
                    #debugPrint( '2 dSubset', dSubsetUnit )

                    if nSubsetUnit.getDimensions( ) == dSubsetUnit.getDimensions( ):
                        debugPrint( 'dimensions matched', dSubsetUnit.getDimensions( ) )
                        newNSubset = [ ]
                        newDSubset = [ ]

                        for n in nSubset:
                            baseUnit = g.basicUnitTypes[ getUnitType( n ) ].baseUnit

                            if n != baseUnit:
                                debugPrint( 'conversion added:', n, baseUnit )
                                conversionsNeeded.append( ( n, baseUnit ) )

                            newNSubset.append( baseUnit )

                        for d in dSubset:
                            baseUnit = g.basicUnitTypes[ getUnitType( d ) ].baseUnit

                            if d != baseUnit:
                                debugPrint( 'conversion added:', d, baseUnit )
                                conversionsNeeded.append( ( d, baseUnit ) )

                            newDSubset.append( baseUnit )

                        # TODO:  This maybe isn't quite what we want.
                        debugPrint( 'conversions added', '*'.join( sorted( newNSubset ) ),
                                                         '*'.join( sorted( newDSubset ) ) )
                        conversionsNeeded.append( ( '*'.join( sorted( newNSubset ) ),
                                                    '*'.join( sorted( newDSubset ) ) ) )
                        matchFound = True

                        for n in nSubset:
                            #print( 'nOriginalElements', nOriginalElements, 'n', n )
                            nOriginalElements.remove( n )
                            changed = True

                        for d in dSubset:
                            #print( 'dOriginalElements', dOriginalElements, 'd', d )
                            dOriginalElements.remove( d )
                            changed = True

                        break

                if matchFound:
                    break

            if matchFound:
                break

        debugPrint( 'final nElements', nOriginalElements )
        debugPrint( 'final dElements', dOriginalElements )

        # convert the value based on all the conversions we queued up
        convertedValue = self.value

        if not g.unitConversionMatrix:
            loadUnitConversionMatrix( )

        for i in conversionsNeeded:
            if i in g.unitConversionMatrix:
                convertedValue = fmul( convertedValue, g.unitConversionMatrix[ i ] )
            else:
                convertedValue = fmul( convertedValue, RPNMeasurement( 1, i[ 0 ] ).convertValue( i[ 1 ] ) )

        # build up the resulting units
        units = RPNUnits( '*'.join( nOriginalElements ) )
        denominator = RPNUnits( '*'.join( dOriginalElements ) )

        for d in denominator:
            units[ d ] += denominator[ d ] * -1

        debugPrint( 'normalizeUnits final units', units )
        debugPrint( )

        if units:
            result = RPNMeasurement( convertedValue, units )

            if changed:
                return result.normalizeUnits( )
            else:
                return result
        else:
            return convertedValue
Exemplo n.º 12
0
def runConvertTests( ):
    # unit types... make sure every unit can be converted to every other unit
    if not g.unitOperators:
        loadUnitData( )

    if not g.unitConversionMatrix:
        loadUnitConversionMatrix( )

    for unit in g.unitOperators:
        unitInfo = g.unitOperators[ unit ]

        baseUnit = g.basicUnitTypes[ getUnitType( unit ) ].baseUnit

        if unit != baseUnit:
            if unitInfo.unitType == 'constant':
                if ( unit, baseUnit ) not in g.unitConversionMatrix:
                    raise ValueError( '( ' + unit + ', ' + baseUnit + ' ) is not found in the unit conversion matrix.' )
                if ( baseUnit, unit ) not in g.unitConversionMatrix:
                    raise ValueError( '( ' + unit + ', ' + baseUnit + ' ) is not found in the unit conversion matrix.' )
            else:
                testOperator( unit + ' ' + baseUnit + ' convert' )

    # compound units
    testOperator( 'ampere coulomb/second convert' )
    testOperator( 'btupf joule/kelvin convert' )
    testOperator( 'candela meter sqr / lambert convert' )
    testOperator( 'clausius joule/kelvin convert' )
    testOperator( 'coulomb/farad volt convert' )
    testOperator( 'coulomb/kilogram roentgen convert' )
    testOperator( 'coulomb/volt farad convert' )
    testOperator( 'footcandle lumen square_foot / convert' )
    testOperator( 'footlambert candela square_meter / convert' )
    testOperator( 'galileo meter second sqr / convert' )
    testOperator( 'gauss maxwell centimeter sqr / convert' )
    testOperator( 'gray joule/kilogram convert' )
    testOperator( 'henry weber/ampere convert' )
    testOperator( 'joule kilogram meter sqr * second sqr / convert' )
    testOperator( 'joule pascal meter cubed * convert' )
    testOperator( 'joule/second watt convert' )
    testOperator( 'kine meter/second convert' )
    testOperator( 'lux lumen meter sqr / convert' )
    testOperator( 'mach meter/second convert' )
    testOperator( 'maxwell gauss centimeter sqr * convert' )
    testOperator( 'meter*newton newton meter * convert' )
    testOperator( 'nat joule/kelvin convert' )
    testOperator( 'newton joule/meter convert' )
    testOperator( 'newton kilogram meter * second sqr / convert' )
    testOperator( 'newton meter sqr / pascal convert' )
    testOperator( 'newton second * meter sqr / pascal-second convert' )
    testOperator( 'nit candela meter sqr / convert' )
    testOperator( 'oc1 bit/second convert' )
    testOperator( 'oersted ampere/meter convert' )
    testOperator( 'ohm joule second * coulomb sqr / convert' )
    testOperator( 'ohm kilogram meter sqr * second cubed ampere sqr * / convert' )
    testOperator( 'ohm second/farad convert' )
    testOperator( 'ohm volt/ampere convert' )
    testOperator( 'ohm watt ampere sqr / convert' )
    testOperator( 'pascal kilogram meter second sqr * / convert' )
    testOperator( 'pascal second * kilogram meter second * / convert' )
    testOperator( 'second watt * watt-second convert' )
    testOperator( 'siemens ampere/volt convert' )
    testOperator( 'siemens second cubed ampere sqr * kilogram meter sqr * / convert' )
    testOperator( 'stilb candela meter sqr / convert' )
    testOperator( 'tesla kilogram ampere second sqr * / convert' )
    testOperator( 'tesla volt second * meter sqr / convert' )
    testOperator( 'tesla weber meter sqr / convert' )
    testOperator( 'watt erg/second convert' )
    testOperator( 'watt joule/second convert' )
    testOperator( 'watt kilogram meter sqr * second cubed / convert' )
    testOperator( 'watt newton meter * second / convert' )
    testOperator( 'watt second * watt-second convert' )
    testOperator( 'watt-second second watt * convert' )
    testOperator( 'watt-second watt second * convert' )
    testOperator( 'weber tesla meter sqr * convert' )
    testOperator( 'lumen candela*steradian' )
    testOperator( 'candela*steradian lumen' )

    # additional test cases
    testOperator( '16800 mA hours * 5 volts * joule convert' )
    testOperator( '1/coulomb 1/ampere*second convert' )
    testOperator( 'kilogram/meter*second^2 joule/meter^3 convert' )
    testOperator( '34000 square_miles 8 feet 9 mph * / ydhms' )
    testOperator( 'second hertz convert' )
    testOperator( 'day hertz convert' )
    testOperator( 'second daily convert' )
    testOperator( 'day daily convert' )
    testOperator( '30 N 100 m * kWh convert' )
    testOperator( '1 20 range dBm watt convert' )
    testOperator( '0 100 10 range2 dBm watt convert -s1' )
    testOperator( '60 dBm kilowatt convert' )
    testOperator( 'barn gigaparsec * cubic_inch convert' )
    testOperator( 'cubic_inch barn gigaparsec * convert' )
    testOperator( 'earth_radius 2 pi * * miles convert' )
    testOperator( 'gallon cup convert' )
    testOperator( 'marathon miles convert' )
    testOperator( 'marathon [ miles feet ] convert' )
    testOperator( 'mph miles hour / convert' )
    testOperator( 'miles hour / mph convert' )
    testOperator( '65 miles hour / furlongs fortnight / convert' )
    testOperator( '1 watt dBm convert' )
    testOperator( 'coulomb^3/ampere^2*second^2 coulomb convert' )
    testOperator( 'mph miles hourly * convert' )
    testOperator( 'ohm/hertz', 'second/siemens' )
    testOperator( 'elementary_charge sqr [ 4 pi e0 electron_mass c sqr ] product / meter convert' )
    testOperator( 'coulomb^2 ampere^2*second^2 convert' )
    testOperator( 'h eV second * convert' )
    testOperator( 'h_bar c * MeV fm * convert' )
    testOperator( 'h foot*pound-force*second convert' )
    testOperator( '400 W/m^2 stefan_boltzmann / 4 root' )
    testOperator( 'second^2/henry farad convert' )
    testOperator( 'farad second^2/henry convert' )
    testOperator( 'second^2/farad henry convert' )
    testOperator( 'henry second^2/farad convert' )
    testOperator( 'coulomb/volt farad convert' )
    testOperator( 'farad coulomb/volt convert' )
    testOperator( 'ampere*second/volt farad convert' )
    testOperator( 'farad ampere*second/volt convert' )
    testOperator( 'farad 1/hertz*ohm convert' )
    testOperator( 'farad joule/volt^2 convert' )
    testOperator( 'farad meter*newton/volt^2 convert' )
    testOperator( 'farad second*watt/volt^2 convert' )
    testOperator( 'farad second/ohm convert' )
    testOperator( '1/hertz*ohm farad convert' )
    testOperator( 'joule/volt^2 farad convert' )
    testOperator( 'meter*newton/volt^2 farad convert' )
    testOperator( 'second*watt/volt^2 farad convert' )
    testOperator( 'second/ohm farad convert' )
    testOperator( 'coulomb ampere*second convert' )
    testOperator( 'coulomb farad*volt convert' )
    testOperator( 'coulomb joule/volt convert' )
    testOperator( 'ampere*second coulomb convert' )
    testOperator( 'farad*volt coulomb convert' )
    testOperator( 'joule/volt coulomb convert' )
    testOperator( 'coulomb/second ampere convert' )
    testOperator( 'ampere coulomb/second convert' )
    testOperator( 'watt/volt ampere convert' )
    testOperator( 'ampere watt/volt convert' )
    testOperator( 'siemens ampere/volt convert' )
    testOperator( 'siemens coulomb^2*second/kilogram*meter^2 convert' )
    testOperator( 'ampere/volt siemens convert' )
    testOperator( 'coulomb^2*second/kilogram*meter^2 siemens convert' )
    testOperator( 'coulomb/farad volt convert' )
    testOperator( 'joule/coulomb volt convert' )
    testOperator( 'watt/ampere volt convert' )
    testOperator( 'volt coulomb/farad convert' )
    testOperator( 'volt joule/coulomb convert' )
    testOperator( 'volt watt/ampere convert' )
    testOperator( 'watt meter*newton/second convert' )
    testOperator( 'meter*newton/second watt convert' )
    testOperator( 'watt ampere*volt convert' )
    testOperator( 'ampere*volt watt convert' )
    testOperator( 'erg/second watt convert' )
    testOperator( 'joule/second watt convert' )
    testOperator( 'watt erg/second convert' )
    testOperator( 'watt joule/second convert' )
    testOperator( 'joule*second/coulomb^2 ohm convert' )
    testOperator( 'joule/ampere^2*second ohm convert' )
    testOperator( 'second/farad ohm convert' )
    testOperator( 'volt/ampere ohm convert' )
    testOperator( 'watt/ampere^2 ohm convert' )
    testOperator( 'ohm joule*second/coulomb^2 convert' )
    testOperator( 'ohm joule/ampere^2*second convert' )
    testOperator( 'ohm second/farad convert' )
    testOperator( 'ohm volt/ampere convert' )
    testOperator( 'ohm watt/ampere^2 convert' )
    testOperator( 'kilogram/meter*second pascal*second convert' )
    testOperator( 'newton*second/meter^2 pascal*second convert' )
    testOperator( 'pascal*second kilogram/meter*second convert' )
    testOperator( 'pascal*second newton*second/meter^2 convert' )
    testOperator( 'newton/meter^2 pascal convert' )
    testOperator( 'pascal newton/meter^2 convert' )
    testOperator( 'ampere*second*volt joule convert' )
    testOperator( 'joule ampere*second*volt convert' )
    testOperator( 'meter*newton joule convert' )
    testOperator( 'meter^3*pascal joule convert' )
    testOperator( 'joule meter*newton convert' )
    testOperator( 'joule meter^3*pascal convert' )
    testOperator( 'coulomb*volt joule convert' )
    testOperator( 'second*watt joule convert' )
    testOperator( 'joule coulomb*volt convert' )
    testOperator( 'joule second*watt convert' )
    testOperator( 'horsepower*second joule convert' )
    testOperator( 'joule horsepower*second convert' )
    testOperator( 'lux lumen/foot^2 convert' )
    testOperator( 'lumen/foot^2 lux convert' )
    testOperator( 'joule/ampere^2 henry convert' )
    testOperator( 'ohm*second henry convert' )
    testOperator( 'ohm/hertz henry convert' )
    testOperator( 'weber/ampere henry convert' )
    testOperator( 'henry joule/ampere^2 convert' )
    testOperator( 'henry ohm*second convert' )
    testOperator( 'henry ohm/hertz convert' )
    testOperator( 'henry weber/ampere convert' )
    testOperator( 'joule/kilogram meter^2/second^2 convert' )
    testOperator( 'meter^2/second^2 joule/kilogram convert' )
    testOperator( 'joule/kilogram gray convert' )
    testOperator( 'gray joule/kilogram convert' )
    testOperator( 'meter^2/second^2 gray convert' )
    testOperator( 'gray meter^2/second^2 convert' )
    testOperator( 'kilogram/second^3 watt/meter^2' )
    testOperator( 'watt/meter^2 kilogram/second^3' )
    testOperator( 'tesla kilogram/coulomb*second convert' )
    testOperator( 'tesla joule/ampere*meter^2 convert' )
    testOperator( 'tesla ampere*henry/meter^2 convert' )
    testOperator( 'tesla maxwell/centimeter^2 convert' )
    testOperator( 'tesla newton/ampere*meter convert' )
    testOperator( 'tesla newton*second/coulomb*meter convert' )
    testOperator( 'tesla second*volt/meter^2 convert' )
    testOperator( 'tesla weber/meter^2 convert' )
    testOperator( 'kilogram/coulomb*second tesla convert' )
    testOperator( 'joule/ampere*meter^2 tesla convert' )
    testOperator( 'ampere*henry/meter^2 tesla convert' )
    testOperator( 'maxwell/centimeter^2 tesla convert' )
    testOperator( 'newton/ampere*meter tesla convert' )
    testOperator( 'newton*second/coulomb*meter tesla convert' )
    testOperator( 'second*volt/meter^2 tesla convert' )
    testOperator( 'weber/meter^2 tesla convert' )
    testOperator( 'second*volt weber convert' )
    testOperator( 'meter^2*tesla weber convert' )
    testOperator( 'centimeter^2*gauss weber convert' )
    testOperator( 'weber second*volt convert' )
    testOperator( 'weber meter^2*tesla convert' )
    testOperator( 'weber centimeter^2*gauss convert' )
    testOperator( 'newton ampere*weber/meter convert' )
    testOperator( 'newton joule/meter convert' )
    testOperator( 'ampere*weber/meter newton convert' )
    testOperator( 'joule/meter newton convert' )
    testOperator( 'poise pascal*second convert' )
    testOperator( 'pascal*second poise convert' )


    # let's check some answers
    expectEqual( '1/hertz second convert', '1 second' )
    expectEqual( '1/second hertz convert', '1 hertz' )
    expectEqual( '1/ohm siemens convert', '1 siemens' )
    expectEqual( '1/siemens ohm convert', '1 ohm' )
    expectEqual( '12 inches foot convert', '1 foot' )
    expectEqual( '1 foot inches convert', '12 inches' )
    expectEqual( 'newton*day kilonewton*second convert', '86.4 kilonewton*second' )
    expectEqual( '3 cups/second gallons/minute convert', '11.25 gallon/minute' )
    expectEqual( 'coulomb/ampere*second', '1' )
    expectEqual( '16800 mA hours * 5 volts * joule convert', '302400 joules' )
    expectEqual( '2 ampere 100 ohms * volts convert', '200 volts' )
    expectEqual( '120 volt 100 ohm / ampere convert', '1.2 amperes' )
    expectEqual( 'day second convert', '86400 seconds' )
    expectEqual( '120 coulombs 10 ampere / second convert', '12 seconds' )
    expectEqual( '1 kilowatt 1 decavolt / ampere convert', '100 amperes' )
    expectEqual( '1 watt 1 ohm / ampere sqr convert', '1 ampere^2' )
    expectEqual( '50 watts 5 amperes^2 / ohm convert', '10 ohms' )
    expectEqual( '120 volts^2 50 watts / ohms convert', '2.4 ohms' )
    expectEqual( '200 ohms 4 watts * volts^2 convert', '800 volts^2' )
    expectEqual( '1 kilowatt 10 ohms / sqrt', '10 amperes' )
    expectEqual( 'volt meter / newton coulomb / convert', '1 newton coulomb /' )
    expectEqual( 'Wb Hz/V convert', '1 Hz/V' )
    expectEqual( 'decameter meters convert', '10 meters' )
    expectEqual( 'hectare ares convert', '100 ares' )
    expectEqual( 'kilogram gram convert', '1000 grams' )
    expectEqual( '1 volt millivolt convert', '1000 millivolts' )
    expectEqual( '1 petabyte bit convert', '8e15 bits' )
    expectEqual( 'mile^2 acre convert', '640 acres' )
    expectEqual( 'gallon cubic_inches convert', '231 cubic_inches' )

    # unit exponentiation
    testOperator( '8 floz inch 3 ** convert' )
    testOperator( 'foot 4 power square_inch sqr convert' )

    # lists of units
    testOperator( '0 5000 284 range2 seconds [ hour minute second ] convert -s1' )