Project

General

Profile

« Previous | Next » 

Revision 1471

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.

View differences:

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