mirror of
https://github.com/verigak/progress.git
synced 2025-12-08 19:33:24 +00:00
Allow custom properties in format strings
This commit is contained in:
@@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
from __future__ import division
|
from __future__ import division
|
||||||
|
|
||||||
|
from datetime import timedelta
|
||||||
from math import ceil
|
from math import ceil
|
||||||
from sys import stderr
|
from sys import stderr
|
||||||
from time import time
|
from time import time
|
||||||
@@ -26,16 +27,25 @@ class Infinite(object):
|
|||||||
file = stderr
|
file = stderr
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
self.ctx = {}
|
|
||||||
for key, val in kwargs.items():
|
|
||||||
if hasattr(self, key):
|
|
||||||
setattr(self, key, val)
|
|
||||||
else:
|
|
||||||
self.ctx[key] = val
|
|
||||||
|
|
||||||
self.index = 0
|
|
||||||
self.avg = 0
|
self.avg = 0
|
||||||
self._ts = time()
|
self.index = 0
|
||||||
|
self.start_ts = time()
|
||||||
|
self._ts = self.start_ts
|
||||||
|
for key, val in kwargs.items():
|
||||||
|
setattr(self, key, val)
|
||||||
|
|
||||||
|
def __getitem__(self, key):
|
||||||
|
if key.startswith('_'):
|
||||||
|
return None
|
||||||
|
return getattr(self, key, None)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def elapsed(self):
|
||||||
|
return int(time() - self.start_ts)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def elapsed_td(self):
|
||||||
|
return timedelta(seconds=self.elapsed)
|
||||||
|
|
||||||
def update_stats(self):
|
def update_stats(self):
|
||||||
# Calculate moving average
|
# Calculate moving average
|
||||||
@@ -44,10 +54,6 @@ class Infinite(object):
|
|||||||
self.avg = (dt + self.index * self.avg) / (self.index + 1) if self.avg else dt
|
self.avg = (dt + self.index * self.avg) / (self.index + 1) if self.avg else dt
|
||||||
self._ts = now
|
self._ts = now
|
||||||
|
|
||||||
kv = [(key, val) for key, val in self.__dict__.items()
|
|
||||||
if not key.startswith('_')]
|
|
||||||
self.ctx.update(kv)
|
|
||||||
|
|
||||||
def update(self):
|
def update(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@@ -75,8 +81,15 @@ class Progress(Infinite):
|
|||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super(Progress, self).__init__(*args, **kwargs)
|
super(Progress, self).__init__(*args, **kwargs)
|
||||||
self.max = kwargs.get('max', 100)
|
self.max = kwargs.get('max', 100)
|
||||||
self.eta = 0
|
self.remaining = self.max
|
||||||
self.elapsed = 0
|
|
||||||
|
@property
|
||||||
|
def eta(self):
|
||||||
|
return int(ceil(self.avg * self.remaining))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def eta_td(self):
|
||||||
|
return timedelta(seconds=self.eta)
|
||||||
|
|
||||||
def update_stats(self):
|
def update_stats(self):
|
||||||
self.progress = min(1, self.index / self.max)
|
self.progress = min(1, self.index / self.max)
|
||||||
@@ -88,14 +101,8 @@ class Progress(Infinite):
|
|||||||
if self.delta:
|
if self.delta:
|
||||||
dt = (now - self._ts) / self.delta
|
dt = (now - self._ts) / self.delta
|
||||||
self.avg = (dt + self.index * self.avg) / (self.index + 1) if self.avg else dt
|
self.avg = (dt + self.index * self.avg) / (self.index + 1) if self.avg else dt
|
||||||
self.eta = int(ceil(self.avg * self.remaining))
|
|
||||||
self.elapsed += now - self._ts
|
|
||||||
self._ts = now
|
self._ts = now
|
||||||
|
|
||||||
kv = [(key, val) for key, val in self.__dict__.items()
|
|
||||||
if not key.startswith('_')]
|
|
||||||
self.ctx.update(kv)
|
|
||||||
|
|
||||||
def start(self):
|
def start(self):
|
||||||
self.delta = 0
|
self.delta = 0
|
||||||
self.update_stats()
|
self.update_stats()
|
||||||
|
|||||||
@@ -32,10 +32,10 @@ class Bar(WritelnMixin, Progress):
|
|||||||
filled_length = int(self.width * self.progress)
|
filled_length = int(self.width * self.progress)
|
||||||
empty_length = self.width - filled_length
|
empty_length = self.width - filled_length
|
||||||
|
|
||||||
message = self.message % self.ctx
|
message = self.message % self
|
||||||
bar = self.fill * filled_length
|
bar = self.fill * filled_length
|
||||||
empty = self.empty_fill * empty_length
|
empty = self.empty_fill * empty_length
|
||||||
suffix = self.suffix % self.ctx
|
suffix = self.suffix % self
|
||||||
line = ''.join([message, self.bar_prefix, bar, empty, self.bar_suffix,
|
line = ''.join([message, self.bar_prefix, bar, empty, self.bar_suffix,
|
||||||
suffix])
|
suffix])
|
||||||
self.writeln(line)
|
self.writeln(line)
|
||||||
@@ -69,11 +69,11 @@ class IncrementalBar(Bar):
|
|||||||
empty_length = self.width - filled_length
|
empty_length = self.width - filled_length
|
||||||
phase = expanded_length - (filled_length * nphases)
|
phase = expanded_length - (filled_length * nphases)
|
||||||
|
|
||||||
message = self.message % self.ctx
|
message = self.message % self
|
||||||
bar = self.phases[-1] * filled_length
|
bar = self.phases[-1] * filled_length
|
||||||
current = self.phases[phase] if phase > 0 else ''
|
current = self.phases[phase] if phase > 0 else ''
|
||||||
empty = self.empty_fill * max(0, empty_length - len(current))
|
empty = self.empty_fill * max(0, empty_length - len(current))
|
||||||
suffix = self.suffix % self.ctx
|
suffix = self.suffix % self
|
||||||
line = ''.join([message, self.bar_prefix, bar, current, empty,
|
line = ''.join([message, self.bar_prefix, bar, current, empty,
|
||||||
self.bar_suffix, suffix])
|
self.bar_suffix, suffix])
|
||||||
self.writeln(line)
|
self.writeln(line)
|
||||||
|
|||||||
@@ -10,13 +10,16 @@ from progress.bar import (Bar, ChargingBar, FillingSquaresBar,
|
|||||||
from progress.spinner import Spinner, PieSpinner, MoonSpinner, LineSpinner
|
from progress.spinner import Spinner, PieSpinner, MoonSpinner, LineSpinner
|
||||||
from progress.counter import Counter, Countdown, Stack, Pie
|
from progress.counter import Counter, Countdown, Stack, Pie
|
||||||
|
|
||||||
|
for bar_cls in (Bar, ChargingBar, FillingSquaresBar, FillingCirclesBar):
|
||||||
for bar in (Bar, ChargingBar, FillingSquaresBar, FillingCirclesBar):
|
suffix = '%(index)d/%(max)d [%(elapsed)d / %(eta)d]'
|
||||||
for i in bar(bar.__name__).iter(range(100)):
|
bar = bar_cls(bar_cls.__name__, suffix=suffix)
|
||||||
|
for i in bar.iter(range(100)):
|
||||||
sleep(0.04)
|
sleep(0.04)
|
||||||
|
|
||||||
for bar in (IncrementalBar, ShadyBar):
|
for bar_cls in (IncrementalBar, ShadyBar):
|
||||||
for i in bar(bar.__name__).iter(range(200)):
|
suffix = '%(percent)d%% [%(elapsed_td)s / %(eta_td)s]'
|
||||||
|
bar = bar_cls(bar_cls.__name__, suffix=suffix)
|
||||||
|
for i in bar.iter(range(200)):
|
||||||
sleep(0.02)
|
sleep(0.02)
|
||||||
|
|
||||||
for spin in (Spinner, PieSpinner, MoonSpinner, LineSpinner):
|
for spin in (Spinner, PieSpinner, MoonSpinner, LineSpinner):
|
||||||
@@ -26,7 +29,7 @@ for spin in (Spinner, PieSpinner, MoonSpinner, LineSpinner):
|
|||||||
|
|
||||||
for singleton in (Counter, Countdown, Stack, Pie):
|
for singleton in (Counter, Countdown, Stack, Pie):
|
||||||
for i in singleton(singleton.__name__ + ' ').iter(range(100)):
|
for i in singleton(singleton.__name__ + ' ').iter(range(100)):
|
||||||
sleep(0.04)
|
sleep(0.03)
|
||||||
print()
|
print()
|
||||||
|
|
||||||
bar = IncrementalBar('Random', backtrack=True, suffix='')
|
bar = IncrementalBar('Random', backtrack=True, suffix='')
|
||||||
|
|||||||
Reference in New Issue
Block a user