[Zope] Data aggregation within a tree

Brad Knotwell b.knotwell@f5.com
Tue, 16 Jul 2002 17:35:20 -0700


Dieter Maurer writes:
 > Brad Knotwell writes:
 >  > My application has two custom objects types (one of them is
 >  > folderish).  I'm trying to add a view to the folderish object that'll
 >  > aggregate statistics information on the lower-levels of the tree.
 >  > 
 >  > Specifically, I'd like a flavor for how to do the following:
 >  > 
 >  >     traverse a tree w/o rendering it
 >  >     test an object's type
 >  >     if an object is a specific type:
 >  >        update counters appropriately based on the internal state of
 >  >        the object
 >  > 
 >  >     render the results
 >  > 
 >  > Since I only want to traverse the tree (not render it), am I correct 
 >  > in presuming dtml-tree isn't my friend in this case and I'll need to
 >  > work in straight Python instead?
 > You are correct.
 > 
 > Look at the code of "OFS.FindSupport.ZopeFind" and see how it implements
 > traversal.
 > 
 > Do the same in either an External Method or a Python Script (here
 > several access restrictions will apply).
 > 
 > 
 > Dieter

For our other readers, here's some example code to traverse a tree and
aggregate information (based on meta_type as well as the Status field
of my custom ZClass).  I had planned to create a Statistics class in
the script, but I got permissions errors when I tried to instantiate
the object.  As a result, I keep state in the function and the code
looks a trifle odd.

--Brad

def traverseTree(tree_root):
    untested = passed = failed = notest = 0
    for object in tree_root.objectValues():
        if object.meta_type == 'Test Case Folder':
            subres = traverseTree(object)
	    untested = untested + subres[0]
            passed = passed + subres[1]
            failed = failed + subres[2]
            notest = notest + subres[3]
        elif object.meta_type == 'Test Case':
            if object.Status == 'Untested':
                untested = untested + 1
            elif object.Status == 'Pass':
                passed = passed + 1
            elif object.Status == 'Fail':
                failed = failed + 1
            elif object.Status == 'Notest':
                notest = notest + 1
            else:
                untested = untested + 1

    return(untested,passed,failed,notest)

print 'Untested(%d):Passed(%d):Failed(%d):Notest(%d)' % traverseTree(context)
return printed