Skip to content
Snippets Groups Projects

Table formatter

  • Clone with SSH
  • Clone with HTTPS
  • Embed
  • Share
    The snippet can be accessed without any authentication.
    Authored by Markus Lutteropp

    Simple table formatter implementations

    Edited
    tableview.py 4.40 KiB
    #!/usr/bin/env python3
    
    from sys import stdout
    
    class TableView:
        spacer: str
        filler: str
        header_separator: str
        record_separator: str
        intersection: str
        left_intersection_mid: str
        right_intersection_mid: str
        field_separator: str
        top_border: bool
        field_width: dict[str,int]
        _header_printed: bool
    
        def __init__(
                self,
                spacer: str = " | ",
                filler: str = " ",
                header_separator: str = "",
                record_separator: str = "-",
                intersection: str = "",
                left_intersection_mid: str = "",
                right_intersection_mid: str = "",
                field_separator: str = "|",
                top_border: bool = True,
                headers: "list[str] | None" = None
            ) -> None:
            self.spacer = spacer
            self.filler = filler
            self.top_border = top_border
            self.header_separator = header_separator
            self.left_intersection_mid = left_intersection_mid
            self.right_intersection_mid = right_intersection_mid
            self.record_separator = record_separator
            self.intersection = intersection
            self.field_separator = field_separator
            self.field_width = {}
            self._header_printed = False
            if headers is not None and len(headers) == 0:
                for header in headers:
                    self.field_width[header] = 0
    
        def seed(self, record: dict[str,str]):
            preseeded = len(self.field_width) > 0
            for key, item in record.items():
                recognized = key in self.field_width.keys()
                if preseeded and not recognized:
                    raise Exception(f"{key} is not a recognized field and we already populated!")
                elif recognized:
                    if len(item) > self.field_width[key]:
                        self.field_width[key] = len(item)
                else:
                    self.field_width[key] = len(item)
    
        def _print(self, out: list[str], output=stdout, separator: bool = False):
            if separator:
                border = (self.left_intersection_mid, self.right_intersection_mid)
                mid = self.intersection
            else:
                border = (self.field_separator, self.field_separator)
                mid = self.field_separator
            output.write(f"{border[0]}{mid.join(out)}{border[1]}\n")
    
        def print(self, input: dict[str, str], output=stdout):
            if len(input.keys()) != len(self.field_width.keys()):
                raise Exception("field count mismatch!")
            self._print([
                f"{self.filler}{input[x]}{self.filler * (self.field_width[x] + 1 - len(str(input[x])))}" for x in self.field_width.keys()
            ], output=output)
    
        def printSeparator(self, output=stdout):
            if self._header_printed:
                separator = self.header_separator
                self._header_printed = False
            else:
                separator = self.record_separator
            self._print([
                f"{separator * (self.field_width[x] + 2)}" for x in self.field_width.keys()
            ], separator=True, output=output)
    
        def printHeader(self, output=stdout):
            tmp = {}
            for x in self.field_width.keys():
                tmp[x] = x
            if self.top_border:
                self._header_printed = True
                self.printSeparator(output)
            self.print(tmp, output)
            self._header_printed = True
    
        def printRecord(self, record: dict[str, str], output=stdout):
            self.print(record, output)
    
        def reset_widths(self):
            for x in self.field_width.keys():
                self.field_width[x] = 0
    
        def __str__(self) -> str:
            return str(self.__dict__)
    
        def __repr__(self) -> str:
            return f"TableView[{str(self)}]"
    
    
    if __name__ == "__main__":
        borders: bool = False
        tv = TableView(
            top_border=borders
        )
        data: list[dict[str, str]] = [
            {
                "Pete": "Boobies",
                "Karl": "Mansies",
                "Klaus": "Red Wine",
                "Manfred": "Getting married",
                "Voltron": "Nothingness"
            },
            {
                "Pete": "Radisches",
                "Karl": "Chocolate",
                "Klaus": "Bananas",
                "Manfred": "Fire",
                "Voltron": "Smokes"
            },
        ]
        output = stdout
        for record in data:
            tv.seed(record)
    
        tv.printHeader(output)
        for record in data:
            tv.printSeparator(output)
            tv.printRecord(record, output)
        if borders:
            tv.printSeparator(output)
        output.flush()
    0% Loading or .
    You are about to add 0 people to the discussion. Proceed with caution.
    Please register or to comment