printbuddies.printbuddies API documentation

# printbuddies.printbuddies

View Source

      1from os import get_terminal_size
      2from time import sleep
      3from typing import Any
      4
      5from noiftimer import Timer
      6
      7
      8def clear():
      9    """Erase the current line from the terminal."""
     10    print(" " * (get_terminal_size().columns - 1), flush=True, end="\r")
     11
     12
     13def print_in_place(string: str, animate: bool = False, animate_refresh: float = 0.01):
     14    """Calls to print_in_place will overwrite
     15    the previous line of text in the terminal
     16    with the 'string' param.
     17
     18    :param animate: Will cause the string
     19    to be printed to the terminal
     20    one character at a time.
     21
     22    :param animate_refresh: Number of seconds
     23    between the addition of characters
     24    when 'animate' is True."""
     25    clear()
     26    string = str(string)
     27    width = get_terminal_size().columns
     28    string = string[: width - 2]
     29    if animate:
     30        for i in range(len(string)):
     31            print(f"{string[:i+1]}", flush=True, end=" \r")
     32            sleep(animate_refresh)
     33    else:
     34        print(string, flush=True, end="\r")
     35
     36
     37def ticker(info: list[str]):
     38    """Prints info to terminal with
     39    top and bottom padding so that repeated
     40    calls print info without showing previous
     41    outputs from ticker calls.
     42
     43    Similar visually to print_in_place,
     44    but for multiple lines."""
     45    width = get_terminal_size().columns
     46    info = [str(line)[: width - 1] for line in info]
     47    height = get_terminal_size().lines - len(info)
     48    print("\n" * (height * 2), end="")
     49    print(*info, sep="\n", end="")
     50    print("\n" * (int((height) / 2)), end="")
     51
     52
     53class ProgBar:
     54    """Self incrementing, dynamically sized progress bar.
     55
     56    Includes a Timer object from noiftimer that starts timing
     57    on the first call to display and stops timing once
     58    self.counter >= self.total.
     59    It can be easily added to the progress bar display by calling
     60    Timer's checkTime function and passing the value to the 'prefix' or 'suffix'
     61    param of self.display():
     62
     63    bar = ProgBar(total=someTotal)
     64    bar.display(prefix=f"Run time: {bar.timer.checkTime()}")"""
     65
     66    def __init__(
     67        self,
     68        total: float,
     69        fill_ch: str = "_",
     70        unfill_ch: str = "/",
     71        width_ratio: float = 0.75,
     72        new_line_after_completion: bool = True,
     73        clear_after_completion: bool = False,
     74    ):
     75        """:param total: The number of calls to reach 100% completion.
     76
     77        :param fill_ch: The character used to represent the completed part of the bar.
     78
     79        :param unfill_ch: The character used to represent the uncompleted part of the bar.
     80
     81        :param width_ratio: The width of the progress bar relative to the width of the terminal window.
     82
     83        :param new_line_after_completion: Make a call to print() once self.counter >= self.total.
     84
     85        :param clear_after_completion: Make a call to printbuddies.clear() once self.counter >= self.total.
     86
     87        Note: if new_line_after_completion and clear_after_completion are both True, the line will be cleared
     88        then a call to print() will be made."""
     89        self.total = total
     90        self.fill_ch = fill_ch[0]
     91        self.unfill_ch = unfill_ch[0]
     92        self.width_ratio = width_ratio
     93        self.new_line_after_completion = new_line_after_completion
     94        self.clear_after_completion = clear_after_completion
     95        self.timer = Timer()
     96        self.reset()
     97
     98    def reset(self):
     99        self.counter = 0
    100        self.percent = ""
    101        self.prefix = ""
    102        self.suffix = ""
    103        self.filled = ""
    104        self.unfilled = ""
    105        self.bar = ""
    106
    107    def get_percent(self) -> str:
    108        """Returns the percentage complete to two decimal places
    109        as a string without the %."""
    110        percent = str(round(100.0 * self.counter / self.total, 2))
    111        if len(percent.split(".")[1]) == 1:
    112            percent = percent + "0"
    113        if len(percent.split(".")[0]) == 1:
    114            percent = "0" + percent
    115        return percent
    116
    117    def _prepare_bar(self):
    118        self.terminal_width = get_terminal_size().columns - 1
    119        bar_length = int(self.terminal_width * self.width_ratio)
    120        progress = int(bar_length * self.counter / self.total)
    121        self.filled = self.fill_ch * progress
    122        self.unfilled = self.unfill_ch * (bar_length - progress)
    123        self.percent = self.get_percent()
    124        self.bar = self.get_bar()
    125
    126    def _trim_bar(self):
    127        original_width = self.width_ratio
    128        while len(self.bar) > self.terminal_width and self.width_ratio > 0:
    129            self.width_ratio -= 0.01
    130            self._prepare_bar()
    131        self.width_ratio = original_width
    132
    133    def get_bar(self):
    134        return f"{self.prefix} [{self.filled}{self.unfilled}]-{self.percent}% {self.suffix}"
    135
    136    def display(
    137        self,
    138        prefix: str = "",
    139        suffix: str = "",
    140        counter_override: float = None,
    141        total_override: float = None,
    142        return_object: Any = None,
    143    ) -> Any:
    144        """Writes the progress bar to the terminal.
    145
    146        :param prefix: String affixed to the front of the progress bar.
    147
    148        :param suffix: String appended to the end of the progress bar.
    149
    150        :param counter_override: When an externally incremented completion counter is needed.
    151
    152        :param total_override: When an externally controlled bar total is needed.
    153
    154        :param return_object: An object to be returned by display().
    155
    156        Allows display() to be called within a comprehension:
    157
    158        e.g.
    159
    160        bar = ProgBar(9)
    161
    162        myList = [bar.display(return_object=i) for i in range(10)]"""
    163        if not self.timer.started:
    164            self.timer.start()
    165        if counter_override is not None:
    166            self.counter = counter_override
    167        if total_override:
    168            self.total = total_override
    169        # Don't wanna divide by 0 there, pal
    170        while self.total <= 0:
    171            self.total += 1
    172        self.prefix = prefix
    173        self.suffix = suffix
    174        self._prepare_bar()
    175        self._trim_bar()
    176        pad = " " * (self.terminal_width - len(self.bar))
    177        width = get_terminal_size().columns
    178        print(f"{self.bar}{pad}"[: width - 2], flush=True, end="\r")
    179        if self.counter >= self.total:
    180            self.timer.stop()
    181            if self.clear_after_completion:
    182                clear()
    183            if self.new_line_after_completion:
    184                print()
    185        self.counter += 1
    186        return return_object

