Revision 1471
Added by Aaron Marcuse-Kubitza over 12 years ago
units.py | ||
---|---|---|
16 | 16 |
else: return strings.remove_suffix('.', units) # for abbr ending in '.' |
17 | 17 |
# TODO: deal with '"° and abbrs |
18 | 18 |
|
19 |
def parse_units(value): |
|
20 |
'''@return tuple (number float, units str|None)''' |
|
21 |
number = value |
|
19 |
class Quantity: |
|
20 |
def __init__(self, value='', units=None): |
|
21 |
self.value = value |
|
22 |
self.units = std_units(util.none_if(units, u'')) |
|
23 |
|
|
24 |
def quantity2str(quantity): |
|
25 |
str_ = quantity.value |
|
26 |
if quantity.units != None: str_ += ' '+quantity.units |
|
27 |
return str_ |
|
28 |
|
|
29 |
Quantity.__str__ = quantity2str |
|
30 |
|
|
31 |
def str2quantity(str_): |
|
32 |
value = str_ |
|
22 | 33 |
units = None |
23 |
if not value.isdigit(): # optimization to avoid regexp for simple cases
|
|
34 |
if not str_.isdigit(): # optimization to avoid regexp for simple cases
|
|
24 | 35 |
match = re.match(ur'(?i)^\s*(.*?\d\.?)\s*([a-z\'"°][\w.*/^-]*?)?\s*$', |
25 |
value) |
|
26 |
if match: # has units |
|
27 |
number, units = match.groups() |
|
28 |
units = std_units(util.none_if(units, u'')) |
|
29 |
return (format.str2float(number), units) |
|
36 |
str_) |
|
37 |
if match: value, units = match.groups() # has units |
|
38 |
return Quantity(value, units) |
|
30 | 39 |
|
31 |
def cleanup_units(value, default_units=None): |
|
32 |
'''Cleans up units so the number is separated from the units by one space. |
|
33 |
@param default_units Units to add if value has no units. If None, raises |
|
34 |
MissingUnitsException if value has no units. |
|
35 |
''' |
|
36 |
number, units = parse_units(value) |
|
37 |
if units == None: |
|
38 |
if default_units != None: units = default_units |
|
39 |
else: raise MissingUnitsException(value) |
|
40 |
return str(number)+' '+units |
|
40 |
def set_default_units(quantity, units): |
|
41 |
if quantity.units == None: quantity.units = units |
|
42 |
|
|
43 |
def convert(quantity, units): |
|
44 |
units = std_units(units) |
|
45 |
if units == None: return Quantity(quantity.value, units) # remove units |
|
46 |
elif quantity.units == units: return quantity |
|
47 |
else: raise NotImplementedError('Unit conversion not implemented yet') |
Also available in: Unified diff
units.py: Restructured to use a Quantity object for the units-tagged value and conversion functions quantity2str() and str2quantity() to convert between that and a raw string. Added convert() with basic support for removing units and passing through matching units. xml_func.py: _units: Added "to" attr. VegBIEN mappings: Remove units using new _units "to" attr instead of temporary workaround in _units.