Files
@ 053889940418
Branch filter:
Location: light9/flax/TLUtility.py
053889940418
6.1 KiB
text/x-python
some changes to allow integration into rsn. more needed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 | """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
|