91 lines
2.5 KiB
Python
91 lines
2.5 KiB
Python
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 ''
|