/
convert.py
78 lines (59 loc) · 2.34 KB
/
convert.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
import logging
LOG = logging.getLogger(__name__)
# special cases to try, like when a user asks to convert 25 pints to oz
SPECIAL = {
'ounce': 'floz',
'boltzmann_constant': 'km'
}
class Converter(object):
def __init__(self, definitions=None, separator='>', precision=None):
from pint import UnitRegistry
self.ureg = UnitRegistry()
self.ureg.load_definitions('unit_defs.txt')
self.load_definitions(definitions)
self.separator = separator
self.precision = precision
def load_definitions(self, definitions):
if not definitions:
return
if not isinstance(definitions, (list, tuple)):
definitions = [definitions]
for d in definitions:
LOG.info('loading definitions from %s', d)
self.ureg.load_definitions(d)
def convert(self, query):
from pint.unit import DimensionalityError
import re
Q_ = self.ureg.Quantity
# step 1: split the query into an input value and output units at a
# self.separator
value, sep, units = query.partition(self.separator)
value = re.sub(r'([A-Za-z]) ([A-Za-z])', r'\1_\2', value.strip())
units = re.sub(r'(\w) (\w)', r'\1_\2', units.strip())
LOG.debug('query: %s', query)
LOG.debug('input: %s', value)
LOG.debug('units: %s', units)
in_val = Q_(value)
out_units = Q_(units.replace(' ', '_'))
try:
out_val = in_val.to(out_units)
except DimensionalityError, e:
if str(e.units1) in SPECIAL:
in_val2 = in_val.magnitude * Q_(SPECIAL[str(e.units1)])
out_val = in_val2.to(out_units)
elif str(e.units2) in SPECIAL:
out_units2 = Q_(SPECIAL[str(e.units2)])
out_val = in_val.to(out_units2)
else:
raise
LOG.debug(u'converted {0} to {1:P}'.format(in_val, out_val))
magnitude = out_val.magnitude
units = out_val.units
if self.precision:
from decimal import Decimal
rval = Decimal('1.' + '0'*self.precision)
magnitude = Decimal(out_val.magnitude).quantize(rval)
return (magnitude, u'{0} {1}'.format(magnitude, units))
if __name__ == '__main__':
from sys import argv
print Converter().convert(argv[1])