def from_lines(cls, lines, to_base_func=None): header, lines = lines[0], lines[1:] r = _header_re.search(header) name = r.groupdict()['name'].strip() aliases = r.groupdict()['aliases'] if aliases: aliases = tuple(a.strip() for a in r.groupdict()['aliases'].split('=')) else: aliases = () defaults = r.groupdict()['defaults'] if defaults: def to_num(val): val = complex(val) if not val.imag: return val.real return val defaults = dict((str(k), to_num(v)) for k, v in _def_re.findall(defaults.strip('()'))) ctx = cls(name, aliases, defaults) else: ctx = cls(name, aliases) names = set() for line in lines: line = line.strip() if not line or line.startswith('#'): continue rel, eq = line.split(':') names.update(_varname_re.findall(eq)) func = _expression_to_function(eq) if '<->' in rel: src, dst = (ParserHelper.from_string(s) for s in rel.split('<->')) if to_base_func: src = to_base_func(src) dst = to_base_func(dst) ctx.add_transformation(src, dst, func) ctx.add_transformation(dst, src, func) elif '->' in rel: src, dst = (ParserHelper.from_string(s) for s in rel.split('->')) if to_base_func: src = to_base_func(src) dst = to_base_func(dst) ctx.add_transformation(src, dst, func) else: raise ValueError('Relationships must be specified with <-> or ->.') if defaults: missing_pars = set(defaults.keys()).difference(set(names)) if missing_pars: raise ValueError('Context parameters {0} not found in any equation.'.format(missing_pars)) return ctx
def test_issue25(self): x = ParserHelper.from_string("10 %") self.assertEqual(x, ParserHelper(10, {"%": 1})) x = ParserHelper.from_string("10 ‰") self.assertEqual(x, ParserHelper(10, {"‰": 1})) ureg.define("percent = [fraction]; offset: 0 = %") ureg.define("permille = percent / 10 = ‰") x = ureg.parse_expression("10 %") self.assertEqual(x, ureg.Quantity(10, {"%": 1})) y = ureg.parse_expression("10 ‰") self.assertEqual(y, ureg.Quantity(10, {"‰": 1})) self.assertEqual(x.to("‰"), ureg.Quantity(1, {"‰": 1}))
def test_issue25(self): x = ParserHelper.from_string("10 %") assert x == ParserHelper(10, {"%": 1}) x = ParserHelper.from_string("10 ‰") assert x == ParserHelper(10, {"‰": 1}) ureg.define("percent = [fraction]; offset: 0 = %") ureg.define("permille = percent / 10 = ‰") x = ureg.parse_expression("10 %") assert x == ureg.Quantity(10, {"%": 1}) y = ureg.parse_expression("10 ‰") assert y == ureg.Quantity(10, {"‰": 1}) assert x.to("‰") == ureg.Quantity(1, {"‰": 1})
def test_issue25(self): x = ParserHelper.from_string('10 %') self.assertEqual(x, ParserHelper(10, {'%': 1})) x = ParserHelper.from_string('10 ‰') self.assertEqual(x, ParserHelper(10, {'‰': 1})) ureg = UnitRegistry() ureg.define('percent = [fraction]; offset: 0 = %') ureg.define('permille = percent / 10 = ‰') x = ureg.parse_expression('10 %') self.assertEqual(x, ureg.Quantity(10, {'%': 1})) y = ureg.parse_expression('10 ‰') self.assertEqual(y, ureg.Quantity(10, {'‰': 1})) self.assertEqual(x.to('‰'), ureg.Quantity(1, {'‰': 1}))
def test_issue25(self): x = ParserHelper.from_string("10 %") self.assertEqual(x, ParserHelper(10, {"%": 1})) x = ParserHelper.from_string("10 ‰") self.assertEqual(x, ParserHelper(10, {"‰": 1})) ureg = UnitRegistry() ureg.define("percent = [fraction]; offset: 0 = %") ureg.define("permille = percent / 10 = ‰") x = ureg.parse_expression("10 %") self.assertEqual(x, ureg.Quantity(10, {"%": 1})) y = ureg.parse_expression("10 ‰") self.assertEqual(y, ureg.Quantity(10, {"‰": 1})) self.assertEqual(x.to("‰"), ureg.Quantity(1, {"‰": 1}))
def __init__(self, name, symbol, aliases, ): self.reference = reference self.is_base = is_base if isinstance(converter, string_types): converter = ParserHelper.from_string(converter) self.reference = UnitsContainer(converter) converter = ScaleConverter(converter.scale) super(UnitDefinition, self).__init__(name, symbol, aliases, converter)
def _freeze(d): """Return a hashable view of dict. """ if isinstance(d, string_types): d = ParserHelper.from_string(d) if isinstance(d, frozenset): return d return frozenset(d.items())
def test_basic(self): # Parse Helper ar mutables, so we build one everytime x = lambda: ParserHelper(1, meter=2) xp = lambda: ParserHelper(1, meter=2) y = lambda: ParserHelper(2, meter=2) self.assertEqual(x(), xp()) self.assertNotEqual(x(), y()) self.assertEqual(ParserHelper.from_string(""), ParserHelper()) self.assertEqual(repr(x()), "<ParserHelper(1, {'meter': 2.0})>") self.assertEqual(ParserHelper(2), 2) self.assertEqual(x(), dict(meter=2)) self.assertEqual(x(), "meter ** 2") self.assertNotEqual(y(), dict(meter=2)) self.assertNotEqual(y(), "meter ** 2") self.assertNotEqual(xp(), object())
def test_basic(self): # Parse Helper ar mutables, so we build one everytime x = lambda: ParserHelper(1, meter=2) xp = lambda: ParserHelper(1, meter=2) y = lambda: ParserHelper(2, meter=2) self.assertEqual(x(), xp()) self.assertNotEqual(x(), y()) self.assertEqual(ParserHelper.from_string(''), ParserHelper()) self.assertEqual(repr(x()), "<ParserHelper(1, {'meter': 2})>") self.assertEqual(ParserHelper(2), 2) self.assertEqual(x(), dict(meter=2)) self.assertEqual(x(), 'meter ** 2') self.assertNotEqual(y(), dict(meter=2)) self.assertNotEqual(y(), 'meter ** 2') self.assertNotEqual(xp(), object())
def test_basic(self): # Parse Helper ar mutables, so we build one everytime x = lambda: ParserHelper(1, meter=2) xp = lambda: ParserHelper(1, meter=2) y = lambda: ParserHelper(2, meter=2) assert x() == xp() assert x() != y() assert ParserHelper.from_string("") == ParserHelper() assert repr(x()) == "<ParserHelper(1, {'meter': 2})>" assert ParserHelper(2) == 2 assert x() == dict(meter=2) assert x() == "meter ** 2" assert y() != dict(meter=2) assert y() != "meter ** 2" assert xp() != object()
def test_nan(self): for s in ("nan", "NAN", "NaN", "123 NaN nan NAN 456"): with self.subTest(s): p = ParserHelper.from_string(s + " kg") assert math.isnan(p.scale) self.assertEqual(dict(p), {"kg": 1})
def test_nan(self, subtests): for s in ("nan", "NAN", "NaN", "123 NaN nan NAN 456"): with subtests.test(s): p = ParserHelper.from_string(s + " kg") assert math.isnan(p.scale) assert dict(p) == {"kg": 1}
def from_lines(cls, lines, to_base_func=None): header, lines = lines[0], lines[1:] r = _header_re.search(header) name = r.groupdict()['name'].strip() aliases = r.groupdict()['aliases'] if aliases: aliases = tuple(a.strip() for a in r.groupdict()['aliases'].split('=')) else: aliases = () defaults = r.groupdict()['defaults'] if defaults: def to_num(val): val = complex(val) if not val.imag: return val.real return val defaults = dict((str(k), to_num(v)) for k, v in _def_re.findall(defaults.strip('()'))) ctx = cls(name, aliases, defaults) else: ctx = cls(name, aliases) names = set() for line in lines: line = line.strip() if not line or line.startswith('#'): continue rel, eq = line.split(':') names.update(_varname_re.findall(eq)) func = _expression_to_function(eq) if '<->' in rel: src, dst = (ParserHelper.from_string(s) for s in rel.split('<->')) if to_base_func: src = to_base_func(src) dst = to_base_func(dst) ctx.add_transformation(src, dst, func) ctx.add_transformation(dst, src, func) elif '->' in rel: src, dst = (ParserHelper.from_string(s) for s in rel.split('->')) if to_base_func: src = to_base_func(src) dst = to_base_func(dst) ctx.add_transformation(src, dst, func) else: raise ValueError( 'Relationships must be specified with <-> or ->.') if defaults: missing_pars = set(defaults.keys()).difference(set(names)) if missing_pars: raise ValueError( 'Context parameters {0} not found in any equation.'.format( missing_pars)) return ctx