home · contact · privacy
De-hardcode Lookupables' .id_ paddings in string formattings.
authorPlom Heller <plom@plomlompom.com>
Sat, 30 May 2026 02:07:12 +0000 (04:07 +0200)
committerPlom Heller <plom@plomlompom.com>
Sat, 30 May 2026 02:07:12 +0000 (04:07 +0200)
bricksplom.py

index b5c9f35c961fe326320d1ea8cdd50f6abc336f24..786cadb3a3e1c3bbf456e39f81696ab4b30891ec 100755 (executable)
@@ -96,7 +96,18 @@ class WithDb:
 
 
 class Lookupable:
-    'Provide methods used by BricksDb.lookup.'
+    'Provides methods for BricksDb.lookup and .id_ padding.'
+    _id_indent: int = 0
+    id_: str
+
+    @classmethod
+    def indent_id(cls, id_: str) -> str:
+        'id_ indented by value of cls._id_indent.'
+        return (max(0, cls._id_indent - len(id_)) * ' ') + id_
+
+    def id_indented(self) -> str:
+        'self.id_ indented by value of self._id_indent.'
+        return self.indent_id(self.id_)
 
     def searchable(
             self
@@ -113,6 +124,7 @@ class Lookupable:
 
 class Color(Textfiled, Lookupable):
     'Color incl. solidness/transparency field.'
+    _id_indent = 3
 
     def __init__(
             self,
@@ -141,13 +153,14 @@ class Color(Textfiled, Lookupable):
     def raw(
             self
             ) -> str:
-        return (f'{self.id_:>3} '
+        return (f'{self.id_indented()} '
                 + (CHAR_COL_SOLID if self.solid else CHAR_COL_TRANSPARENT)
                 + self.wavelength)
 
 
 class Design(Textfiled, Lookupable):
     'Shape and texture configurations with descriptions and equalities.'
+    _id_indent = 6
     alternate_to: Optional[Self] = None
 
     def __init__(
@@ -204,13 +217,14 @@ class Design(Textfiled, Lookupable):
     def raw(
             self
             ) -> str:
-        return f'{self.id_:>6} ' + (f'={self.alternate_to.id_}'
-                                    if self.alternate_to
-                                    else f'_{self._description}')
+        return f'{self.id_indented()} ' + (f'={self.alternate_to.id_}'
+                                           if self.alternate_to
+                                           else f'_{self._description}')
 
 
 class Piece(Textfiled, WithDb, Lookupable):
     'Individual configuration of design and color.'
+    _id_indent = 7
 
     def __init__(
             self,
@@ -246,8 +260,8 @@ class Piece(Textfiled, WithDb, Lookupable):
     def raw(
             self
             ) -> str:
-        return (f'{self.id_:>7} {self.design_id:>6} '
-                f'{self.color_id:>3} {self.comment}').rstrip()
+        return (f'{self.id_indented()} {Design.indent_id(self.design_id)} '
+                f'{Color.indent_id(self.color_id)} {self.comment}').rstrip()
 
     def __str__(
             self
@@ -256,7 +270,7 @@ class Piece(Textfiled, WithDb, Lookupable):
         design = self._db.designs[self.design_id]
         color = str(self._db.colors[self.color_id]).strip()
         comment = f' # {self.comment}' if self.comment else ''
-        return (f'{self.id_:>7} {self.design_id:>6} '
+        return (f'{self.id_indented()} {Design.indent_id(self.design_id)} '
                 f'{design.description} ({color}){comment}')
 
 
@@ -330,9 +344,11 @@ class Collection(Textfiled, WithDb, Lookupable):
     def raw(
             self
             ) -> str:
-        return (f'{self.id_} {self._is_in_str}{self.description}{CHAR_NEWLINE}'
+        return (f'{self.id_indented()} '
+                f'{self._is_in_str}{self.description}{CHAR_NEWLINE}'
                 + self._format_paginated(lambda count, p_id, comment:
-                                         f' {count:2} {p_id:>7} {comment}'))
+                                         f' {count:2} {Piece.indent_id(p_id)}'
+                                         + (f' {comment}' if comment else '')))
 
     def __str__(
             self
@@ -397,16 +413,18 @@ class Collection(Textfiled, WithDb, Lookupable):
                         break
                     if box:
                         break
-            box_listing = f'{box.id_:>2}:{idx_in_box:>2}' if box else '__:__'
-            return (f'{count:>2}× {piece_id:>7}:{design_id:>6} {box_listing} '
-                    f'{color} {self._db.designs[design_id].description}'
-                    f'{tail_comment}')
+            box_listing = ((box.id_indented() if box else Box.indent_id(''))
+                           + ':' + (f'{idx_in_box:>2}' if box else '__'))
+            return (f'{count:>2}× {Piece.indent_id(piece_id)}:'
+                    f'{Design.indent_id(design_id)} {box_listing} {color} '
+                    f'{self._db.designs[design_id].description}{tail_comment}')
 
         return f'{self}{CHAR_NEWLINE}{self._format_paginated(format_line)}'
 
 
 class Box(WithDb, Lookupable):
     'Order of designs.'
+    _id_indent = 4
 
     def __init__(
             self,
@@ -432,7 +450,7 @@ class Box(WithDb, Lookupable):
     def __str__(
             self
             ) -> str:
-        return (f'{self.id_:>2} '
+        return (f'{self.id_indented()} '
                 + ', '.join('/'.join(design.all_ids)
                             for design, _ in self.designs_to_listings))
 
@@ -446,7 +464,8 @@ class Box(WithDb, Lookupable):
                 f'=== {" / ".join(design.all_ids)}: {design.description} ===']
             for count, piece_id, comment in listings:
                 color = self._db.colors[self._db.pieces[piece_id].color_id]
-                lines += [f'{count:>2}× {piece_id:>7} / {color} # {comment}']
+                lines += [f'{count:>2}× {Piece.indent_id(piece_id)} / {color} '
+                          f'# {comment}']
         return CHAR_NEWLINE.join(lines)
 
     def raw(
@@ -539,7 +558,8 @@ class BricksDb:
         if inquiry.startswith(CHAR_INQUIRY):
             return CHAR_NEWLINE.join(
                     [(v.raw() if show_raw else str(v)) for
-                     v in sorted(table.values(), key=lambda v: f'{v.id_:>7}')
+                     v in sorted(table.values(),
+                                 key=lambda v: f'{v.id_indented()}')
                      if inquiry[1:].upper() in str(v.searchable()).upper()])
         item = table[inquiry]
         return item.raw() if show_raw else item.show()