Skip to content

Commit

Permalink
Track count updates and closed status
Browse files Browse the repository at this point in the history
  • Loading branch information
avylove committed Sep 20, 2023
1 parent 13f1694 commit 81ceb2e
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 22 deletions.
4 changes: 2 additions & 2 deletions doc/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,12 @@ Classes
.. autoclass:: Counter
:members:
:inherited-members:
:exclude-members: elapsed, position
:exclude-members: count, elapsed, position

.. autoclass:: StatusBar
:members:
:inherited-members:
:exclude-members: elapsed, position
:exclude-members: count, elapsed, position

.. autoclass:: SubCounter
:members:
Expand Down
41 changes: 36 additions & 5 deletions enlighten/_basecounter.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class BaseCounter(object):
Base class for counters
"""

__slots__ = ('_color', 'count', 'manager', 'start_count')
__slots__ = ('_color', '_count', 'manager', 'start_count')
_repr_attrs = ('count', 'color')
_placeholder_ = u'___ENLIGHTEN_PLACEHOLDER___'
_placeholder_len_ = len(_placeholder_)
Expand All @@ -50,7 +50,7 @@ def __init__(self, keywords=None, **kwargs):
if keywords is not None:
kwargs = keywords

self.count = self.start_count = kwargs.pop('count', 0)
self._count = self.start_count = kwargs.pop('count', 0)
self._color = None

self.manager = kwargs.pop('manager', None)
Expand All @@ -59,6 +59,20 @@ def __init__(self, keywords=None, **kwargs):

self.color = kwargs.pop('color', None)

@property
def count(self):
"""
Running count
A property so additional logic can be added in children
"""

return self._count

@count.setter
def count(self, value):

self._count = value

@property
def color(self):
"""
Expand Down Expand Up @@ -144,33 +158,49 @@ def __call__(self, *args):
self.update()


class PrintableCounter(BaseCounter):
class PrintableCounter(BaseCounter): # pylint: disable=too-many-instance-attributes
"""
Base class for printable counters
"""

__slots__ = ('enabled', '_fill', 'last_update', 'leave', 'min_delta', '_pinned', 'start')
__slots__ = ('_closed', '_count_updated', 'enabled', '_fill', 'last_update',
'leave', 'min_delta', '_pinned', 'start')

def __init__(self, keywords=None, **kwargs):

if keywords is not None: # pragma: no branch
kwargs = keywords
super(PrintableCounter, self).__init__(keywords=kwargs)

self._closed = False
self.enabled = kwargs.pop('enabled', True)
self._fill = u' '
self.fill = kwargs.pop('fill', u' ')
self.leave = kwargs.pop('leave', True)
self.min_delta = kwargs.pop('min_delta', 0.1)
self._pinned = False
self.last_update = self.start = time.time()
self.last_update = self.start = self._count_updated = time.time()

def __enter__(self):
return self

def __exit__(self, *args):
self.close()

@property
def count(self):
"""
Running count
"""

return self._count

@count.setter
def count(self, value):

self._count = value
self._count_updated = time.time()

@property
def elapsed(self):
"""
Expand Down Expand Up @@ -228,6 +258,7 @@ def close(self, clear=False):
else:
self.refresh()

self._closed = True
self.manager.remove(self)

def format(self, width=None, elapsed=None):
Expand Down
26 changes: 14 additions & 12 deletions enlighten/_counter.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ def __init__(self, parent, color=None, count=0, all_fields=False):
all_fields(bool): Populate ``rate``, ``interval``, and ``eta`` fields (Default: False)
"""

if parent.count - parent.subcount - count < 0:
if parent._count - parent.subcount - count < 0:
raise ValueError('Invalid count: %s' % count)

super(SubCounter, self).__init__(manager=parent.manager, color=color, count=count)
Expand Down Expand Up @@ -128,7 +128,7 @@ def update_from(self, source, incr=1, force=False):
raise ValueError('source must be parent or peer')

# Make sure counts won't go negative
if self.count + incr < 0 or source.count - incr < 0:
if self._count + incr < 0 or source.count - incr < 0:
raise ValueError('Invalid increment: %s' % incr)

# Make sure parent count won't go negative
Expand Down Expand Up @@ -462,9 +462,9 @@ def elapsed(self):
Get elapsed time is seconds (float)
"""

# Clock stops running when total is reached
if self.count == self.total:
return self.last_update - self.start
# If closed or total is reached, use last time count was updated
if self._closed or self._count == self.total:
return self._count_updated - self.start

return time.time() - self.start

Expand All @@ -474,7 +474,8 @@ def subcount(self):
Sum of counts from all subcounters
"""

return sum(subcounter.count for subcounter in self._subcounters)
# pylint: disable=protected-access
return sum(subcounter._count for subcounter in self._subcounters)

# pylint: disable=too-many-locals
def _get_subcounters(self, elapsed, fields, bar_fields=True, force_float=False):
Expand Down Expand Up @@ -569,8 +570,9 @@ def format(self, width=None, elapsed=None):

width = width or self.manager.width
total = self.total
count = self.count

iterations = float(abs(self.count - self.start_count))
iterations = float(abs(count - self.start_count))

fields = self.fields.copy()
fields.update(self._fields)
Expand All @@ -587,8 +589,8 @@ def format(self, width=None, elapsed=None):
', '.join(reserved_fields),
EnlightenWarning)

force_float = isinstance(self.count, float) or isinstance(total, float)
fields['count'] = Float(self.count) if force_float else self.count
force_float = isinstance(count, float) or isinstance(total, float)
fields['count'] = Float(count) if force_float else count
fields['desc'] = self.desc or u''
fields['total'] = Float(total) if force_float and total is not None else total
fields['unit'] = self.unit or u''
Expand All @@ -607,7 +609,7 @@ def format(self, width=None, elapsed=None):
fields['interval'] = rate ** -1 if rate else rate

# Only process bar if total was given and n doesn't exceed total
if total is not None and self.count <= total:
if total is not None and count <= total:
return self._format_bar(fields, iterations, width, elapsed, force_float)

# Otherwise return a counter
Expand Down Expand Up @@ -689,7 +691,7 @@ def _format_bar(self, fields, iterations, width, elapsed, force_float):
fields['eta'] = u'00:00'
else:
# Use float to force to float in Python 2
percentage = self.count / float(self.total)
percentage = self._count / float(self.total)
rate = fields['rate']

# Get eta. Use iterations so a counter running backwards is accurate
Expand Down Expand Up @@ -806,7 +808,7 @@ def update(self, incr=1, force=False, **fields): # pylint: disable=arguments-di
if self.enabled:
currentTime = time.time()
# Update if force, 100%, or minimum delta has been reached
if force or self.count == self.total or \
if force or self._count == self.total or \
currentTime - self.last_update >= self.min_delta:
self.refresh(elapsed=currentTime - self.start)

Expand Down
11 changes: 8 additions & 3 deletions tests/test_counter.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,14 +140,19 @@ def test_elapsed(self):

ctr = self.ctr
ctr.start = time.time() - 5.0
ctr.last_update = ctr.start + 3.0
ctr._count_updated = ctr.start + 3.0

self.assertEqual(int(ctr.elapsed), 5)

# Clock stops running when total is reached
ctr.count = ctr.total
# Uses last time count was updated when closed
ctr.close()
self.assertEqual(int(ctr.elapsed), 3)

# Used last time count was updated when count equals total
ctr._closed = False
ctr.count = ctr.total
self.assertEqual(int(ctr.elapsed), 5)

def test_refresh(self):
"""
Refresh counter if enabled
Expand Down

0 comments on commit 81ceb2e

Please sign in to comment.