#!/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
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}')
class BricksDb:
'Collection of all the tables enabling their combined processing.'
+ lookupable = frozenset(
+ {'boxes', 'designs', 'collections', 'colors', 'pieces'})
def __init__(
self,
) -> 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
) -> 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
# 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():
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,
('PIECES', self.pieces),
('DESIGNS', self.designs),
('BOXES', self.boxes()),
- ('COLLECTIONS', self.colls)):
+ ('COLLECTIONS', self.collections)):
print(title)
for item in items.values():
print(item)
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()