import decimal import re import enum import collections from . import si unit_ord = ("full", "utf", "ascii") UnitDef = collections.namedtuple("UnitDef", unit_ord) unit_defs = { UnitDef("ohm", "Ω", "R"), UnitDef("volt", "V", "V"), UnitDef("amper", "A", "A"), } units_dicts = [] for r in unit_ord: d = dict() for u in unit_defs: d[getattr(u, r)] = u units_dicts.append(d) def symbol_to_unitdef(symbol): for ud in units_dicts: if symbol in ud: return ud[symbol] return None class Component: class Unit: def __init__(self, unit): if isinstance(unit, type(self)): self.u = unit.u elif isinstance(unit, UnitDef): self.u = unit else: self.u = symbol_to_unitdef(unit) if self.u is None: raise ValueError("invalid unit") def __str__(self, _ord="utf"): return getattr(self.u, _ord) class Value: def __init__(self, value, unit=None): self.unit = Component.Unit(unit) if isinstance(value, str): self.value = decode_infix(value) else: self.value = decimal.Decimal(value) def prefixed(self, replace_separator=True): return si.prefix(self.value, replace_separator=replace_separator) def __str__(self, unit_repr="utf8"): if self.unit is None: unit = None elif unit_repr == "utf8": unit = self.unit.u.utf elif unit_repr == "ascii": unit = self.unit.u.ascii elif unit_repr == "full": unit = self.unit.u.full else: raise ValueError("Invalid unit_repr: {!r:s}".format(unit_repr)) s = "{!s:s}".format(si.prefix(self.value)) if unit is not None: s += " {:s}".format(unit) return s def __init__(self, value=None, package=None): self.value = value self.package = package def to_item(): pass @classmethod def from_item(cls, item): if re.match("rezystor", item.name): return Resistor.from_item(item) class Resistor(Component): def __init__(self, resistance, package, tolerance): if isinstance(resistance, str): self.resistance = si.decode_infix(resistance) else: self.resistance = decimal.Decimal(value) self.tolerance = str(tolerance) self.package = str(package) @property def value(self): return self.Value(self.resistance, "ohm") @classmethod def from_item(cls, item): m = re.match("rezystor ([^ ]+) ([^ ]+)", item.name) tolerance = item.props.get("tolerance", "unknown") return cls(m.group(1), m.group(2), tolerance) def __repr__(self): return """""".format( self.value, self.package, self.tolerance )