dosage/dosagelib/progress.py
2012-06-20 22:41:04 +02:00

93 lines
2.6 KiB
Python

# -*- coding: iso-8859-1 -*-
# Copyright (C) 2004-2005 Tristan Seligmann and Jonathan Jacobs
from __future__ import division
import sys
import time
from . import util
class Guess(object):
def __init__(self, weight):
self.weight = weight
self.guess = 0
self.best = 0
def feed(self, value):
self.guess = self.weight * value + (1 - self.weight) * self.guess
def distance(self, value):
return (self.guess - value) ** 2
class FortuneTeller(object):
weights = (0.2, 0.3, 0.4)
def __init__(self):
self.guesses = map(Guess, self.weights)
def feed(self, value):
best = min([(guess.distance(value), guess) for guess in self.guesses])[1]
best.best += 1
for guess in self.guesses:
guess.feed(value)
def predict(self):
return max([(guess.best, guess) for guess in self.guesses])[1].guess
class OperationComplete(Exception): pass
def drawBar(fill, total, caption):
screenWidth = util.getWindowSize()
ratio = fill / total
mask = '[%%s>%%s] (%.2f%%%%) %s' % (ratio * 100, caption)
barWidth = screenWidth - len(mask) + 6
fillWidth = int(barWidth * ratio) - 1
emptyWidth = barWidth - fillWidth - 1
sys.stdout.write('\r')
sys.stdout.write(mask % ('=' * fillWidth, '-' * emptyWidth))
sys.stdout.flush()
def drawBounceBar(pos, caption):
screenWidth = util.getWindowSize()
mask = '[%%s<=>%%s] %s' % (caption,)
barWidth = screenWidth - len(mask) + 4
leftWidth = pos % barWidth - 1
rightWidth = barWidth - leftWidth - 1
sys.stdout.write('\r')
sys.stdout.write(mask % (' ' * leftWidth, ' ' * rightWidth))
sys.stdout.flush()
def progressBar(fn):
completed = bps = 0
count = 0
ft = FortuneTeller()
currentTime = lastTime = time.time()
try:
while 1:
inc = 0
while currentTime - lastTime < 0.2:
progress, total = fn()
inc += progress
currentTime = time.time()
ft.feed(inc / (currentTime - lastTime))
lastTime = currentTime
completed += inc
bps = ft.predict()
if total == 0:
drawBounceBar(count, '%s/sec' % util.saneDataSize(bps))
count += 1
else:
drawBar(completed, max(total, completed), '%s/sec' % util.saneDataSize(bps))
except OperationComplete:
if count > 0:
drawBounceBar(count, '%s/sec' % util.saneDataSize(bps))
else:
drawBar(max(total, completed), max(total, completed), '%s/sec' % util.saneDataSize(bps))
print ''