printbuddies.printbuddies

  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 an internal timer that starts when this object is created.
 57    It can be easily added to the progress bar display by adding
 58    the 'runtime' property to display's prefix or suffix param:
 59
 60    >>> bar = ProgBar(total=100)
 61    >>> time.sleep(30)
 62    >>> bar.display(prefix=bar.runtime)
 63    >>> "runtime: 30s [_///////////////////]1.00%" """
 64
 65    def __init__(
 66        self,
 67        total: float,
 68        update_frequency: int = 1,
 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 update_frequency: The progress bar will only update once every this number of calls to display().
 78        The larger the value, the less performance impact ProgBar has on the loop in which it is called.
 79        e.g.
 80        >>> bar = ProgBar(100, update_frequency=10)
 81        >>> for _ in range(100):
 82        >>>     bar.display()
 83
 84        ^The progress bar in the terminal will only update once every ten calls, going from 0%->100% in 10% increments.
 85        Note: If 'total' is not a multiple of 'update_frequency', the display will not show 100% completion when the loop finishes.
 86
 87        :param fill_ch: The character used to represent the completed part of the bar.
 88
 89        :param unfill_ch: The character used to represent the uncompleted part of the bar.
 90
 91        :param width_ratio: The width of the progress bar relative to the width of the terminal window.
 92
 93        :param new_line_after_completion: Make a call to print() once self.counter >= self.total.
 94
 95        :param clear_after_completion: Make a call to printbuddies.clear() once self.counter >= self.total.
 96
 97        Note: if new_line_after_completion and clear_after_completion are both True, the line will be cleared
 98        then a call to print() will be made."""
 99        self.total = total
