Mercurial > code > home > repos > light9
view flax/TLUtility.py @ 15:c76b62eccdec
put **kw back in, they now go to the scale and can override the defaults.
put **kw back in, they now go to the scale and can override the defaults.
for our purposes, we probably want to edit the defaults so we don't have
them in every call.
author | dmcc |
---|---|
date | Sun, 07 Jul 2002 06:18:40 +0000 |
parents | 45b12307c695 |
children |
line wrap: on
line source
"""Collected utility functions, many are taken from Drew's utils.py in Cuisine CVS and Hiss's Utility.py.""" from __future__ import generators import sys __author__ = "David McClosky <dmcc@bigasterisk.com>, " + \ "Drew Perttula <drewp@bigasterisk.com>" __cvsid__ = "$Id: TLUtility.py,v 1.1 2003/05/25 08:25:35 dmcc Exp $" __version__ = "$Revision: 1.1 $"[11:-2] def make_attributes_from_args(*argnames): """ This function simulates the effect of running self.foo=foo for each of the given argument names ('foo' in the example just now). Now you can write: def __init__(self,foo,bar,baz): copy_to_attributes('foo','bar','baz') ... instead of: def __init__(self,foo,bar,baz): self.foo=foo self.bar=bar self.baz=baz ... """ callerlocals=sys._getframe(1).f_locals callerself=callerlocals['self'] for a in argnames: try: setattr(callerself,a,callerlocals[a]) except KeyError: raise KeyError, "Function has no argument '%s'" % a def enumerate(*collections): """Generates an indexed series: (0,coll[0]), (1,coll[1]) ... this is a multi-list version of the code from the PEP: enumerate(a,b) gives (0,a[0],b[0]), (1,a[1],b[1]) ... """ i = 0 iters = [iter(collection) for collection in collections] while 1: yield [i,] + [iterator.next() for iterator in iters] i += 1 def dumpobj(o): """Prints all the object's non-callable attributes""" print repr(o) for a in [x for x in dir(o) if not callable(getattr(o, x))]: try: print " %20s: %s " % (a, getattr(o, a)) except: pass print "" def dict_filter_update(d, **newitems): """Adds a set of new keys and values to dictionary 'd' if the values are true: >>> some_dict = {} >>> dict_filter_update(some_dict, a=None, b=0, c=1, e={}, s='hello') >>> some_dict {'c': 1, 's': 'hello'} """ for k, v in newitems.items(): if v: d[k] = v def try_get_logger(channel): """Tries to get a logger with the channel 'channel'. Will return a silent DummyClass if logging is not available.""" try: import logging log = logging.getLogger(channel) except ImportError: log = DummyClass() return log class DummyClass: """A class that can be instantiated but never used. It is intended to be replaced when information is available. Usage: >>> d = DummyClass(1, 2, x="xyzzy") >>> d.someattr Traceback (most recent call last): File "<stdin>", line 1, in ? File "Utility.py", line 33, in __getattr__ raise AttributeError, "Attempted usage of a DummyClass: %s" % key AttributeError: Attempted usage of a DummyClass: someattr >>> d.somefunction() Traceback (most recent call last): File "<stdin>", line 1, in ? File "Utility.py", line 33, in __getattr__ raise AttributeError, "Attempted usage of a DummyClass: %s" % key AttributeError: Attempted usage of a DummyClass: somefunction""" def __init__(self, use_warnings=1, raise_exceptions=0, **kw): """Constructs a DummyClass""" make_attributes_from_args('use_warnings', 'raise_exceptions') def __getattr__(self, key): """Raises an exception to warn the user that a Dummy is not being replaced in time.""" if key == "__del__": return msg = "Attempted usage of '%s' on a DummyClass" % key if self.use_warnings: import warnings warnings.warn(msg) if self.raise_exceptions: raise AttributeError, msg return lambda *args, **kw: self.bogus_function() def bogus_function(self): pass class ClassyDict(dict): """A dict that accepts attribute-style access as well (for keys that are legal names, obviously). I used to call this Struct, but chose the more colorful name to avoid confusion with the struct module.""" def __getattr__(self, a): return self[a] def __setattr__(self, a, v): self[a] = v def __delattr__(self, a): del self[a] def trace(func): """Good old fashioned Lisp-style tracing. Example usage: >>> def f(a, b, c=3): >>> print a, b, c >>> return a + b >>> >>> >>> f = trace(f) >>> f(1, 2) |>> f called args: [1, 2] 1 2 3 <<| f returned 3 3 TODO: print out default keywords (maybe) indent for recursive call like the lisp version (possible use of generators?)""" name = func.func_name def tracer(*args, **kw): s = '|>> %s called' % name if args: s += ' args: %r' % list(args) if kw: s += ' kw: %r' % kw print s ret = func(*args, **kw) print '<<| %s returned %s' % (name, ret) return ret return tracer # these functions taken from old light8 code def dict_max(*dicts): """ ({'a' : 5, 'b' : 9}, {'a' : 10, 'b' : 4}) returns ==> {'a' : 10, 'b' : 9} """ newdict = {} for d in dicts: for k,v in d.items(): newdict[k] = max(v, newdict.get(k, 0)) return newdict def dict_scale(d,scl): """scales all values in dict and returns a new dict""" return dict([(k,v*scl) for k,v in d.items()]) def dict_subset(d, dkeys, default=0): """Subset of dictionary d: only the keys in dkeys. If you plan on omitting keys, make sure you like the default.""" newd = {} # dirty variables! for k in dkeys: newd[k] = d.get(k, default) return newd # functions specific to Timeline # TBD def last_less_than(array, x): """array must be sorted""" best = None for elt in array: if elt <= x: best = elt elif best is not None: return best return best # TBD def first_greater_than(array, x): """array must be sorted""" array_rev = array[:] array_rev.reverse() best = None for elt in array_rev: if elt >= x: best = elt elif best is not None: return best return best