From 36afd597d09a3ae3b1bccdc5943db8cccd6d7d34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lubom=C3=ADr=20Sedl=C3=A1=C5=99?= Date: Thu, 25 May 2023 15:10:49 +0200 Subject: [PATCH 1/2] Add support for custom formatting of progress The default display of count/goal is not great when the progressbar tracks a large number like size of a downloaded file. This attribute allows setting a function that can process the value before it is printed. --- README | 1 + README.md | 1 + README.rst | 1 + cli_progressbar/progressbar.py | 3 ++- 4 files changed, 5 insertions(+), 1 deletion(-) diff --git a/README b/README index 34907fc..e581309 100644 --- a/README +++ b/README @@ -78,6 +78,7 @@ Parameters - ``zfill`` bar zero fill symbol (default: -) - ``decimals`` positive number of decimals in percent complete (default: 1) +- ``formatter`` a function that formats the count and goal, useful for handling large numbers like file sizes Any Questions? Report a Bug? Enhancements? ------------------------------------------ diff --git a/README.md b/README.md index e72a565..58a4a74 100644 --- a/README.md +++ b/README.md @@ -114,6 +114,7 @@ manager.progress_2.stop('stop progress 2') * `fill` bar fill symbol (default: █) * `zfill` bar zero fill symbol (default: -) * `decimals` positive number of decimals in percent complete (default: 1) +* `formatter` a function that formats the count and goal, useful for handling large numbers like file sizes ## Any Questions? Report a Bug? Enhancements? diff --git a/README.rst b/README.rst index 41a131c..544a146 100644 --- a/README.rst +++ b/README.rst @@ -132,6 +132,7 @@ Parameters - ``zfill`` bar zero fill symbol (default: -) - ``decimals`` positive number of decimals in percent complete (default: 1) +- ``formatter`` a function that formats the count and goal, useful for handling large numbers like file sizes Any Questions? Report a Bug? Enhancements? ------------------------------------------ diff --git a/cli_progressbar/progressbar.py b/cli_progressbar/progressbar.py index c3f0699..8d3c34a 100644 --- a/cli_progressbar/progressbar.py +++ b/cli_progressbar/progressbar.py @@ -16,6 +16,7 @@ def __init__(self, goal: int = -1): self.fill = '█' self.zfill = '-' self.decimals = 1 + self.formatter = lambda x: x def set_status(self, status: str): if status == self.status: @@ -32,7 +33,7 @@ def update(self, count: int, status: str = ''): percents = round(100.0 * count / float(self.goal), self.decimals) bar = self.fill * filled_len + self.zfill * (self.bar_len - filled_len) - text = '[%s] %s%s | %s/%s' % (bar, percents, '%', count, self.goal) + text = '[%s] %s%s | %s/%s' % (bar, percents, '%', self.formatter(count), self.formatter(self.goal)) if self.showing_status: text += ' | %s' % self.showing_status From 6a854961ca9efaa4eb15bde4328accb8b30fe07d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lubom=C3=ADr=20Sedl=C3=A1=C5=99?= Date: Thu, 25 May 2023 15:59:08 +0200 Subject: [PATCH 2/2] Ensure line is always emptied While it was possible to get garbage characters before the previous commit by setting goal to a smaller value and reusing the same progressbar, the previous commit made it much more likely. Originally the size part could only grow, but now it can shrink. This commit adds just enough spaces to the printed line to cover up everything from the previous iteration. --- cli_progressbar/progressbar.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/cli_progressbar/progressbar.py b/cli_progressbar/progressbar.py index 8d3c34a..3188502 100644 --- a/cli_progressbar/progressbar.py +++ b/cli_progressbar/progressbar.py @@ -10,20 +10,17 @@ class Progress: def __init__(self, goal: int = -1): self.goal = goal self.status = '' - self.showing_status = '' - self.longest_status = 0 self.bar_len = 60 self.fill = '█' self.zfill = '-' self.decimals = 1 self.formatter = lambda x: x + self.last_len = 0 def set_status(self, status: str): if status == self.status: return self.status = status - self.longest_status = max(len(status), self.longest_status) - self.showing_status = status + ' ' * (self.longest_status - len(status)) def update(self, count: int, status: str = ''): self.set_status(status) @@ -34,8 +31,12 @@ def update(self, count: int, status: str = ''): bar = self.fill * filled_len + self.zfill * (self.bar_len - filled_len) text = '[%s] %s%s | %s/%s' % (bar, percents, '%', self.formatter(count), self.formatter(self.goal)) - if self.showing_status: - text += ' | %s' % self.showing_status + if self.status: + text += ' | %s' % self.status + + padding = ' ' * (self.last_len - len(text)) + self.last_len = len(text) + text += padding pos = getattr(self, 'pos', 0) self.move_to(pos)