over/core/core.50-misc.pyx

340 lines
8.5 KiB
Cython

# 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 "<enum %s>" %(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