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 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
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.
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.
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.
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()}")
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.
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 %.
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)]