from mxTools import *
from mxTools import __version__
from xmap import *

#
# Experimental function prototypes
#

def sortedby(sequence,*indices):

    """ sortedby(sequence,*indices)
    
        Returns a list representing the sequence sorted ascending by
        the fields pointed to by the additional arguments
        (indices). sequence must be at least two-dimensional, e.g. a
        list of tuples.

    """
    x = apply(tuples,tuple(extract(lists(sequence),indices))+(sequence,))
    x.sort()
    return map(get,x,(-1,)*len(x))

def projection(sequence,*indices):

    """ projection(sequence,*indices)

        Experimental function that extracts columns from tables
        (sequence of sequences). If only one index is given, a list of
        all elements in that dimension is returned. For more indices,
        the list will contain tuples with entries for each given
        dimension.

    """
    if len(indices) == 1:
	return lists(sequence)[indices[0]]
    else:
	return tuples(extract(lists(sequence),indices))

def frange(x,y,ticks):

    """frange(x,y,ticks)

       Returns a list of ticks equidistant floating point values from
       the interval [x,y] such that the first is equal to x and the
       last equal to y.

    """
    l = [x] * ticks
    fticks = float(ticks-1)
    diff = y - x
    for i,value in irange(l):
        l[i] = value + diff*(i/fticks)
    return l

import operator,types

def issequence(obj,

               isSequenceType=operator.isSequenceType,
               InstanceType=types.InstanceType):

    """issequence(obj)

       Returns 1 iff obj defines the sequence protocol, o
       otherwise. For instances at least __getitem__ must be defined.
    
    """
    rc = isSequenceType(obj)
    if rc and type(obj) == InstanceType:
        rc = hasattr(obj,'__getitem__')
    return rc

del operator,types

def defined(name):

    """ defined(name)

        Return 1/0 depending on whether name is a defined symbol
        in the caller's namespace.

    """
    import sys
    frame = sys.cur_frame(1)
    # Look up the symbol name
    ok = frame.f_locals.has_key(name) or \
	 frame.f_globals.has_key(name) or \
	 frame.f_builtins.has_key(name)
    del frame
    return ok

def acqchain(obj):

    """ acqchain(obj)

        Returns a list of object representing the acquisition
        chain that the new builtin acquire() would scan.

	The order is top to bottom, with obj always being the
	last entry in the list.

    """
    l = []
    append = l.append
    while obj:
	append(obj)
	obj = obj.baseobj
    l.reverse()
    return l

# Constants
True = (1==1)
False = (1==0)
