home · contact · privacy
Add basic argparsing, translating positional arguments into table lookups.
authorPlom Heller <plom@plomlompom.com>
Fri, 1 May 2026 23:36:41 +0000 (01:36 +0200)
committerPlom Heller <plom@plomlompom.com>
Fri, 1 May 2026 23:36:41 +0000 (01:36 +0200)
bricksplom.py

index 31396ffdc7dda0fc7bee0d2cac281a4a035ac8e5..835ba1878f128dd8759fa0caad2c3ca2162820b1 100755 (executable)
@@ -1,6 +1,7 @@
 #!/usr/bin/env python3
 'Data structures for managing/sorting bricks of a certain kind.'
 from abc import ABC, abstractmethod
+from argparse import ArgumentError, ArgumentParser
 from os import environ
 from pathlib import Path
 from typing import Callable, Optional, Self
@@ -359,7 +360,7 @@ class Box(WithDb):
                 count_pieces = 0
                 color = self._db.colors[piece.color_id]
                 for listings in [c.piece_listings_flat()
-                                 for c in self._db.colls.values()]:
+                                 for c in self._db.collections.values()]:
                     for count in [t[0] for t in listings if t[1] == piece.id_]:
                         count_pieces += count
                 print(f'{count_pieces:>2}× {piece.id_:>7} / {color}')
@@ -367,6 +368,8 @@ class Box(WithDb):
 
 class BricksDb:
     'Collection of all the tables enabling their combined processing.'
+    lookupable = frozenset(
+            {'boxes', 'designs', 'collections', 'colors', 'pieces'})
 
     def __init__(
             self,
@@ -374,17 +377,17 @@ class BricksDb:
             ) -> None:
         self.colors = Color.from_textfile((path_tables, PATH_COLORS))
         self.pieces = Piece.from_textfile((path_tables, PATH_PIECES))
-        self.colls = Collection.from_textfile((path_tables, PATH_COLLECTIONS),
-                                              db=self)
+        self.collections = Collection.from_textfile(
+                (path_tables, PATH_COLLECTIONS), db=self)
         self.designs = Design.from_textfile((path_tables, PATH_DESIGNS))
         self._check_consistencies_between_tables()
 
     def boxes(
             self
             ) -> dict[str, Box]:
-        'Parsed from "box:"-prefixed entries in .colls.'
+        'Parsed from "box:"-prefixed entries in .collections.'
         collected = {}
-        for coll in [c for c in self.colls.values()
+        for coll in [c for c in self.collections.values()
                      if c.id_.startswith(BOX_PREFIX)]:
             box_id = coll.id_[len(BOX_PREFIX):]
             assert box_id
@@ -404,7 +407,7 @@ class BricksDb:
             ) -> None:
 
         # check all items listed in collections recorded in pieces
-        for coll in self.colls.values():
+        for coll in self.collections.values():
             for _, piece_id, _ in coll.piece_listings_flat():
                 assert piece_id in self.pieces, piece_id
 
@@ -434,7 +437,7 @@ class BricksDb:
 
         # check collections in-out directions even out
         counts: dict[str, int] = {}
-        for coll in self.colls.values():
+        for coll in self.collections.values():
             if coll.is_in is None:
                 continue
             for count, piece_id, _ in coll.piece_listings_flat():
@@ -443,6 +446,17 @@ class BricksDb:
         for piece_id, count in counts.items():
             assert count == 0, (piece_id, count)
 
+    def lookup(
+            self,
+            table_name: str,
+            inquiry: str
+            ) -> str:
+        'Return result of inquiry on table of table_name.'
+        assert table_name in self.lookupable
+        maybe_dict = getattr(self, table_name)
+        table = maybe_dict if isinstance(maybe_dict, dict) else maybe_dict()
+        return table[inquiry]
+
     def piece_to_box_listing(
             self,
             piece_id: str,
@@ -464,7 +478,7 @@ class BricksDb:
                              ('PIECES', self.pieces),
                              ('DESIGNS', self.designs),
                              ('BOXES', self.boxes()),
-                             ('COLLECTIONS', self.colls)):
+                             ('COLLECTIONS', self.collections)):
             print(title)
             for item in items.values():
                 print(item)
@@ -473,8 +487,28 @@ class BricksDb:
 def main(
         ) -> None:
     'Load tables from BRICKSPLOM_DIR and put out in reproducible listings.'
+    def add_abbrev_choices_arg(
+            parser: ArgumentParser,
+            argname: str,
+            choices: set[str]
+            ) -> None:
+        def complete(
+                arg: str
+                ) -> str:
+            candidates = tuple(c for c in choices if c.startswith(arg))
+            if len(candidates) > 1:
+                raise ArgumentError(
+                    action,
+                    f'{arg} – ambiguous, could match: {", ".join(candidates)}')
+            return (candidates + (arg, ))[0]
+        action = parser.add_argument(argname, choices=choices, type=complete)
+
     db = BricksDb(environ.get(NAME_ENV_DIRNAME, '.'))
-    db.print()
+    parser = ArgumentParser()
+    add_abbrev_choices_arg(parser, 'table', set(db.lookupable))
+    parser.add_argument('inquiry')
+    args = parser.parse_args()
+    print(db.lookup(args.table, args.inquiry))
 
 
 main()