100        self.update_frequency = update_frequency
101        self.fill_ch = fill_ch[0]
102        self.unfill_ch = unfill_ch[0]
103        self.width_ratio = width_ratio
104        self.new_line_after_completion = new_line_after_completion
105        self.clear_after_completion = clear_after_completion
106        self.reset()
107        self.with_context = False
108
109    def __enter__(self):
110        self.with_context = True
111        return self
112
113    def __exit__(self, *args, **kwargs):
114        if self.clear_after_completion:
115            clear()
116        else:
117            print()
118
119    def reset(self):
120        self.counter = 1
121        self.percent = ""
122        self.prefix = ""
123        self.suffix = ""
124        self.filled = ""
125        self.unfilled = ""
126        self.bar = ""
127        self.timer = Timer(subsecond_resolution=False).start()
128
129    @property
130    def runtime(self) -> str:
131        return f"runtime:{self.timer.elapsed_str}"
132
133    def get_percent(self) -> str:
134        """Returns the percentage complete to two decimal places
135        as a string without the %."""
136        percent = str(round(100.0 * self.counter / self.total, 2))
137        if len(percent.split(".")[1]) == 1:
138            percent = percent + "0"
139        if len(percent.split(".")[0]) == 1:
140            percent = "0" + percent
141        return percent
142
143    def _prepare_bar(self):
144        self.terminal_width = get_terminal_size().columns - 1
145        bar_length = int(self.terminal_width * self.width_ratio)
146        progress = int(bar_length * min(self.counter / self.total, 1.0))
147        self.filled = self.fill_ch * progress
148        self.unfilled = self.unfill_ch * (bar_length - progress)
149        self.percent = self.get_percent()
150        self.bar = self.get_bar()
151
152    def _trim_bar(self):
153        original_width = self.width_ratio
154        while len(self.bar) > self.terminal_width and self.width_ratio > 0:
155            self.width_ratio -= 0.01
156            self._prepare_bar()
157        self.width_ratio = original_width
158
159    def get_bar(self):
160        return f"{self.prefix}{' '*bool(self.prefix)}[{self.filled}{self.unfilled}]-{self.percent}% {self.suffix}"
161
162    def display(
163        self,
164        prefix: str = "",
165        suffix: str = "",
166        counter_override: float | None = None,
167        total_override: float | None = None,
168        return_object: Any | None = None,
169    ) -> Any:
170        """Writes the progress bar to the terminal.
171
172        :param prefix: String affixed to the front of the progress bar.
173
174        :param suffix: String appended to the end of the progress bar.
175
176        :param counter_override: When an externally incremented completion counter is needed.
177
178        :param total_override: When an externally controlled bar total is needed.
179
180        :param return_object: An object to be returned by display().
181
182        Allows display() to be called within a comprehension:
183
184        e.g.
185
186        >>> bar = ProgBar(10)
187        >>> def square(x: int | float)->int|float:
188        >>>     return x * x
189        >>> myList = [bar.display(return_object=square(i)) for i in range(10)]
190        >>> <progress bar gets displayed>
191        >>> myList
192        >>> [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]"""
193        if not self.timer.started:
194            self.timer.start()
195        if counter_override is not None:
196            self.counter = counter_override
197        if total_override:
198            self.total = total_override
199        # Don't wanna divide by 0 there, pal
200        while self.total <= 0:
201            self.total += 1
202        if self.counter % self.update_frequency == 0:
203            self.prefix = prefix
204            self.suffix = suffix
205            self._prepare_bar()
206            self._trim_bar()
207            pad = " " * (self.terminal_width - len(self.bar))
208            width = get_terminal_size().columns
209            print(f"{self.bar}{pad}"[: width - 2], flush=True, end="\r")
210        if self.counter >= self.total:
211            self.timer.stop()
212            if not self.with_context:
213                if self.clear_after_completion:
214                    clear()
215                if self.new_line_after_completion:
216                    print()
217        self.counter += 1
218        return return_object
219
220
221class Spinner:
222    """Prints one of a sequence of characters in order everytime display() is called.
223
224    The display function writes the new character to the same line, overwriting the previous character.
225
226    The sequence will be cycled through indefinitely.
227
228    If used as a context manager, the last printed character will be cleared upon exiting.
229    """
230
231    def __init__(
232        self, sequence: list[str] = ["/", "-", "\\"], width_ratio: float = 0.25
233    ):
234        """
235        :param sequence: Override the built in spin sequence.
236
237        :param width: The fractional amount of the terminal for characters to move across."""
238        self._base_sequence = sequence
239        self.width_ratio = width_ratio
240        self.sequence = self._base_sequence
241
242    def __enter__(self):
243        return self
244
245    def __exit__(self, *args, **kwargs):
246        clear()
247
248    @property
249    def width_ratio(self) -> float:
250        return self._width_ratio
251
252    @width_ratio.setter
253    def width_ratio(self, ratio: float):
254        self._width_ratio = ratio
255        self._update_width()
256
257    def _update_width(self):
258        self._current_terminal_width = get_terminal_size().columns
259        self._width = int((self._current_terminal_width - 1) * self.width_ratio)
260
261    @property
262    def sequence(self) -> list[Any]:
263        return self._sequence
264
265    @sequence.setter
266    def sequence(self, character_list: list[Any]):
267        self._sequence = [
268            ch.rjust(i + j)
269            for i in range(1, self._width, len(character_list))
270            for j, ch in enumerate(character_list)
271        ]
272        self._sequence += self._sequence[::-1]
273
274    def _get_next(self) -> str:
275        """Pop the first element of self._sequence, append it to the end, and return the element."""
276        ch = self.sequence.pop(0)
277        self.sequence.append(ch)
278        return ch
279
280    def display(self):
281        """Print the next character in the sequence."""
282        if get_terminal_size().columns != self._current_terminal_width:
283            self._update_width()
284            self.sequence = self._base_sequence
285        print_in_place(self._get_next())
def clear():
 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 ticker(info: list[str]):
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:
 54class ProgBar:
 55    """Self incrementing, dynamically sized progress bar.
 56
 57    Includes an internal timer that starts when this object is created.
 58    It can be easily added to the progress bar display by adding
 59    the 'runtime' property to display's prefix or suffix param:
 60
 61    >>> bar = ProgBar(total=100)
 62    >>> time.sleep(30)
 63    >>> bar.display(prefix=bar.runtime)
 64    >>> "runtime: 30s [_///////////////////]1.00%" """
 65
 66    def __init__(
 67        self,
 68        total: float,
 69        update_frequency: int = 1,
 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 update_frequency: The progress bar will only update once every this number of calls to display().
 79        The larger the value, the less performance impact ProgBar has on the loop in which it is called.
 80        e.g.
 81        >>> bar = ProgBar(100, update_frequency=10)
 82        >>> for _ in range(100):
 83        >>>     bar.display()
 84
 85        ^The progress bar in the terminal will only update once every ten calls, going from 0%->100% in 10% increments.
 86        Note: If 'total' is not a multiple of 'update_frequency', the display will not show 100% completion when the loop finishes.
 87
 88        :param fill_ch: The character used to represent the completed part of the bar.
 89
 90        :param unfill_ch: The character used to represent the uncompleted part of the bar.
 91
 92        :param width_ratio: The width of the progress bar relative to the width of the terminal window.
 93
 94        :param new_line_after_completion: Make a call to print() once self.counter >= self.total.
 95
 96        :param clear_after_completion: Make a call to printbuddies.clear() once self.counter >= self.total.
 97
 98        Note: if new_line_after_completion and clear_after_completion are both True, the line will be cleared
 99        then a call to print() will be made."""
100        self.total = total
101        self.update_frequency = update_frequency
102        self.fill_ch = fill_ch[0]
103        self.unfill_ch = unfill_ch[0]
104        self.width_ratio = width_ratio
105        self.new_line_after_completion = new_line_after_completion
106        self.clear_after_completion = clear_after_completion
107        self.reset()
108        self.with_context = False
109
110    def __enter__(self):
111        self.with_context = True
112        return self
113
114    def __exit__(self, *args, **kwargs):
115        if self.clear_after_completion:
116            clear()
117        else:
118            print()
119
120    def reset(self):
121        self.counter = 1
122        self.percent = ""
123        self.prefix = ""
124        self.suffix = ""
125        self.filled = ""
126        self.unfilled = ""
127        self.bar = ""
128        self.timer = Timer(subsecond_resolution=False).start()
129
130    @property
131    def runtime(self) -> str:
132        return f"runtime:{self.timer.elapsed_str}"
133
134    def get_percent(self) -> str:
135        """Returns the percentage complete to two decimal places
136        as a string without the %."""
137        percent = str(round(100.0 * self.counter / self.total, 2))
138        if len(percent.split(".")[1]) == 1:
139            percent = percent + "0"
140        if len(percent.split(".")[0]) == 1:
141            percent = "0" + percent
142        return percent
143
144    def _prepare_bar(self):
145        self.terminal_width = get_terminal_size().columns - 1
146        bar_length = int(self.terminal_width * self.width_ratio)
147        progress = int(bar_length * min(self.counter / self.total, 1.0))
148        self.filled = self.fill_ch * progress
149        self.unfilled = self.unfill_ch * (bar_length - progress)
150        self.percent = self.get_percent()
151        self.bar = self.get_bar()
152
153    def _trim_bar(self):
154        original_width = self.width_ratio
155        while len(self.bar) > self.terminal_width and self.width_ratio > 0:
156            self.width_ratio -= 0.01
157            self._prepare_bar()
158        self.width_ratio = original_width
159
160    def get_bar(self):
161        return f"{self.prefix}{' '*bool(self.prefix)}[{self.filled}{self.unfilled}]-{self.percent}% {self.suffix}"
162
163    def display(
164        self,
165        prefix: str = "",
166        suffix: str = "",
167        counter_override: float | None = None,
168        total_override: float | None = None,
169        return_object: Any | None = None,
170    ) -> Any:
171        """Writes the progress bar to the terminal.
172
173        :param prefix: String affixed to the front of the progress bar.
174
175        :param suffix: String appended to the end of the progress bar.
176
177        :param counter_override: When an externally incremented completion counter is needed.
178
179        :param total_override: When an externally controlled bar total is needed.
180
181        :param return_object: An object to be returned by display().
182
183        Allows display() to be called within a comprehension:
184
185        e.g.
186
187        >>> bar = ProgBar(10)
188        >>> def square(x: int | float)->int|float:
189        >>>     return x * x
190        >>> myList = [bar.display(return_object=square(i)) for i in range(10)]
191        >>> <progress bar gets displayed>
192        >>> myList
193        >>> [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]"""
194        if not self.timer.started:
195            self.timer.start()
196        if counter_override is not None:
197            self.counter = counter_override
198        if total_override:
199            self.total = total_override
200        # Don't wanna divide by 0 there, pal
201        while self.total <= 0:
202            self.total += 1
203        if self.counter % self.update_frequency == 0:
204            self.prefix = prefix
205            self.suffix = suffix
206            self._prepare_bar()
207            self._trim_bar()
208            pad = " " * (self.terminal_width - len(self.bar))
209            width = get_terminal_size().columns
210            print(f"{self.bar}{pad}"[: width - 2], flush=True, end="\r")
211        if self.counter >= self.total:
212            self.timer.stop()
213            if not self.with_context:
214                if self.clear_after_completion:
215                    clear()
216                if self.new_line_after_completion:
217                    print()
218        self.counter += 1
219        return return_object

Self incrementing, dynamically sized progress bar.

Includes an internal timer that starts when this object is created. It can be easily added to the progress bar display by adding the 'runtime' property to display's prefix or suffix param:

>>> bar = ProgBar(total=100)
>>> time.sleep(30)
>>> bar.display(prefix=bar.runtime)
>>> "runtime: 30s [_///////////////////]1.00%"
ProgBar( total: float, update_frequency: int = 1, fill_ch: str = '_', unfill_ch: str = '/', width_ratio: float = 0.75, new_line_after_completion: bool = True, clear_after_completion: bool = False)
 66    def __init__(
 67        self,
 68        total: float,
 69        update_frequency: int = 1,
 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 update_frequency: The progress bar will only update once every this number of calls to display().
 79        The larger the value, the less performance impact ProgBar has on the loop in which it is called.
 80        e.g.
 81        >>> bar = ProgBar(100, update_frequency=10)
 82        >>> for _ in range(100):
 83        >>>     bar.display()
 84
 85        ^The progress bar in the terminal will only update once every ten calls, going from 0%->100% in 10% increments.
 86        Note: If 'total' is not a multiple of 'update_frequency', the display will not show 100% completion when the loop finishes.
 87
 88        :param fill_ch: The character used to represent the completed part of the bar.
 89
 90        :param unfill_ch: The character used to represent the uncompleted part of the bar.
 91
 92        :param width_ratio: The width of the progress bar relative to the width of the terminal window.
 93
 94        :param new_line_after_completion: Make a call to print() once self.counter >= self.total.
 95
 96        :param clear_after_completion: Make a call to printbuddies.clear() once self.counter >= self.total.
 97
 98        Note: if new_line_after_completion and clear_after_completion are both True, the line will be cleared
 99        then a call to print() will be made."""
100        self.total = total
101        self.update_frequency = update_frequency
102        self.fill_ch = fill_ch[0]
103        self.unfill_ch = unfill_ch[0]
104        self.width_ratio = width_ratio
105        self.new_line_after_completion = new_line_after_completion
106        self.clear_after_completion = clear_after_completion
107        self.reset()
108        self.with_context = False
Parameters
  • total: The number of calls to reach 100% completion.

  • update_frequency: The progress bar will only update once every this number of calls to display(). The larger the value, the less performance impact ProgBar has on the loop in which it is called. e.g.

    >>> bar = ProgBar(100, update_frequency=10)
    >>> for _ in range(100):
    >>>     bar.display()
    

^The progress bar in the terminal will only update once every ten calls, going from 0%->100% in 10% increments. Note: If 'total' is not a multiple of 'update_frequency', the display will not show 100% completion when the loop finishes.

  • 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):
