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 datetime import timedelta
|
||||
from math import ceil
|
||||
from sys import stderr
|
||||
from time import time
|
||||
@@ -26,16 +27,25 @@ class Infinite(object):
|
||||
file = stderr
|
||||
|
||||
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._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):
|
||||
# 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._ts = now
|
||||
|
||||
kv = [(key, val) for key, val in self.__dict__.items()
|
||||
if not key.startswith('_')]
|
||||
self.ctx.update(kv)
|
||||
|
||||
def update(self):
|
||||
pass
|
||||
|
||||
@@ -75,8 +81,15 @@ class Progress(Infinite):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(Progress, self).__init__(*args, **kwargs)
|
||||
self.max = kwargs.get('max', 100)
|
||||
self.eta = 0
|
||||
self.elapsed = 0
|
||||
self.remaining = self.max
|
||||
|
||||
@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):
|
||||
self.progress = min(1, self.index / self.max)
|
||||
@@ -88,14 +101,8 @@ class Progress(Infinite):
|
||||
if self.delta:
|
||||
dt = (now - self._ts) / self.delta
|
||||
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
|
||||
|
||||
kv = [(key, val) for key, val in self.__dict__.items()
|
||||
if not key.startswith('_')]
|
||||
self.ctx.update(kv)
|
||||
|
||||
def start(self):
|
||||
self.delta = 0
|
||||
self.update_stats()
|
||||
|
||||
@@ -32,10 +32,10 @@ class Bar(WritelnMixin, Progress):
|
||||
filled_length = int(self.width * self.progress)
|
||||
empty_length = self.width - filled_length
|
||||
|
||||
message = self.message % self.ctx
|
||||
message = self.message % self
|
||||
bar = self.fill * filled_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,
|
||||
suffix])
|
||||
self.writeln(line)
|
||||
@@ -69,11 +69,11 @@ class IncrementalBar(Bar):
|
||||
empty_length = self.width - filled_length
|
||||
phase = expanded_length - (filled_length * nphases)
|
||||
|
||||
message = self.message % self.ctx
|
||||
message = self.message % self
|
||||
bar = self.phases[-1] * filled_length
|
||||
current = self.phases[phase] if phase > 0 else ''
|
||||
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,
|
||||
self.bar_suffix, suffix])
|
||||
self.writeln(line)
|
||||
|
||||
@@ -10,13 +10,16 @@ from progress.bar import (Bar, ChargingBar, FillingSquaresBar,
|
||||
from progress.spinner import Spinner, PieSpinner, MoonSpinner, LineSpinner
|
||||
from progress.counter import Counter, Countdown, Stack, Pie
|
||||
|
||||
|
||||
for bar in (Bar, ChargingBar, FillingSquaresBar, FillingCirclesBar):
|
||||
for i in bar(bar.__name__).iter(range(100)):
|
||||
for bar_cls in (Bar, ChargingBar, FillingSquaresBar, FillingCirclesBar):
|
||||
suffix = '%(index)d/%(max)d [%(elapsed)d / %(eta)d]'
|
||||
bar = bar_cls(bar_cls.__name__, suffix=suffix)
|
||||
for i in bar.iter(range(100)):
|
||||
sleep(0.04)
|
||||
|
||||
for bar in (IncrementalBar, ShadyBar):
|
||||
for i in bar(bar.__name__).iter(range(200)):
|
||||
for bar_cls in (IncrementalBar, ShadyBar):
|
||||
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)
|
||||
|
||||
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 i in singleton(singleton.__name__ + ' ').iter(range(100)):
|
||||
sleep(0.04)
|
||||
sleep(0.03)
|
||||
print()
|
||||
|
||||
bar = IncrementalBar('Random', backtrack=True, suffix='')
|
||||
|
||||
Reference in New Issue
Block a user