Skip to content

Commit 3c64350

Browse files
authored
Merge pull request #10 from soda480/0.2.7
feat: calculate and show duration
2 parents f36fb35 + ec51d9b commit 3c64350

6 files changed

Lines changed: 31 additions & 15 deletions

File tree

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ with ProgressBar(total=75, completed_message=completed_message, clear_alias=True
107107

108108
#### [example3](https://github.com/soda480/progress1bar/tree/master/examples/example3.py)
109109

110-
Configure `ProgressBar` with a non-default ticker, do not use color, and use regular expressions to determine the `total`, `count` and `alias` attributes:
110+
Configure `ProgressBar` with a custom ticker, show duration, do not use color, and use regular expressions to determine the `total`, `count` and `alias` attributes:
111111

112112
<details><summary>Code</summary>
113113

@@ -121,7 +121,7 @@ regex = {
121121
'count': r'^processed .*$',
122122
'alias': r'^processor is (?P<value>.*)$'
123123
}
124-
with ProgressBar(ticker=10148, regex=regex, use_color=False) as pb:
124+
with ProgressBar(ticker=9616, regex=regex, use_color=False, show_duration=True) as pb:
125125
pb.match(f'processor is {names.get_full_name()}')
126126
total = random.randint(500, 1000)
127127
pb.match(f'processing total of {total}')

build.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
authors = [Author('Emilio Reyes', 'soda480@gmail.com')]
1616
summary = 'A simple ANSI-based progress bar'
1717
url = 'https://github.com/soda480/progress1bar'
18-
version = '0.2.6'
18+
version = '0.2.7'
1919
default_task = [
2020
'clean',
2121
'analyze',
@@ -59,7 +59,7 @@ def set_properties(project):
5959
'Topic :: Software Development :: Libraries :: Python Modules',
6060
'Topic :: System :: Networking',
6161
'Topic :: System :: Systems Administration'])
62-
project.set_property('radon_break_build_average_complexity_threshold', 4)
62+
project.set_property('radon_break_build_average_complexity_threshold', 5)
6363
project.set_property('radon_break_build_complexity_threshold', 10)
6464
project.set_property('bandit_break_build', True)
6565
project.set_property('anybadge_exclude', 'coverage, complexity')

docs/images/example3.gif

229 Bytes
Loading

examples/example3.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
'count': r'^processed .*$',
99
'alias': r'^processor is (?P<value>.*)$'
1010
}
11-
with ProgressBar(ticker=10148, regex=regex, use_color=False) as pb:
11+
with ProgressBar(ticker=9616, regex=regex, use_color=False, show_duration=True) as pb:
1212
pb.match(f'processor is {names.get_full_name()}')
1313
total = random.randint(500, 1000)
1414
pb.match(f'processing total of {total}')

src/main/python/progress1bar/progressbar.py

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import re
22
import sys
33
import logging
4-
4+
import datetime
55
import cursor
66
from colorama import Style
77
from colorama import Fore
@@ -34,7 +34,8 @@ def __init__(self, **kwargs):
3434
'show_prefix': True,
3535
'show_fraction': True,
3636
'show_percentage': True,
37-
'use_color': True
37+
'use_color': True,
38+
'show_duration': False
3839
}
3940
for (attribute, default) in defaults.items():
4041
setattr(self, attribute, kwargs.get(attribute, default))
@@ -43,7 +44,8 @@ def __init__(self, **kwargs):
4344
raise ValueError('ticker value not in supported range')
4445
self._ticker = chr(ticker)
4546
# self.complete boolean to track if progress bar has completed
46-
self.complete = False
47+
# self.complete = False
48+
self.__dict__['complete'] = False
4749
# self._completed int to track the number of progress bar completions
4850
# it's typically just 1 but can be multiple when using .reset()
4951
self._completed = 0
@@ -60,6 +62,7 @@ def __init__(self, **kwargs):
6062
# execute after total is set
6163
self._fill = self._get_fill(kwargs.get('fill', {}))
6264
if total:
65+
self._start_time = datetime.datetime.now()
6366
# print progress bar if total specified in constructor
6467
self._print(False)
6568

@@ -92,14 +95,27 @@ def __setattr__(self, name, value):
9295
if name == 'count' and self.total is None:
9396
return
9497
super(ProgressBar, self).__setattr__(name, value)
95-
if name in ['total', 'count']:
98+
if name in ['total', 'count', 'complete']:
9699
if name == 'count':
97100
self._modulus_count = round(round(self.count / self.total, 2) * PROGRESS_WIDTH)
98-
else:
101+
self._print(True)
102+
elif name == 'total':
99103
if not self._fill['total']:
100104
# only set fill for total if is is not set
101105
self._fill['total'] = len(str(value))
102-
self._print(name == 'count')
106+
if value and not self._completed:
107+
# only start the timer once even if reset
108+
self._start_time = datetime.datetime.now()
109+
self._print(False)
110+
else:
111+
if value:
112+
# if complete is true then set stop time and compute duration
113+
self._stop_time = datetime.datetime.now()
114+
start = self._start_time.time().strftime('%H:%M:%S')
115+
stop = self._stop_time.time().strftime('%H:%M:%S')
116+
self.duration = str(datetime.datetime.strptime(stop, '%H:%M:%S') - datetime.datetime.strptime(start, '%H:%M:%S'))
117+
else:
118+
self.duration = None
103119

104120
def __enter__(self):
105121
""" on entry - hide cursor if show and stderr is attached to tty
@@ -193,7 +209,7 @@ def _get_complete(self):
193209
progress = 'Processing complete'
194210
if self.completed_message:
195211
progress = self.completed_message
196-
if self.duration:
212+
if self.duration and self.show_duration:
197213
progress = f'{progress} - {self.duration}'
198214
return progress
199215

src/unittest/python/test_progressbar.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ def test__match_count_ShouldReturnNone_When_NoRegexMatch(self, *patches):
231231
@patch('progress1bar.progressbar.sys.stderr.isatty', return_value=False)
232232
@patch('progress1bar.progressbar.colorama_init')
233233
def test__get_complete_Should_ReturnExpected_When_MessageAndDuration(self, *patches):
234-
pbar = ProgressBar()
234+
pbar = ProgressBar(show_duration=True)
235235
pbar.completed_message = 'All done'
236236
pbar.duration = '01:23:45'
237237
result = pbar._get_complete()
@@ -241,7 +241,7 @@ def test__get_complete_Should_ReturnExpected_When_MessageAndDuration(self, *patc
241241
@patch('progress1bar.progressbar.sys.stderr.isatty', return_value=False)
242242
@patch('progress1bar.progressbar.colorama_init')
243243
def test__get_complete_Should_ReturnExpected_When_NoMessageAndDuration(self, *patches):
244-
pbar = ProgressBar()
244+
pbar = ProgressBar(show_duration=True)
245245
pbar.duration = '01:23:45'
246246
result = pbar._get_complete()
247247
expected_result = 'Processing complete - 01:23:45'
@@ -259,7 +259,7 @@ def test__get_complete_Should_ReturnExpected_When_NoMessageAndNoDuration(self, *
259259
@patch('progress1bar.progressbar.colorama_init')
260260
@patch('progress1bar.progressbar.ProgressBar._get_complete')
261261
def test__get_progress_Should_ReturnExpected_When_Complete(self, get_complete_patch, *patches):
262-
pbar = ProgressBar()
262+
pbar = ProgressBar(total=10)
263263
pbar.complete = True
264264
result = pbar._get_progress()
265265
self.assertEqual(result, get_complete_patch.return_value)

0 commit comments

Comments
 (0)