Project

General

Profile

1
# Quantities with units
2
# This file's encoding must be UTF-8Y with BOM so Python will auto-detect UTF-8
3

    
4
import re
5

    
6
import format
7
import strings
8
import util
9

    
10
class MissingUnitsException(Exception):
11
    def __init__(self, value):
12
        Exception.__init__(self, 'Value has no units: '+value)
13

    
14
def std_units(units):
15
    if units == None: return units
16
    else: return strings.remove_suffix('.', units) # for abbr ending in '.'
17
    # TODO: deal with '"° and abbrs
18

    
19
def parse_units(value):
20
    '''@return tuple (number float, units str|None)'''
21
    number = value
22
    units = None
23
    if not value.isdigit(): # optimization to avoid regexp for simple cases
24
        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)
30

    
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
(14-14/19)