You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

66 lines
2.3 KiB

import pint
class ConverterError(Exception):
pass
class Converter(object):
def __init__(self):
self.ureg = pint.UnitRegistry(autoconvert_offset_to_baseunit=True)
self.ureg.define('degreeC = kelvin; offset: 273.15 = °C = C')
self.ureg.define('degreeF = 5 / 9 * kelvin; offset: 255.372222 = °F = F')
self.default_units = {
self.ureg.degC: self.ureg.degreeF,
self.ureg.degreeC: self.ureg.degreeF,
self.ureg.degF: self.ureg.degreeC,
self.ureg.degreeF: self.ureg.degreeC,
self.ureg.kilometer: self.ureg.mile,
self.ureg.meter: self.ureg.foot,
self.ureg.centimeter: self.ureg.inch,
self.ureg.millimeter: self.ureg.inch,
self.ureg.mile: self.ureg.kilometer,
self.ureg.foot: self.ureg.meter,
self.ureg.inch: self.ureg.millimeter,
self.ureg.kilogram: self.ureg.pound,
self.ureg.pound: self.ureg.kilogram,
self.ureg.ounce: self.ureg.kilogram,
self.ureg.liter: self.ureg.gallon,
self.ureg.milliliter: self.ureg.floz,
self.ureg.gallon: self.ureg.liter,
self.ureg.floz: self.ureg.milliliter,
}
def convert(self, expression, unit=None):
try:
q = self.ureg.parse_expression(expression)
except pint.errors.UndefinedUnitError:
raise ConverterError('unknown units')
try:
q.units
except AttributeError:
if unit is not None:
q = self.ureg.parse_expression(expression + unit)
unit = None
else:
raise ConverterError('unknown units')
try:
q.units
except AttributeError:
raise ConverterError('unknown units')
if unit is not None:
try:
u = self.ureg.parse_units(unit)
except pint.errors.UndefinedUnitError:
raise ConverterError('unknown units')
else:
try:
u = self.default_units[q.units]
except KeyError:
raise ConverterError('no target units specified')
try:
result = q.to(u)
except pint.errors.DimensionalityError:
raise ConverterError('invalid conversion')
return '{:0.5g~P}'.format(result)