def clear(): View Source

     9def clear():
    10    """Erase the current line from the terminal."""
    11    print(" " * (get_terminal_size().columns - 1), flush=True, end="\r")

Erase the current line from the terminal.

def print_in_place(string: str, animate: bool = False, animate_refresh: float = 0.01): View Source

    14def print_in_place(string: str, animate: bool = False, animate_refresh: float = 0.01):
    15    """Calls to print_in_place will overwrite
    16    the previous line of text in the terminal
    17    with the 'string' param.
    18
    19    :param animate: Will cause the string
    20    to be printed to the terminal
    21    one character at a time.
    22
    23    :param animate_refresh: Number of seconds
    24    between the addition of characters
    25    when 'animate' is True."""
    26    clear()
    27    string = str(string)
    28    width = get_terminal_size().columns
    29    string = string[: width - 2]
    30    if animate:
    31        for i in range(len(string)):
    32            print(f"{string[:i+1]}", flush=True, end=" \r")
    33            sleep(animate_refresh)
    34    else:
    35        print(string, flush=True, end="\r")

Calls to print_in_place will overwrite the previous line of text in the terminal with the 'string' param.

###### Parameters

- animate: Will cause the string to be printed to the terminal one character at a time.

- animate_refresh: Number of seconds between the addition of characters when 'animate' is True.

def ticker(info: list[str]): View Source

    38def ticker(info: list[str]):
    39    """Prints info to terminal with
    40    top and bottom padding so that repeated
    41    calls print info without showing previous
    42    outputs from ticker calls.
    43
    44    Similar visually to print_in_place,
    45    but for multiple lines."""
    46    width = get_terminal_size().columns
    47    info = [str(line)[: width - 1] for line in info]
    48    height = get_terminal_size().lines - len(info)
    49    print("\n" * (height * 2), end="")
    50    print(*info, sep="\n", end="")
    51    print("\n" * (int((height) / 2)), end="")

Prints info to terminal with top and bottom padding so that repeated calls print info without showing previous outputs from ticker calls.

Similar visually to print_in_place, but for multiple lines.

