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 )
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
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)
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
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
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
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
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
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')
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
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
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' )