electronics-inventory/electronics_inventory/components.py

109 lines
3.0 KiB
Python

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 """<Resistor('{!s:s}', '{!s:s}', '{:s}')>""".format(
self.value, self.package, self.tolerance
)