diff --git a/src/util.py b/src/util.py --- a/src/util.py +++ b/src/util.py @@ -1,5 +1,8 @@ +import math import os import sys +import collections +from datetime import datetime def spawnDaemon(fun): @@ -45,22 +48,61 @@ class Progress: self._i0=i0 self._i=i0 self._last="" + self._past=collections.deque() def p(self,i): i0=self._i0 n=self._n + now=datetime.now() assert i0<=i1: + self._past.append((now,i)) + if res!=self._last or (now-self._past[0][0]).total_seconds()>5: + eta=formatSeconds(self.eta(i)) + self._print("{0} (ETA {1})".format(res,eta)) self._last=res + while (now-self._past[0][0]).total_seconds()>5: + self._past.popleft() def done(self): - print("100%") + self._print("100%",end="\n") + + def eta(self,i2): + t2=datetime.now() + (t1,i1)=self._past[0] + if i2==i1: return float("nan") + return (self._n-i2)/(i2-i1)*(t2-t1).total_seconds() @staticmethod def _p(i,n,i0): _1=1 if n>=i0 else -1 return 100*(i+_1-i0)//(n-i0) + + def _print(self,s,end=""): + print("\r"+" "*80,end="") + print("\r"+s,end=end) + + +def formatSeconds(secs): + if math.isnan(secs): return "?" + secs=round(secs) + if secs<60: return "{0}s".format(secs) + mins=secs//60 + secs%=60 + if mins<60: return "{0:02}:{1:02}".format(mins, secs) + hours=mins//60 + mins%=60 + return "{0:02}:{1:02}:{2:02}".format(hours, mins, secs) + + +if __name__=="__main__": + import random + import time + progress=Progress(100) + for i in range(1,100): + progress.p(i) + time.sleep(random.random()*2) + progress.done()