120    def reset(self):
121        self.counter = 1
122        self.percent = ""
123        self.prefix = ""
124        self.suffix = ""
125        self.filled = ""
126        self.unfilled = ""
127        self.bar = ""
128        self.timer = Timer(subsecond_resolution=False).start()
def get_percent(self) -> str:
134    def get_percent(self) -> str:
135        """Returns the percentage complete to two decimal places
136        as a string without the %."""
137        percent = str(round(100.0 * self.counter / self.total, 2))
138        if len(percent.split(".")[1]) == 1:
139            percent = percent + "0"
140        if len(percent.split(".")[0]) == 1:
141            percent = "0" + percent
142        return percent

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

def get_bar(self):
160    def get_bar(self):
161        return f"{self.prefix}{' '*bool(self.prefix)}[{self.filled}{self.unfilled}]-{self.percent}% {self.suffix}"
def display( self, prefix: str = '', suffix: str = '', counter_override: float | None = None, total_override: float | None = None, return_object: typing.Any | None = None) -> Any:
163    def display(
164        self,
165        prefix: str = "",
166        suffix: str = "",
167        counter_override: float | None = None,
168        total_override: float | None = None,
169        return_object: Any | None = None,
170    ) -> Any:
171        """Writes the progress bar to the terminal.
172
173        :param prefix: String affixed to the front of the progress bar.
174
175        :param suffix: String appended to the end of the progress bar.
176
177        :param counter_override: When an externally incremented completion counter is needed.
178
179        :param total_override: When an externally controlled bar total is needed.
180
181        :param return_object: An object to be returned by display().
182
183        Allows display() to be called within a comprehension:
184
185        e.g.
186
187        >>> bar = ProgBar(10)
188        >>> def square(x: int | float)->int|float:
189        >>>     return x * x
190        >>> myList = [bar.display(return_object=square(i)) for i in range(10)]
191        >>> <progress bar gets displayed>
192        >>> myList
193        >>> [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]"""
194        if not self.timer.started:
195            self.timer.start()
196        if counter_override is not None:
197            self.counter = counter_override
198        if total_override:
199            self.total = total_override
200        # Don't wanna divide by 0 there, pal
201        while self.total <= 0:
202            self.total += 1
203        if self.counter % self.update_frequency == 0:
204            self.prefix = prefix
205            self.suffix = suffix
206            self._prepare_bar()
207            self._trim_bar()
208            pad = " " * (self.terminal_width - len(self.bar))
209            width = get_terminal_size().columns
210            print(f"{self.bar}{pad}"[: width - 2], flush=True, end="\r")
211        if self.counter >= self.total:
212            self.timer.stop()
213            if not self.with_context:
214                if self.clear_after_completion:
215                    clear()
216                if self.new_line_after_completion:
217                    print()
218        self.counter += 1
219        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(10)
>>> def square(x: int | float)->int|float:
>>>     return x * x
>>> myList = [bar.display(return_object=square(i)) for i in range(10)]
>>> <progress bar gets displayed>
>>> myList
>>> [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
class Spinner:
222class Spinner:
223    """Prints one of a sequence of characters in order everytime display() is called.
224
225    The display function writes the new character to the same line, overwriting the previous character.
226
227    The sequence will be cycled through indefinitely.
228
229    If used as a context manager, the last printed character will be cleared upon exiting.
230    """
231
232    def __init__(
233        self, sequence: list[str] = ["/", "-", "\\"], width_ratio: float = 0.25
234    ):
235        """
236        :param sequence: Override the built in spin sequence.
237
238        :param width: The fractional amount of the terminal for characters to move across."""
239        self._base_sequence = sequence
240        self.width_ratio = width_ratio
241        self.sequence = self._base_sequence
242
243    def __enter__(self):
244        return self
245
246    def __exit__(self, *args, **kwargs):
247        clear()
248
249    @property
250    def width_ratio(self) -> float:
251        return self._width_ratio
252
253    @width_ratio.setter
254    def width_ratio(self, ratio: float):
255        self._width_ratio = ratio
256        self._update_width()
257
258    def _update_width(self):
259        self._current_terminal_width = get_terminal_size().columns
260        self._width = int((self._current_terminal_width - 1) * self.width_ratio)
261
262    @property
263    def sequence(self) -> list[Any]:
264        return self._sequence
265
266    @sequence.setter
267    def sequence(self, character_list: list[Any]):
268        self._sequence = [
269            ch.rjust(i + j)
270            for i in range(1, self._width, len(character_list))
271            for j, ch in enumerate(character_list)
272        ]
273        self._sequence += self._sequence[::-1]
274
275    def _get_next(self) -> str:
276        """Pop the first element of self._sequence, append it to the end, and return the element."""
277        ch = self.sequence.pop(0)
278        self.sequence.append(ch)
279        return ch
280
281    def display(self):
282        """Print the next character in the sequence."""
283        if get_terminal_size().columns != self._current_terminal_width:
284            self._update_width()
285            self.sequence = self._base_sequence
286        print_in_place(self._get_next())

Prints one of a sequence of characters in order everytime display() is called.

The display function writes the new character to the same line, overwriting the previous character.

The sequence will be cycled through indefinitely.

If used as a context manager, the last printed character will be cleared upon exiting.

Spinner(sequence: list[str] = ['/', '-', '\\'], width_ratio: float = 0.25)
232    def __init__(
233        self, sequence: list[str] = ["/", "-", "\\"], width_ratio: float = 0.25
234    ):
235        """
236        :param sequence: Override the built in spin sequence.
237
238        :param width: The fractional amount of the terminal for characters to move across."""
239        self._base_sequence = sequence
240        self.width_ratio = width_ratio
241        self.sequence = self._base_sequence
Parameters
  • sequence: Override the built in spin sequence.

  • width: The fractional amount of the terminal for characters to move across.

def display(self):
281    def display(self):
282        """Print the next character in the sequence."""
283        if get_terminal_size().columns != self._current_terminal_width:
284            self._update_width()
285            self.sequence = self._base_sequence
286        print_in_place(self._get_next())

Print the next character in the sequence.