Files @ f3d65ae17a8f
Branch filter:

Location: light9/flax/TLUtility.py - annotation

drewp
these are mostly replaced with guys&dolls material (effects were not touched)
these are mostly replaced with guys&dolls material (effects were not touched)
dance show went to a new dir called Configs/
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
45b12307c695
"""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