# This is the preferred order when writing a CSV file
pref_order_csv = ('device', 'value', 'footprint', 'loadstatus', 'provided', 'mfg',
- 'mfg_part_number', 'vendor', 'vendor_part_number', 'quantity', 'refdes')
+ 'mfg_part_number', 'vendor', 'vendor_part_number', 'quantity', 'refdes', 'pnpformat')
pref_order_tab = ('refdes', 'device', 'value', 'footprint', 'loadstatus', 'provided', 'mfg',
- 'mfg_part_number', 'vendor', 'vendor_part_number', 'quantity')
+ 'mfg_part_number', 'vendor', 'vendor_part_number', 'quantity', 'pnpformat')
value_pattern=r'([0-9]+)(\.[0-9]*)?([kmMupng]?)(F|H|Hz|V|screws)?([ _][0-9]+(\.[0-9]*))?'
refdes_pattern=r'([a-zA-Z]+)([0-9]+)'
+def refdes_number(refdes):
+ mr = re.fullmatch(refdes_pattern, refdes)
+ if mr:
+ return int(mr.group(2)) + ord(mr.group(1))
+ raise ValueError('Invalid refdes %s' % (refdes,))
+
+
class Part():
"""
A single part containing a dictionary with all of the attributes
for i in range(len(values)):
if values[i]:
self.attrs[keys[i]] = values[i]
+ if not self.get('quantity'):
+ self.set('quantity', '1')
+ refdes = self.get_refdes()
+ if refdes:
+ self.set('refdes', " ".join(sorted(refdes, key=refdes_number)))
+
+ def __str__(self):
+ return self.attrs.__str__()
# Get an attribute value, returning None for
# missing attributes
return self.attrs[attr]
return None
+ # Get the list of refdes for a part
+ def get_refdes(self):
+ refdes = self.get('refdes')
+ if not refdes:
+ return ()
+ return refdes.split()
+
+ # Add a refdes to a part. Refdes is a space-separated string
+ def add_refdes(self, refdes):
+ if not refdes:
+ return
+ my_refdes = self.get('refdes')
+ quantity = self.get('quantity')
+ if quantity:
+ quantity = str(int(quantity) + 1)
+ else:
+ quantity = str(1)
+ if my_refdes:
+ refdes = my_refdes + " " + refdes
+ self.set('refdes', " ".join(sorted(refdes.split(), key=refdes_number)))
+ self.set('quantity', quantity)
+
# Get an attribute value in lower case
def get_lower(self, attr):
if attr in self.attrs:
# Add/replace a part, computing the key
def set(self, part):
key = part.key()
- self.parts[key] = part
+ if key in self.parts:
+ self.parts[key].add_refdes(part.get('refdes'))
+ else:
+ self.parts[key] = part
# Import from a CSV file object
def import_csv_file(self, infile):
refdes = 'unknown'
if part is not None:
refdes = part.get_unknown('refdes')
-
+ try:
+ refdes = refdes[0]
+ except:
+ pass
mr = re.fullmatch(refdes_pattern, refdes)
if mr:
category = mr.group(1)
keys = sorted(list(self.parts), key=self.cmp_tab_key)
for key in keys:
part = self.get(key)
- print("\t".join(tuple(map(part.get_unknown, attrs))), file=outfile)
+ orig_refdes = part.get('refdes')
+ for refdes in part.get_refdes():
+ part.set('refdes', refdes)
+ print("\t".join(tuple(map(part.get_unknown, attrs))), file=outfile)
+ part.set('refdes', orig_refdes)
# Export to a tab-delimited file
def export_tab(self, outname):