home · contact · privacy
Add packing-into-boxes helper to Collection.
authorPlom Heller <plom@plomlompom.com>
Fri, 24 Apr 2026 01:46:37 +0000 (03:46 +0200)
committerPlom Heller <plom@plomlompom.com>
Fri, 24 Apr 2026 01:46:37 +0000 (03:46 +0200)
bricksplom.py

index 904951640c6c6f0ad5ef5a103417052e0753f02f..64406098fce2476547b95c1a73adaa88f426cbd4 100755 (executable)
@@ -2,7 +2,7 @@
 'Data structures for managing/sorting bricks of a certain kind.'
 from abc import ABC, abstractmethod
 from pathlib import Path
-from typing import Optional, Self
+from typing import Callable, Optional, Self
 
 PATH_BOXES = 'boxes.txt'
 PATH_COLLECTIONS = 'collections.txt'
@@ -230,16 +230,23 @@ class Collection(Textfiled):
     def __str__(
             self
             ) -> str:
+        return f'\n{self.id_} {self.description}\n' + self._format_paginated(
+                lambda count, p_id, comment: f' {count:2} {p_id:>7} {comment}')
+
+    def _format_paginated(
+            self,
+            format_line: Callable[[int, str, str], str]
+            ) -> str:
         pages = []
         for page in self.piece_listings:
             columns = []
             for column in page:
                 lines = []
                 for count, piece_id, comment in column:
-                    lines += [f' {count:2} {piece_id:>7} {comment}']
+                    lines += [format_line(count, piece_id, comment)]
                 columns += ['\n'.join(lines)]
             pages += ['\n -\n'.join(columns)]
-        return f'\n{self.id_} {self.description}\n' + '\n =\n'.join(pages)
+        return '\n =\n'.join(pages)
 
     def piece_listings_flat(self) -> tuple[PieceListing, ...]:
         'Flattened variant of .piece_listings, no division into pages/cols.'
@@ -249,6 +256,33 @@ class Collection(Textfiled):
                 collected += list(column)
         return tuple(collected)
 
+    def _piece_to_box_idx_and_description(
+            self,
+            piece: 'Piece',
+            designs: dict[str, 'Design'],
+            boxes: dict[str, 'Box']
+            ) -> tuple[str, str]:
+        design = Design.possibly_by_alt(piece.design_id, designs)
+        assert design is not None
+        description = design.description
+        box = [b for b in boxes.values() if design.id_ in b.designs][0]
+        idx_in_box = box.designs.index(design.id_)
+        return f'{box.id_:>2}:{idx_in_box:>2}', description
+
+    def print_packing_instructions(
+            self,
+            pieces: dict[str, 'Piece'],
+            designs: dict[str, 'Design'],
+            boxes: dict[str, 'Box'],
+            ) -> None:
+        'Print helper for putting into boxes all pieces of self.'
+        def format_line(_, piece_id, __) -> str:
+            box_listing, description = self._piece_to_box_idx_and_description(
+                    pieces[piece_id], designs, boxes)
+            return f'{piece_id:>7} {box_listing} {description}'
+
+        print(self._format_paginated(format_line))
+
     def print_unpacking_instructions(
             self,
             pieces: dict[str, 'Piece'],
@@ -260,15 +294,11 @@ class Collection(Textfiled):
         lines = []
         for count, piece_id, _ in self.piece_listings_flat():
             piece = pieces[piece_id]
+            box_listing, description = self._piece_to_box_idx_and_description(
+                    piece, designs, boxes)
             color = str(colors[piece.color_id]).lstrip().split(CHAR_SPACE,
                                                                maxsplit=1)[1]
-            design = Design.possibly_by_alt(piece.design_id, designs)
-            assert design is not None
-            description = design.description
-            box = [b for b in boxes.values() if design.id_ in b.designs][0]
-            idx_in_box = box.designs.index(design.id_)
-            lines += [f'{box.id_:>2}:{idx_in_box:>2} '
-                      f'{count}× {color} {description}']
+            lines += [f'{box_listing} {count}× {color} {description}']
         for line in sorted(lines):
             print(line)