# class Autoloader: # """ # Python module autoloader. To activate, call et.autoloader.register() from python shell. # Try not to rely on it as it'll betray you when there's more than one new module in a single command. # """ # def __init__(self): # self.original_handler = sys.excepthook # def register(self, deact=False): # if not deact: # sys.excepthook = self # else: # sys.excepthook = self.original_handler # def __call__(self, exctype, value, trace): # if exctype == NameError: # module_name = textfilter(value.args[0], {"name '": "", "' is not defined": ""}) # #retval = _exec("import %s" % module_name, trace) # command_locals = trace.tb_frame.f_locals # command_globals = trace.tb_frame.f_globals # try: # retval relates to import success only # exec "import %s" % module_name in command_locals, command_globals # retval = True # output("Autoloaded module §g%s§/" %(module_name), 0, timestamp=True) # exec trace.tb_frame.f_code in command_locals, command_globals # retval = True # except ImportError: # retval = False # except: # traceback.print_exc() # if exctype != NameError or not retval: # traceback.print_exception(exctype, value, trace) # def wait(seconds_target, text="", minutes=True, progress_bar=True, countdown=False): # """ # int seconds how long to wait # str text display this text before the timer # bool minutes use mm:ss ? # bool progress_bar display a progress bar ? TODO # bool countdown count down instead of up # Wait clock. Don't use it on larger scales, i.e. hours, as it accumulates little error every tick # and you may end up waiting extra minutes or even dead. # Returns True if zero is reached, False if interrupted. # """ # seconds = 0 # try: # while seconds <= seconds_target: # if countdown: # seconds_use = seconds_target - seconds # else: # seconds_use = seconds # if minutes: # mins = str(seconds_use/60).zfill(2) # secs = str(seconds_use%60).zfill(2) # mins_target = str(seconds_target/60).zfill(2) # secs_target = str(seconds_target%60).zfill(2) # time_tag = "%s:%s / %s:%s" %(mins, secs, mins_target, secs_target) # else: # time_tag = "%s / %s" %(seconds_use, seconds_target) # prog_bar = " " # if progress_bar: # # determine how much space we have to crap up... I mean use # # 13 = 8 spaces at the end, 5 for ' [>] ' # width_max = get_terminal_size()[1] - len(re.sub("§.", "", text)) - len(time_tag) - 20 # left_side = int((seconds/float(seconds_target)) * width_max) # right_side = width_max - left_side # prog_bar = " [%s>%s] " %('='*left_side, ' '*right_side) # output(text+prog_bar+time_tag+' \r', 0, newline=False) # if not seconds == seconds_target: # time.sleep(1) # seconds += 1 # except (EOFError, KeyboardInterrupt): # output(text+prog_bar+time_tag+' ', 3) # return False # else: # output(text+prog_bar+time_tag+' ', 2) # return True # def progress(part, width=None, before="", after="", show_percent=True, newline=False): # """ # Display a progress bar. # float part 0.0 to 1.0 # int width width in cols, defaults to terminal width # str before text displayed before the progress bar # str after text displayed after the progress bar # bool show_percent display percent after the bar (but before the after part) # bool newline append a \n # """ # if not width: # width = get_terminal_size()[1] # width_bar = width - 2 - 2 - 1 # # a b c # # a = space on each side of the terminal # # b = [ and ] # # c = > # if before: # width_bar -= 1 + len(before) # before = before + " " # if after: # width_bar -= 1 + len(after) # after = " " + after # if show_percent: # width_bar -= 5 # percent = "%s%% " %(str(int(round(part*100))).rjust(3)) # if not newline: # r_part = "\r" # else: # r_part = "" # output(" %s%s[%s>%s]%s %s" %(before, percent, "="*int(part*width_bar), " "*(int((1-part)*width_bar)), after, r_part), newline=newline) # class Unit: # _prefixes = ( ("Y", 24), ("Z", 21), ("E", 18), ("P", 15), ("T", 12), ("G", 9), ("M", 6), ("k", 3), ("", 0), # ("m", -3), ("μ", -6), ("n", -9), ("p", -12), ("f", -15), ("a", -18), ("z", -21), ("y", -24)) # #("c", -2), # def __init__(self, initializer, force_unit=None, dimension=1, space=True): # self.space = space # self.dimension = dimension # if type(initializer) == str: # init from text # integer, decimal, unit = re.findall("(\d+)[.,]*(\d*)\s*(\D+)", initializer)[0] # self.value = float("%s.%s" %(integer, decimal)) # if len(unit) >= 2: # prefix = self._prefix_to_multiplier(unit[0]) # if prefix != None: # self.value *= 10**(prefix*self.dimension) # self.unit = unit[1:] # else: # self.unit = unit # else: # self.unit = unit # if force_unit: # self.unit = force_unit # else: # init from float, str unit and int dimension # self.value = float(initializer) # self.unit = force_unit # def _prefix_to_multiplier(self, prefix): # for p, mul in self._prefixes: # if p == prefix: # return mul # return None # def __repr__(self): # value = self.value # if value < 0: # sign = -1 # value *= -1 # else: # sign = 1 # if value == 0.0: # e = 0 # else: # e = round(math.log(value, 10), 6) # for prefix, mul in self._prefixes: # if mul*self.dimension <= e: # break # if self.unit: # unit = self.unit # else: # unit = "" # if self.space: # space = " " # else: # space = "" # return "%.2f%s%s%s" %(sign*value/10**(mul*self.dimension), space, prefix, unit) # by ephemient@stackoverflow.com def touch(fname, times=None): with open(fname, 'a'): os.utime(fname, times) def console(environment): """ Opens up a Python console. Typical usage: over.console(locals()) """ import code, readline, rlcompleter readline.parse_and_bind("tab: complete") _print = Output("over.core", default_suffix=".\n", timestamp=True, tb=False) _print("opening Python console", prefix.start) c = code.InteractiveConsole(environment) c.interact(banner="") class enum: """ Emulates a C++-like enum type. Based on a py2 enum function by Alec Thomas and acjohnson55. """ def __init__(self, name, words, start=0): self.typename = name self.reverse_enums = dict(enumerate(words, start)) self.enums = dict((value, key) for key, value in self.reverse_enums.items()) def name(self, value): if value in self.reverse_enums: return self.reverse_enums[value] else: raise AttributeError("No attribute of %s has a value of %s." %(self, value)) def __getattr__(self, aname): if aname in self.enums: return self.enums[aname] else: raise AttributeError("%s not in %s." %(aname, self)) def __repr__(self): return "" %(self.typename) class map: def __init__(self, source=None): """ source is a zipped list: [(key, value), (key, value), ...] """ if source: self.keys, self.vals = zip(*source) else: self.keys = [] self.vals = [] def __get_index(self, key): if key in self.keys: return self.keys.index(key) else: return None def __getitem__(self, key): i = self.__get_index(key) if i is None: raise KeyError(key) else: return self.vals[i] def __setitem__(self, key, val): i = self.__get_index(key) if i is None: self.keys.append(key) self.vals.append(val) else: self.vals[i] = val def __contains__(self, item): return item in self.keys def index(self, item): return self.keys.index(item) def sort(self, key=None): tmp_keys = self.keys tmp_vals = self.vals self.keys = [] self.vals = [] for K, V in sorted(zip(tmp_keys, tmp_vals), key=key): self.keys.append(K) self.vals.append(V) @property def items(self): return zip(self.keys, self.vals) def __len__(self): return len(self.vals) def __repr__(self): pairs = [] for i in range(len(self.keys)): pairs.append("%s: %s" %(repr(self.keys[i]), repr(self.vals[i]))) return "<{%s}>" %(", ".join(pairs)) def batch_gen(data, batch_size): """ by rpr (stackoverflow) """ for i in range(0, len(data), batch_size): yield data[i:i+batch_size] class ndict(dict): def __init__(self, *args, **kwargs): dict.__init__(self, *args, **kwargs) def __getattr__(self, name): if name in self: return self[name] else: raise AttributeError("'ndict' object has no attribute '%s'" %(name)) def __setattr__(self, name, value): self[name] = value