Skip to content

Commit

Permalink
Make subcounter fields available in counter_format
Browse files Browse the repository at this point in the history
  • Loading branch information
avylove committed Mar 18, 2020
1 parent 58c0bb0 commit 0aa58c6
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 9 deletions.
33 changes: 24 additions & 9 deletions enlighten/_counter.py
Original file line number Diff line number Diff line change
Expand Up @@ -423,9 +423,9 @@ class can be called directly. The output stream will default to :py:data:`sys.st
- count_n (:py:class:`int`) - Current value of ``count``
- count_0(:py:class:`int`) - Remaining count after deducting counts for all subcounters
- percentage_n (:py:class:`float`) - Percentage complete
- percentage_n (:py:class:`float`) - Percentage complete (``bar_format`` only)
- percentage_0(:py:class:`float`) - Remaining percentage after deducting percentages
for all subcounters
for all subcounters (``bar_format`` only)
.. note::
Expand All @@ -436,7 +436,7 @@ class can be called directly. The output stream will default to :py:data:`sys.st
Additional fields when :py:meth:`add_subcounter` is called with
``all_fields`` set to :py:data:`True`:
- eta_n (:py:class:`str`) - Estimated time to completion
- eta_n (:py:class:`str`) - Estimated time to completion (``bar_format`` only)
- rate_n (:py:class:`float`) - Average increments per second since parent was created
User-defined fields:
Expand Down Expand Up @@ -582,35 +582,40 @@ def close(self, clear=False):

self.manager.remove(self)

def _get_subcounters(self, elapsed):
def _get_subcounters(self, elapsed, bar_fields=True):
"""
Args:
elapsed(float): Time since started.
bar_fields(bool): When False, only set fields for basic counter
Returns:
:py:class:`tuple`: list of subcounters and dictionary of additional fields
Each subcounter in the list will be in a tuple of (subcounter, percentage)
Fields in the dictionary are addressed in the Format documentation of this class
When `bar_fields` is False, only subcounter count and rate fields are set.
percentage will be set to 0.0
"""

fields = {}
subcounters = []

for num, subcounter in enumerate(self._subcounters, 1):

if self.total:
fields['count_{0}'.format(num)] = subcounter.count

if self.total and bar_fields:
subPercentage = subcounter.count / float(self.total)
else:
subPercentage = 0.0

if bar_fields:
fields['percentage_{0}'.format(num)] = subPercentage * 100

# Save in tuple: count, percentage
subcounters.append((subcounter, subPercentage))

# Set fields
fields['percentage_{0}'.format(num)] = subPercentage * 100
fields['count_{0}'.format(num)] = subcounter.count

if subcounter.all_fields:

interations = abs(subcounter.count - subcounter.start_count)
Expand All @@ -621,6 +626,9 @@ def _get_subcounters(self, elapsed):
else:
rate = fields['rate_{0}'.format(num)] = 0.0

if not bar_fields:
continue

if self.total == 0:
fields['eta_{0}'.format(num)] = u'00:00'
elif rate:
Expand Down Expand Up @@ -735,7 +743,14 @@ def format(self, width=None, elapsed=None):
return rtn.format(self._colorize(barText))

# Otherwise return a counter

# Update fields from subcounters
fields['fill'] = u'{0}'
subcounters, subFields = self._get_subcounters(elapsed, bar_fields=False)
if subcounters:
fields.update(subFields)
fields['count_0'] = self.count - sum(sub[0].count for sub in subcounters)

try:
rtn = self.counter_format.format(**fields)
except KeyError as e:
Expand Down
26 changes: 26 additions & 0 deletions tests/test_counter.py
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,18 @@ def test_get_subcounter(self):
self.assertEqual(fields, {'percentage_1': 0.0, 'count_1': 0,
'rate_1': 0.0, 'eta_1': '00:00'})

def test_get_subcounter_counter_format(self):
self.ctr.count = 12
subcounter1 = self.ctr.add_subcounter('green')
subcounter2 = self.ctr.add_subcounter('red', all_fields=True)
subcounter2.count = 6
subcounter3 = self.ctr.add_subcounter('white', count=1, all_fields=True)

subcounters, fields = self.ctr._get_subcounters(8, bar_fields=False)
self.assertEqual(subcounters, [(subcounter1, 0.0), (subcounter2, 0.0), (subcounter3, 0.0)])
self.assertEqual(fields, {'count_1': 0, 'count_2': 6, 'count_3': 1,
'rate_2': 0.75, 'rate_3': 0.0})

def test_remove(self):
self.ctr.leave = False
self.assertTrue(self.ctr in self.manager.counters)
Expand Down Expand Up @@ -677,6 +689,20 @@ def test_subcounter(self):
formatted = ctr.format(elapsed=5, width=80)
self.assertEqual(formatted, u'35 35.0 | 5 5.0 1.0 01:35 | 10 10.0')

def test_subcounter_count_gt_total(self):
"""
When total is exceeded, subcounter fields are still populated
"""
counter_format = u'{count_0} | {count_1} {rate_1} | {count_2}'
ctr = Counter(stream=self.tty.stdout, total=100, counter_format=counter_format)

ctr.count = 500
subcounter1 = ctr.add_subcounter('yellow', all_fields=True)
subcounter1.count = 50
ctr.add_subcounter('blue', count=100)
formatted = ctr.format(elapsed=50, width=80)
self.assertEqual(formatted, u'350 | 50 1.0 | 100')

def test_close(self):
manager = mock.Mock()

Expand Down

0 comments on commit 0aa58c6

Please sign in to comment.