]> git.gag.com Git - hw/altusmetrum/commitdiff
bin: Add argument handling to fillparts programs
authorKeith Packard <keithp@keithp.com>
Tue, 11 Feb 2025 01:13:17 +0000 (17:13 -0800)
committerKeith Packard <keithp@keithp.com>
Tue, 11 Feb 2025 01:13:17 +0000 (17:13 -0800)
This creating output files inside the applications so that errors
don't end up leaving output files lying around after make finishes.

Signed-off-by: Keith Packard <keithp@keithp.com>
bin/fillpartscsv.py
bin/fillpartslist.py
bin/parts.py

index 4f2d24f160d3a2796d4586a47b6144e11289828e..675bb30428dd45db0fa70887a90bf8d3cb0f2b64 100755 (executable)
 # 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
 #
 
-import parts;
-import csv;
-import sys;
+import argparse
+import parts
+import sys
                 
 def main():
-    preferred = parts.Parts(ods='default')
-    my_parts = parts.Parts(csv_file=sys.stdin)
+    parser = argparse.ArgumentParser();
+    parser.add_argument("input", help="CSV format input file")
+    parser.add_argument("-o", "--output", help="CSV format output file")
+    parser.add_argument("-p", "--preferred", help="Preferred parts database")
+    args = parser.parse_args()
+
+    if args.preferred:
+        preferred_name = args.preferred
+    else:
+        preferred_name = 'default'
+    preferred = parts.Parts(ods=preferred_name)
+    if args.input:
+        with open(args.input) as input:
+            my_parts = parts.Parts(csv_file=input)
+    else:
+        my_parts = parts.Parts(csv_file=sys.stdin)
     my_parts.fill_values(preferred)
-    my_parts.export_csv_file(sys.stdout)
+    if args.output:
+        my_parts.export_csv(args.output)
+    else:
+        my_parts.export_csv_file(sys.stdout)
 
 main()
index 00324db92a8150148a3c87276204aa1c839500e0..afc5149db3f9a57264df87e63432412f2db288ce 100755 (executable)
 # 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
 #
 
-import parts;
-import sys;
+import argparse
+import parts
+import sys
                 
 def main():
-    preferred = parts.Parts(ods='default')
-    my_parts = parts.Parts(tab_file=sys.stdin)
+    parser = argparse.ArgumentParser();
+    parser.add_argument("input", help="Tab-delimited input file")
+    parser.add_argument("-o", "--output", help="Tab-delimited output file")
+    parser.add_argument("-p", "--preferred", help="Preferred parts database")
+    args = parser.parse_args()
+
+    if args.preferred:
+        preferred_name = args.preferred
+    else:
+        preferred_name = 'default'
+    preferred = parts.Parts(ods=preferred_name)
+    if args.input:
+        with open(args.input) as input:
+            my_parts = parts.Parts(tab_file=input)
+    else:
+        my_parts = parts.Parts(tab_file=sys.stdin)
     my_parts.fill_values(preferred)
-    my_parts.export_tab_file(sys.stdout)
+    if args.output:
+        my_parts.export_tab(args.output)
+    else:
+        my_parts.export_tab_file(sys.stdout)
 
 main()
index aca296e82ff441e89f715695ba8ce6c1d72a5298..3b6321ae5b30ba5b4af2b3479c79ccc7de4f9cd6 100644 (file)
 AltusMetrum collection of classes
 """
 
-import csv;
-import tempfile;
-import subprocess;
+import csv
+import tempfile
+import subprocess
 import os
 import sys
 import functools
-from pathlib import Path;
-import re;
+from pathlib import Path
+import re
 
 # These attributes form the 'key' used to uniquely identify the part
 key_attrs = ('device', 'value', 'footprint')
@@ -38,64 +38,6 @@ pref_order = ('device', 'value', 'footprint', 'loadstatus', 'provided', 'mfg',
 
 value_pattern=r'([0-9]+)(\.[0-9]*)?([kmMupng]?)(F|H|Hz)?'
 
-def numeric_value(a):
-    m = re.fullmatch(value_pattern, a, flags=re.IGNORECASE)
-    if m:
-        n = m.group(1)
-        if m.group(2):
-            n += m.group(2)
-        number = float(n)
-        scale = m.group(3)
-        if scale == 'G':
-            number *= 1000000000
-        elif scale == 'M':
-            number *= 1000000
-        elif scale == 'k':
-            number *= 1000
-        elif scale == 'm':
-            number /= 1000
-        elif scale == 'u' or scale == 'µ':
-            number /= 1000000
-        elif scale == 'p':
-            number /= 1000000000
-        return number
-    return None
-
-def value_cmp(a, b):
-    na = numeric_value(a)
-    nb = numeric_value(b)
-    if na and nb:
-        if na < nb:
-            return -1
-        if na > nb:
-            return 1
-        return 0
-    if na:
-        return -1
-    if nb:
-        return 1
-    if a < b:
-        return -1
-    if b > a:
-        return 1
-    return 0
-
-def str_cmp(a,b):
-    if a < b:
-        return -1
-    if a > b:
-        return 1
-    return 0
-
-def key_cmp(a, b):
-    c = str_cmp(a[0], b[0])
-    if c:
-        return c
-    c = value_cmp(a[1], b[1])
-    if c:
-        return c
-    return str_cmp(a[2], b[2])
-
 class Part():
     """
     A single part containing a dictionary with all of the attributes
@@ -271,21 +213,58 @@ class Parts():
                 t = t + (i,)
         return t
         
-    # Export to a CSV file
+    # Compute a key value suitable for sorting
+    def cmp_key(self, k):
+        value = k[1]
+        m = re.fullmatch(value_pattern, value, flags=re.IGNORECASE)
+        if m:
+            number = m.group(1)
+            if m.group(2):
+                number += m.group(2)
+            n = float(number)
+            scale = m.group(3)
+            if scale == 'G':
+                n *= 1000000000
+            elif scale == 'M':
+                n *= 1000000
+            elif scale == 'k':
+                n *= 1000
+            elif scale == 'm':
+                n /= 1000
+            elif scale == 'u' or scale == 'µ':
+                n /= 1000000
+            elif scale == 'p':
+                n /= 1000000000
+            value = ""
+        else:
+            n = 0
+        return (k[0], value, n, k[2])
+
+    # Export to a CSV file object
     def export_csv_file(self, outfile):
         csvwriter = csv.writer(outfile, dialect='excel-nl')
         attrs = self.attrs_tuple()
         csvwriter.writerow(attrs)
-        keys = sorted(list(self.parts), key=functools.cmp_to_key(key_cmp))
+        keys = sorted(list(self.parts), key=self.cmp_key)
         for key in keys:
             part = self.get(key)
             csvwriter.writerow(tuple(map(part.get_unknown, attrs)))
         
-    # Export to a tab-delimited file
+    # Export to a CSV file
+    def export_csv(self, outname):
+        with open(outname, "w", newline='') as outfile:
+            self.export_csv_file(outfile)
+        
+    # Export to a tab-delimited file object
     def export_tab_file(self, outfile):
         attrs = self.attrs_tuple()
         print("\t".join(attrs), file=outfile)
-        keys = sorted(list(self.parts), key=functools.cmp_to_key(key_cmp))
+        keys = sorted(list(self.parts), key=self.cmp_key)
         for key in keys:
             part = self.get(key)
             print("\t".join(tuple(map(part.get_unknown, attrs))), file=outfile)
+
+    # Export to a tab-delimited file
+    def export_tab(self, outname):
+        with open(outname, "w") as outfile:
+            self.export_tab_file(outfile)