1# Authors: Karl MacMillan <kmacmillan@mentalrootkit.com> 2# 3# Copyright (C) 2006 Red Hat 4# see file 'COPYING' for use and warranty information 5# 6# This program is free software; you can redistribute it and/or 7# modify it under the terms of the GNU General Public License as 8# published by the Free Software Foundation; version 2 only 9# 10# This program is distributed in the hope that it will be useful, 11# but WITHOUT ANY WARRANTY; without even the implied warranty of 12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13# GNU General Public License for more details. 14# 15# You should have received a copy of the GNU General Public License 16# along with this program; if not, write to the Free Software 17# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18# 19import locale 20import sys 21 22 23PY3 = sys.version_info[0] == 3 24 25if PY3: 26 bytes_type=bytes 27 string_type=str 28else: 29 bytes_type=str 30 string_type=unicode 31 32 33class ConsoleProgressBar: 34 def __init__(self, out, steps=100, indicator='#'): 35 self.blocks = 0 36 self.current = 0 37 self.steps = steps 38 self.indicator = indicator 39 self.out = out 40 self.done = False 41 42 def start(self, message=None): 43 self.done = False 44 if message: 45 self.out.write('\n%s:\n' % message) 46 self.out.write('%--10---20---30---40---50---60---70---80---90--100\n') 47 48 def step(self, n=1): 49 self.current += n 50 51 old = self.blocks 52 self.blocks = int(round(self.current / float(self.steps) * 100) / 2) 53 54 if self.blocks > 50: 55 self.blocks = 50 56 57 new = self.blocks - old 58 59 self.out.write(self.indicator * new) 60 self.out.flush() 61 62 if self.blocks == 50 and not self.done: 63 self.done = True 64 self.out.write("\n") 65 66def set_to_list(s): 67 l = [] 68 l.extend(s) 69 return l 70 71def first(s, sorted=False): 72 """ 73 Return the first element of a set. 74 75 It sometimes useful to return the first element from a set but, 76 because sets are not indexable, this is rather hard. This function 77 will return the first element from a set. If sorted is True, then 78 the set will first be sorted (making this an expensive operation). 79 Otherwise a random element will be returned (as sets are not ordered). 80 """ 81 if not len(s): 82 raise IndexError("empty containter") 83 84 if sorted: 85 l = set_to_list(s) 86 l.sort() 87 return l[0] 88 else: 89 for x in s: 90 return x 91 92def encode_input(text): 93 import locale 94 """Encode given text via preferred system encoding""" 95 # locale will often find out the correct encoding 96 encoding = locale.getpreferredencoding() 97 try: 98 encoded_text = text.encode(encoding) 99 except UnicodeError: 100 # if it fails to find correct encoding then ascii is used 101 # which may lead to UnicodeError if `text` contains non ascii signs 102 # utf-8 is our guess to fix the situation 103 encoded_text = text.encode('utf-8') 104 return encoded_text 105 106def decode_input(text): 107 import locale 108 """Decode given text via preferred system encoding""" 109 # locale will often find out the correct encoding 110 encoding = locale.getpreferredencoding() 111 try: 112 decoded_text = text.decode(encoding) 113 except UnicodeError: 114 # if it fails to find correct encoding then ascii is used 115 # which may lead to UnicodeError if `text` contains non ascii signs 116 # utf-8 is our guess to fix the situation 117 decoded_text = text.decode('utf-8') 118 return decoded_text 119 120class Comparison(): 121 """Class used when implementing rich comparison. 122 123 Inherit from this class if you want to have a rich 124 comparison withing the class, afterwards implement 125 _compare function within your class.""" 126 127 def _compare(self, other, method): 128 raise NotImplemented 129 130 def __eq__(self, other): 131 return self._compare(other, lambda a, b: a == b) 132 133 def __lt__(self, other): 134 return self._compare(other, lambda a, b: a < b) 135 136 def __le__(self, other): 137 return self._compare(other, lambda a, b: a <= b) 138 139 def __ge__(self, other): 140 return self._compare(other, lambda a, b: a >= b) 141 142 def __gt__(self, other): 143 return self._compare(other, lambda a, b: a > b) 144 145 def __ne__(self, other): 146 return self._compare(other, lambda a, b: a != b) 147 148if sys.version_info < (2,7): 149 # cmp_to_key function is missing in python2.6 150 def cmp_to_key(mycmp): 151 'Convert a cmp= function into a key= function' 152 class K: 153 def __init__(self, obj, *args): 154 self.obj = obj 155 def __lt__(self, other): 156 return mycmp(self.obj, other.obj) < 0 157 def __gt__(self, other): 158 return mycmp(self.obj, other.obj) > 0 159 def __eq__(self, other): 160 return mycmp(self.obj, other.obj) == 0 161 def __le__(self, other): 162 return mycmp(self.obj, other.obj) <= 0 163 def __ge__(self, other): 164 return mycmp(self.obj, other.obj) >= 0 165 def __ne__(self, other): 166 return mycmp(self.obj, other.obj) != 0 167 return K 168else: 169 from functools import cmp_to_key 170 171def cmp(first, second): 172 return (first > second) - (second > first) 173 174if __name__ == "__main__": 175 import sys 176 import time 177 p = ConsoleProgressBar(sys.stdout, steps=999) 178 p.start("computing pi") 179 for i in range(999): 180 p.step() 181 time.sleep(0.001) 182 183