class ProgBar: View Source

     54class ProgBar:
     55    """Self incrementing, dynamically sized progress bar.
     56
     57    Includes a Timer object from noiftimer that starts timing
     58    on the first call to display and stops timing once
     59    self.counter >= self.total.
     60    It can be easily added to the progress bar display by calling
     61    Timer's checkTime function and passing the value to the 'prefix' or 'suffix'
     62    param of self.display():
     63
     64    bar = ProgBar(total=someTotal)
     65    bar.display(prefix=f"Run time: {bar.timer.checkTime()}")"""
     66
     67    def __init__(
     68        self,
     69        total: float,
     70        fill_ch: str = "_",
     71        unfill_ch: str = "/",
     72        width_ratio: float = 0.75,
     73        new_line_after_completion: bool = True,
     74        clear_after_completion: bool = False,
     75    ):
     76        """:param total: The number of calls to reach 100% completion.
     77
     78        :param fill_ch: The character used to represent the completed part of the bar.
     79
     80        :param unfill_ch: The character used to represent the uncompleted part of the bar.
     81
     82        :param width_ratio: The width of the progress bar relative to the width of the terminal window.
     83
     84        :param new_line_after_completion: Make a call to print() once self.counter >= self.total.
     85
     86        :param clear_after_completion: Make a call to printbuddies.clear() once self.counter >= self.total.
     87
     88        Note: if new_line_after_completion and clear_after_completion are both True, the line will be cleared
     89        then a call to print() will be made."""
     90        self.total = total
     91        self.fill_ch = fill_ch[0]
     92        self.unfill_ch = unfill_ch[0]
     93        self.width_ratio = width_ratio
     94        self.new_line_after_completion = new_line_after_completion
     95        self.clear_after_completion = clear_after_completion
     96        self.timer = Timer()
     97        self.reset()
     98
     99    def reset(self):
    100        self.counter = 0
    101        self.percent = ""
    102        self.prefix = ""
    103        self.suffix = ""
    104        self.filled = ""
    105        self.unfilled = ""
    106        self.bar = ""
    107
    108    def get_percent(self) -> str:
    109        """Returns the percentage complete to two decimal places
    110        as a string without the %."""
    111        percent = str(round(100.0 * self.counter / self.total, 2))
    112        if len(percent.split(".")[1]) == 1:
    113            percent = percent + "0"
    114        if len(percent.split(".")[0]) == 1:
    115            percent = "0" + percent
    116        return percent
    117
    118    def _prepare_bar(self):
    119        self.terminal_width = get_terminal_size().columns - 1
    120        bar_length = int(self.terminal_width * self.width_ratio)
    121        progress = int(bar_length * self.counter / self.total)
    122        self.filled = self.fill_ch * progress
    123        self.unfilled = self.unfill_ch * (bar_length - progress)
    124        self.percent = self.get_percent()
    125        self.bar = self.get_bar()
    126
    127    def _trim_bar(self):
    128        original_width = self.width_ratio
    129        while len(self.bar) > self.terminal_width and self.width_ratio > 0:
    130            self.width_ratio -= 0.01
    131            self._prepare_bar()
    132        self.width_ratio = original_width
    133
    134    def get_bar(self):
    135        return f"{self.prefix} [{self.filled}{self.unfilled}]-{self.percent}% {self.suffix}"
    136
    137    def display(
    138        self,
    139        prefix: str = "",
    140        suffix: str = "",
    141        counter_override: float = None,
    142        total_override: float = None,
    143        return_object: Any = None,
    144    ) -> Any:
    145        """Writes the progress bar to the terminal.
    146
    147        :param prefix: String affixed to the front of the progress bar.
    148
    149        :param suffix: String appended to the end of the progress bar.
    150
    151        :param counter_override: When an externally incremented completion counter is needed.
    152
    153        :param total_override: When an externally controlled bar total is needed.
    154
    155        :param return_object: An object to be returned by display().
    156
    157        Allows display() to be called within a comprehension:
    158
    159        e.g.
    160
    161        bar = ProgBar(9)
    162
    163        myList = [bar.display(return_object=i) for i in range(10)]"""
    164        if not self.timer.started:
    165            self.timer.start()
    166        if counter_override is not None:
    167            self.counter = counter_override
    168        if total_override:
    169            self.total = total_override
    170        # Don't wanna divide by 0 there, pal
    171        while self.total <= 0:
    172            self.total += 1
    173        self.prefix = prefix
    174        self.suffix = suffix
    175        self._prepare_bar()
    176        self._trim_bar()
    177        pad = " " * (self.terminal_width - len(self.bar))
    178        width = get_terminal_size().columns
    179        print(f"{self.bar}{pad}"[: width - 2], flush=True, end="\r")
    180        if self.counter >= self.total:
    181            self.timer.stop()
    182            if self.clear_after_completion:
    183                clear()
    184            if self.new_line_after_completion:
    185                print()
    186        self.counter += 1
    187        return return_object

Self incrementing, dynamically sized progress bar.

Includes a Timer object from noiftimer that starts timing on the first call to display and stops timing once self.counter >= self.total. It can be easily added to the progress bar display by calling Timer's checkTime function and passing the value to the 'prefix' or 'suffix' param of self.display():

bar = ProgBar(total=someTotal) bar.display(prefix=f"Run time: {bar.timer.checkTime()}")

ProgBar( total: float, fill_ch: str = '_', unfill_ch: str = '/', width_ratio: float = 0.75, new_line_after_completion: bool = True, clear_after_completion: bool = False) View Source

    67    def __init__(
    68        self,
    69        total: float,
    70        fill_ch: str = "_",
    71        unfill_ch: str = "/",
    72        width_ratio: float = 0.75,
    73        new_line_after_completion: bool = True,
    74        clear_after_completion: bool = False,
    75    ):
    76        """:param total: The number of calls to reach 100% completion.
    77
    78        :param fill_ch: The character used to represent the completed part of the bar.
    79
    80        :param unfill_ch: The character used to represent the uncompleted part of the bar.
    81
    82        :param width_ratio: The width of the progress bar relative to the width of the terminal window.
    83
    84        :param new_line_after_completion: Make a call to print() once self.counter >= self.total.
    85
    86        :param clear_after_completion: Make a call to printbuddies.clear() once self.counter >= self.total.
    87
    88        Note: if new_line_after_completion and clear_after_completion are both True, the line will be cleared
    89        then a call to print() will be made."""
    90        self.total = total
    91        self.fill_ch = fill_ch[0]
    92        self.unfill_ch = unfill_ch[0]
    93        self.width_ratio = width_ratio
    94        self.new_line_after_completion = new_line_after_completion
    95        self.clear_after_completion = clear_after_completion
    96        self.timer = Timer()
    97        self.reset()

###### Parameters

- total: The number of calls to reach 100% completion.

- fill_ch: The character used to represent the completed part of the bar.

- unfill_ch: The character used to represent the uncompleted part of the bar.

- width_ratio: The width of the progress bar relative to the width of the terminal window.

- new_line_after_completion: Make a call to print() once self.counter >= self.total.

- clear_after_completion: Make a call to printbuddies.clear() once self.counter >= self.total.

Note: if new_line_after_completion and clear_after_completion are both True, the line will be cleared then a call to print() will be made.

def reset(self): View Source

     99    def reset(self):
    100        self.counter = 0
    101        self.percent = ""
    102        self.prefix = ""
    103        self.suffix = ""
    104        self.filled = ""
    105        self.unfilled = ""
    106        self.bar = ""

def get_percent(self) -> str: View Source

    108    def get_percent(self) -> str:
    109        """Returns the percentage complete to two decimal places
    110        as a string without the %."""
    111        percent = str(round(100.0 * self.counter / self.total, 2))
    112        if len(percent.split(".")[1]) == 1:
    113            percent = percent + "0"
    114        if len(percent.split(".")[0]) == 1:
    115            percent = "0" + percent
    116        return percent

Returns the percentage complete to two decimal places as a string without the %.

def get_bar(self): View Source

    134    def get_bar(self):
    135        return f"{self.prefix} [{self.filled}{self.unfilled}]-{self.percent}% {self.suffix}"

def display( self, prefix: str = '', suffix: str = '', counter_override: float = None, total_override: float = None, return_object: Any = None) -> Any: View Source

    137    def display(
    138        self,
    139        prefix: str = "",
    140        suffix: str = "",
    141        counter_override: float = None,
    142        total_override: float = None,
    143        return_object: Any = None,
    144    ) -> Any:
    145        """Writes the progress bar to the terminal.
    146
    147        :param prefix: String affixed to the front of the progress bar.
    148
    149        :param suffix: String appended to the end of the progress bar.
    150
    151        :param counter_override: When an externally incremented completion counter is needed.
    152
    153        :param total_override: When an externally controlled bar total is needed.
    154
    155        :param return_object: An object to be returned by display().
    156
    157        Allows display() to be called within a comprehension:
    158
    159        e.g.
    160
    161        bar = ProgBar(9)
    162
    163        myList = [bar.display(return_object=i) for i in range(10)]"""
    164        if not self.timer.started:
    165            self.timer.start()
    166        if counter_override is not None:
    167            self.counter = counter_override
    168        if total_override:
    169            self.total = total_override
    170        # Don't wanna divide by 0 there, pal
    171        while self.total <= 0:
    172            self.total += 1
    173        self.prefix = prefix
    174        self.suffix = suffix
    175        self._prepare_bar()
    176        self._trim_bar()
    177        pad = " " * (self.terminal_width - len(self.bar))
    178        width = get_terminal_size().columns
    179        print(f"{self.bar}{pad}"[: width - 2], flush=True, end="\r")
    180        if self.counter >= self.total:
    181            self.timer.stop()
    182            if self.clear_after_completion:
    183                clear()
    184            if self.new_line_after_completion:
    185                print()
    186        self.counter += 1
    187        return return_object

Writes the progress bar to the terminal.

###### Parameters

- prefix: String affixed to the front of the progress bar.

- suffix: String appended to the end of the progress bar.

- counter_override: When an externally incremented completion counter is needed.

- total_override: When an externally controlled bar total is needed.

- return_object: An object to be returned by display().

Allows display() to be called within a comprehension:

e.g.

bar = ProgBar(9)

myList = [bar.display(return_object=i) for i in range(10)]