From 6ea743740ff4524287e5b63a18a45bd19d2451bb Mon Sep 17 00:00:00 2001 From: Trygve Laugstøl Date: Thu, 7 Sep 2017 21:44:16 +0200 Subject: o Reformat all. --- src/ee/kicad/bom/__init__.py | 221 ++++++++++++++++++++------------------ src/ee/kicad/bom/io.py | 81 +++++++------- src/ee/kicad/bom_tool/__init__.py | 185 ++++++++++++++++--------------- src/ee/kicad/bom_tool/predef.py | 5 +- 4 files changed, 254 insertions(+), 238 deletions(-) (limited to 'src/ee/kicad') diff --git a/src/ee/kicad/bom/__init__.py b/src/ee/kicad/bom/__init__.py index d0798a4..2a32521 100644 --- a/src/ee/kicad/bom/__init__.py +++ b/src/ee/kicad/bom/__init__.py @@ -2,124 +2,131 @@ import re import sys __all__ = [ - 'Part', - 'Library', - 'Bom', - 'Comp', - 'split_ref', + 'Part', + 'Library', + 'Bom', + 'Comp', + 'split_ref', ] + def split_ref(ref): - """Split "C12" into a tuple that's useful for sorting by component reference. - - For example: "C12" => ("C", 12, None). "Cfoo" => ("C", sys.maxsize, ""). - """ - m = split_ref.r.match(ref) - if not m: - return (ref, sys.maxsize, "") - groups = m.groups() - ref = groups[0] - val = groups[1] - rest = groups[2] - try: - return (ref, int(val), rest) - except ValueError: - pass - - return (ref, val, rest) -split_ref.r = re.compile("([A-Za-z]+)([0-9]+)(.*)") + """Split "C12" into a tuple that's useful for sorting by component reference. + + For example: "C12" => ("C", 12, None). "Cfoo" => ("C", sys.maxsize, ""). + """ + m = split_ref.r.match(ref) + if not m: + return (ref, sys.maxsize, "") + groups = m.groups() + ref = groups[0] + val = groups[1] + rest = groups[2] + try: + return (ref, int(val), rest) + except ValueError: + pass -class Part: - def __init__(self, name): - self.name = name + return (ref, val, rest) -class Library: - def __init__(self, name): - self.name = name - self.parts = {} - def add_part(self, part): - try: - return self.parts[part] - except KeyError: - p = Part(part) - self.parts[part] = p - return p +split_ref.r = re.compile("([A-Za-z]+)([0-9]+)(.*)") -class Bom(object): - def __init__(self): - self.libraries = {} - self._components = {} - def add_component(self, component): - self._components[component.ref] = component +class Part: + def __init__(self, name): + self.name = name - def get_component(self, name): - return self._components[name] - def get_components(self): - return self._components +class Library: + def __init__(self, name): + self.name = name + self.parts = {} - def all_field_names(self): - fields = set(['ref', 'value']) - for c in self._components.values(): - for f in c.fields: - fields.add(f) - return fields + def add_part(self, part): + try: + return self.parts[part] + except KeyError: + p = Part(part) + self.parts[part] = p + return p + + +class Bom(object): + def __init__(self): + self.libraries = {} + self._components = {} + + def add_component(self, component): + self._components[component.ref] = component + + def get_component(self, name): + return self._components[name] + + def get_components(self): + return self._components + + def all_field_names(self): + fields = set(['ref', 'value']) + for c in self._components.values(): + for f in c.fields: + fields.add(f) + return fields + + def find_library(self, name): + try: + return self.libraries[name] + except KeyError: + lib = Library(name) + self.libraries[name] = lib + return lib + + def to_pandas(self, ref_field_name=None, value_field_name=None): + import pandas + + ref_field_name = ref_field_name or "ref" + value_field_name = value_field_name or "value" + + fields = self.all_field_names() + data = {k: [] for k in fields} + refs = [] + values = [] + for ref, c in self.get_components().items(): + refs.append(c.ref) + values.append(c.value) + for field in fields: + data[field].append(c[field] if field in c else None) + + # del data[ref_field_name] + data[ref_field_name] = refs + data[value_field_name] = values + return pandas.DataFrame(data=data, index=refs) - def find_library(self, name): - try: - return self.libraries[name] - except KeyError: - lib = Library(name) - self.libraries[name] = lib - return lib - - def to_pandas(self, ref_field_name = None, value_field_name = None): - import pandas - - ref_field_name = ref_field_name or "ref" - value_field_name = value_field_name or "value" - - fields = self.all_field_names() - data = {k: [] for k in fields} - refs = [] - values = [] - for ref, c in self.get_components().items(): - refs.append(c.ref) - values.append(c.value) - for field in fields: - data[field].append(c[field] if field in c else None) - -# del data[ref_field_name] - data[ref_field_name] = refs - data[value_field_name] = values - return pandas.DataFrame(data=data, index=refs) class Comp: - def __init__(self, ref, value, library, part, footprint): - self.ref = ref - self.value = value - self.footprint = footprint - self.library = library - self.part = part - self.fields = {} - - def add_field(self, key, value): - self.fields[key] = value - - def __contains__(self, key): - if key == 'ref': - return self.ref is not None - elif key == 'value': - return self.value is not None - else: - return key in self.fields - - def __getitem__(self, key): - if key == 'ref': - return self.ref - elif key == 'value': - return self.value - else: - return self.fields[key] + def __init__(self, ref, value, library, part, footprint): + self.ref = ref + self.value = value + self.footprint = footprint + self.library = library + self.part = part + self.fields = {} + + def add_field(self, key, value): + self.fields[key] = value + + def __contains__(self, key): + if key == 'ref': + return self.ref is not None + elif key == 'value': + return self.value is not None + else: + return key in self.fields + + def __getitem__(self, key): + if key == 'ref': + return self.ref + elif key == 'value': + return self.value + else: + return self.fields[key] diff --git a/src/ee/kicad/bom/io.py b/src/ee/kicad/bom/io.py index c7eef44..d7c0367 100644 --- a/src/ee/kicad/bom/io.py +++ b/src/ee/kicad/bom/io.py @@ -1,44 +1,45 @@ import xml.etree.ElementTree as ElementTree from ee.kicad.bom import * + def read_bom(path): - def child_text(e, child_tag): - child = e.find(child_tag) - - return child.text if child is not None else None - - def add_comp(b, comp): - ref = comp.get("ref") - value = child_text(comp, "value") - footprint = child_text(comp, "footprint") - libsource = comp.find("libsource") - l, p = (None, None) - if libsource is not None: - lib = libsource.get("lib") - part = libsource.get("part") - if lib is not None and part is not None: - l = b.find_library(lib) - p = l.add_part(part) - - c = Comp(ref, value, l, p, footprint) - - fields = comp.find("fields") - if fields is not None: - for f in fields.findall("field"): - key = f.get("name") - value = f.text - c.add_field(key, value) - - b.add_component(c) - return c - - with open(path) as f: - tree = ElementTree.parse(path) - root = tree.getroot() - - b = Bom() - comp = root.find("components").findall("comp") - for c in comp: - add_comp(b, c) - - return b + def child_text(e, child_tag): + child = e.find(child_tag) + + return child.text if child is not None else None + + def add_comp(b, comp): + ref = comp.get("ref") + value = child_text(comp, "value") + footprint = child_text(comp, "footprint") + libsource = comp.find("libsource") + l, p = (None, None) + if libsource is not None: + lib = libsource.get("lib") + part = libsource.get("part") + if lib is not None and part is not None: + l = b.find_library(lib) + p = l.add_part(part) + + c = Comp(ref, value, l, p, footprint) + + fields = comp.find("fields") + if fields is not None: + for f in fields.findall("field"): + key = f.get("name") + value = f.text + c.add_field(key, value) + + b.add_component(c) + return c + + with open(path) as f: + tree = ElementTree.parse(path) + root = tree.getroot() + + b = Bom() + comp = root.find("components").findall("comp") + for c in comp: + add_comp(b, c) + + return b diff --git a/src/ee/kicad/bom_tool/__init__.py b/src/ee/kicad/bom_tool/__init__.py index 9f450c9..f5d2e4f 100644 --- a/src/ee/kicad/bom_tool/__init__.py +++ b/src/ee/kicad/bom_tool/__init__.py @@ -3,108 +3,115 @@ import functools import itertools import pandas as pd + def _none_if_empty(l): - return l if l is not None and len(l) > 0 else None + return l if l is not None and len(l) > 0 else None + class Supplier(): - def __init__(self, name, bom_field = None): - self._name = name - self._bom_field = bom_field if not None else name + def __init__(self, name, bom_field=None): + self._name = name + self._bom_field = bom_field if not None else name + + @property + def bom_field(self): + return self._bom_field - @property - def bom_field(self): - return self._bom_field class Settings(): - def __init__(self, suppliers = None, part_field = None): - self._suppliers = suppliers if suppliers is not None else [] - self._part_field = part_field if part_field is not None else 'part' + def __init__(self, suppliers=None, part_field=None): + self._suppliers = suppliers if suppliers is not None else [] + self._part_field = part_field if part_field is not None else 'part' - @property - def suppliers(self): - return self._suppliers + @property + def suppliers(self): + return self._suppliers - @property - def part_field(self): - return self._part_field + @property + def part_field(self): + return self._part_field + + @part_field.setter + def part_field(self, value): + self._part_field = value - @part_field.setter - def part_field(self, value): - self._part_field = value class CsvFormat(): - def __init__(self, supplier = None, group_by_fields = None, required_fields = None): - self._supplier = supplier - self._group_by_fields = _none_if_empty(group_by_fields) - self._required_fields = _none_if_empty(required_fields) + def __init__(self, supplier=None, group_by_fields=None, required_fields=None): + self._supplier = supplier + self._group_by_fields = _none_if_empty(group_by_fields) + self._required_fields = _none_if_empty(required_fields) + + @property + def supplier(self): + return self._supplier - @property - def supplier(self): - return self._supplier + @property + def group_by_fields(self): + return self._group_by_fields - @property - def group_by_fields(self): - return self._group_by_fields + @property + def required_fields(self): + return self._required_fields - @property - def required_fields(self): - return self._required_fields def _all(fs, c): - for f in fs: - if not f(c): - return False - return True - -def to_panda(bom, bom_settings, csv_format): # type: (Bom, BomSettings, CsvFormat) -> None - filters = [] - - print("csv_format.supplier.bom_field={}".format(csv_format.supplier.bom_field)) - if csv_format.supplier is not None: - filters.append(lambda c: csv_format.supplier.bom_field in c) - - if csv_format.group_by_fields is not None: - filters.append(lambda c: all([field in c for field in csv_format.group_by_fields])) - - if csv_format.required_fields is not None: - filters.append(lambda c: all([field in c for field in csv_format.required_fields])) - - f = functools.partial(_all, filters) - print("len(filters)={}".format(len(filters))) - print("len(bom.get_components())={}".format(len(bom.get_components()))) - - filtered = [c for ref, c in bom.get_components().items() if f(c)] - print("filtered:, len={}".format(len(filtered))) - filtered.sort(key=lambda c: c.ref) - print("sorted filtered:, len={}".format(len(filtered))) - - counts=None - parts=[] - - frame = {} - for n in bom.all_field_names(): - frame[n] = [] - - if csv_format.group_by_fields is not None: - counts, parts, refs=([],[],[]) - for group, comps in itertools.groupby(filtered, key=lambda c: [field for field in c for c in csv_format.group_by_fields]): - gs = list(group) - cs = list(comps) -# counts.append(len(cs)) -# dpns.append(part) -# mpns.append(part) -# refs.append(functools.reduce(lambda a, b: a + ' ' + b, [c.ref for c in cs], '')) - print("group={}".format(gs)) - -# return pd.DataFrame(data={ -# 'count': counts, -# 'mpn': mpns, -# 'dpn': dpns, -# 'refs': refs, -# }) - else: - for ref, c in filtered: - for key, value in c: - frame[key] = value - - return pd.DataFrame(data=frame) + for f in fs: + if not f(c): + return False + return True + + +def to_panda(bom, bom_settings, csv_format): # type: (Bom, BomSettings, CsvFormat) -> None + filters = [] + + print("csv_format.supplier.bom_field={}".format(csv_format.supplier.bom_field)) + if csv_format.supplier is not None: + filters.append(lambda c: csv_format.supplier.bom_field in c) + + if csv_format.group_by_fields is not None: + filters.append(lambda c: all([field in c for field in csv_format.group_by_fields])) + + if csv_format.required_fields is not None: + filters.append(lambda c: all([field in c for field in csv_format.required_fields])) + + f = functools.partial(_all, filters) + print("len(filters)={}".format(len(filters))) + print("len(bom.get_components())={}".format(len(bom.get_components()))) + + filtered = [c for ref, c in bom.get_components().items() if f(c)] + print("filtered:, len={}".format(len(filtered))) + filtered.sort(key=lambda c: c.ref) + print("sorted filtered:, len={}".format(len(filtered))) + + counts = None + parts = [] + + frame = {} + for n in bom.all_field_names(): + frame[n] = [] + + if csv_format.group_by_fields is not None: + counts, parts, refs = ([], [], []) + for group, comps in itertools.groupby(filtered, + key=lambda c: [field for field in c for c in csv_format.group_by_fields]): + gs = list(group) + cs = list(comps) + # counts.append(len(cs)) + # dpns.append(part) + # mpns.append(part) + # refs.append(functools.reduce(lambda a, b: a + ' ' + b, [c.ref for c in cs], '')) + print("group={}".format(gs)) + + # return pd.DataFrame(data={ + # 'count': counts, + # 'mpn': mpns, + # 'dpn': dpns, + # 'refs': refs, + # }) + else: + for ref, c in filtered: + for key, value in c: + frame[key] = value + + return pd.DataFrame(data=frame) diff --git a/src/ee/kicad/bom_tool/predef.py b/src/ee/kicad/bom_tool/predef.py index 717f6d3..bfe8631 100644 --- a/src/ee/kicad/bom_tool/predef.py +++ b/src/ee/kicad/bom_tool/predef.py @@ -1,6 +1,7 @@ from ee.kicad.bom_tool import * -digikey = Supplier('Digi-Key', bom_field = 'digikey') +digikey = Supplier('Digi-Key', bom_field='digikey') + def digikeyCsvFormat(digikey_supplier): - return CsvFormat(supplier = digikey, group_by_fields = [digikey_supplier.bom_field]) + return CsvFormat(supplier=digikey, group_by_fields=[digikey_supplier.bom_field]) -- cgit v1.2.3