Advertisement
Guest User

Python progress bar thingy

a guest
Nov 3rd, 2011
327
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.01 KB | None | 0 0
  1. import sys
  2. import time
  3.  
  4.  
  5. class ProgressBase(object):
  6.     """
  7.    An abstract class that helps to put text on the screen and erase it again.
  8.    """
  9.    
  10.     def __init__(self):
  11.         self._str = ''
  12.  
  13.     def _show(self, text):
  14.         sys.stderr.write('\b' * len(self._str))
  15.         self._str = text.ljust(len(self._str))
  16.         sys.stderr.write(self._str)
  17.  
  18.  
  19. class with_spinner(ProgressBase):
  20.     """
  21.    A spinner for long loops of unknown duration, written on stderr.
  22.  
  23.    Wrap this around any iterable, for example:
  24.    for line in with_spinner(lines, action = 'Processing lines...')
  25.    """
  26.  
  27.     chars = '|/-\\'
  28.  
  29.     def __init__(self, iterable = None, action = None, done = 'done'):
  30.         super(with_spinner, self).__init__()
  31.         self.iterable = iterable
  32.         self.frame = 0
  33.         self.last = time.time()
  34.         self.done = done
  35.         if action:
  36.             sys.stderr.write(action + ' ')
  37.  
  38.     def update(self):
  39.         now = time.time()
  40.         if self.last + 0.5 < now:
  41.             self.last = now
  42.             self.frame = (self.frame + 1) % len(with_spinner.chars)
  43.             self._show(with_spinner.chars[self.frame])
  44.    
  45.     def stop(self):
  46.         self._show(self.done or '')
  47.         sys.stderr.write('\n')
  48.  
  49.     def __iter__(self):
  50.         for item in self.iterable:
  51.             yield item
  52.             self.update()
  53.         self.stop()
  54.    
  55.  
  56. class with_progress_meter(ProgressBase):
  57.     """
  58.    A progress meter for long loops of known length, written on stderr.
  59.  
  60.    Wrap this around a list-like object, for example:
  61.    for line in with_progress_meter(lines, action = 'Processing lines...')
  62.    """
  63.  
  64.     def __init__(self, iterable = None, total = None, action = None, done = 'done'):
  65.         super(with_progress_meter, self).__init__()
  66.         self.iterable = iterable
  67.         if total is None:
  68.             total = len(self.iterable)
  69.         self.total = total
  70.         self.start_time = time.time()
  71.         self.last = self.start_time
  72.         self.at = 0
  73.         self.done = done
  74.         if action:
  75.             sys.stderr.write(action + ' ')
  76.         self._str = ''
  77.  
  78.     def update(self, at):
  79.         self.at = at
  80.         now = time.time()
  81.         if self.last + 0.5 < now:
  82.             self.last = now
  83.             self._show(self._progress())
  84.    
  85.     def stop(self):
  86.         self._show(self.done or '')
  87.         sys.stderr.write('\n')
  88.  
  89.     def __iter__(self):
  90.         at = 0
  91.         for item in self.iterable:
  92.             yield item
  93.             at += 1
  94.             self.update(at)
  95.         self.stop()
  96.    
  97.     def _progress(self):
  98.         text = '%3d%%' % int(self.at * 100 / self.total if self.total else 100)
  99.         if self.at > 0:
  100.             spent = time.time() - self.start_time
  101.             remaining = (self.total - self.at) * spent / self.at
  102.             text += ' (ETA: %d:%02d.%03d)' % (
  103.                 int(remaining) / 60,
  104.                 int(remaining) % 60,
  105.                 int(remaining * 1000) % 1000)
  106.         return text
  107.    
  108.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement