import functools import itertools import pandas as pd from ee.kicad.bom import * def _none_if_empty(l): 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 @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' @property def suppliers(self): return self._suppliers @property def part_field(self): return self._part_field @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) @property def supplier(self): return self._supplier @property def group_by_fields(self): return self._group_by_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)