Welcome, guest | Sign In | My Account | Store | Cart
def graphWalker(node, getChildren, toEvaluate, backPack = None):
    """
    A generator that (lazily, recursively) applies an operation to a directed graph structure.
    
    @param node the graph node where we start
    @param getChildren a callable f such that f(node) returns the child nodes of node
    @param toEvaluate a callable g such that the result rr for a node is rr = g(node, backPack)[0]
    @param backPack a partial result that is carried along and may change as the graph is traversed. 
            g(node, backPack)[1] is passed on to the child nodes.
    @returns an iterator over the results of applying toEvaluate to every node in the tree
    
    @see walkTest() for an example.
    """
    rr = toEvaluate(node, backPack)
    yield rr[0]
    for child in getChildren(node):
        for result in graphWalker(child, getChildren, toEvaluate, rr[1]):
            yield result



"""

SAMPLE (TEST) CODE FOLLOWS:

"""

import os
import stat
       
def walkTest(root = os.getcwd(), recursionLimit = 3):
    """
    A walk that prints all the relative path of all files in a file system rooted 
    at the current directory with respect to that directory. Goes no deeper than
    recursionLimit.
    """
    
    def te(node, rl):
        root, visitedNodes, name = node[:3]
        if rl < 0: raise StopIteration
        return (
                os.sep.join(visitedNodes + [name])[1:],
                rl - 1
                )
    
    def absPath(node):
        return os.sep.join(
                               [node[0]] + node[1] + [node[2]]
                               )
    
    def isdir(path):
        """
        @param path the absolute (?) path of the file
        """
        return stat.S_ISDIR(os.stat(
                                    path
                                    )[stat.ST_MODE])
        
    def gc(node):
        
        root, visitedNodes, name, depth = node
        
        ab = absPath(node)
        if not isdir(ab): return []
        

        return [
                (
                 root,
                 visitedNodes + [name],
                 cc,
                 depth + 1
                 )
                for cc in
                os.listdir(ab)]

    return graphWalker((root, [], "", 0), gc, te, recursionLimit)

if __name__ == "__main__":
    for rr in walkTest():
        print rr
    

History

  • revision 2 (17 years ago)
  • previous revisions are not available