/[ascend]/trunk/pygtk/diagnose.py
ViewVC logotype

Diff of /trunk/pygtk/diagnose.py

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

trunk/pygtk/interface/diagnose.py revision 286 by johnpye, Thu Feb 9 07:36:39 2006 UTC trunk/pygtk/diagnose.py revision 2495 by aakash, Tue Aug 16 11:35:08 2011 UTC
# Line 1  Line 1 
1  import gtk  import gtk
2  import gtk.glade  import ascpy
 import ascend  
3  from itertools import groupby  from itertools import groupby
4  from operator import itemgetter  from operator import itemgetter
5  import math  import math
6  import re  import re
7    
8    import config
9    from infodialog import *
10    
11  ZOOM_RE = re.compile(r"([0-9]+)\s*%?")  ZOOM_RE = re.compile(r"([0-9]+)\s*%?")
12  MAX_ZOOM_SIZE = 2000  MAX_ZOOM_SIZE = float(2000) # float
13  MAX_ZOOM_RATIO = 16  MAX_ZOOM_RATIO = float(16) # float
14    AT_BOUND_TOL = 0.0001;
15    
16  class DiagnoseWindow:  class DiagnoseWindow:
17      def __init__(self,GLADE_FILE,browser,block=0):      def __init__(self,browser,block=0):
18          self.browser=browser          self.browser=browser
19          _xml = gtk.glade.XML(GLADE_FILE,"diagnosewin")          self.browser.builder.add_objects_from_file(self.browser.glade_file, ["diagnosewin"])
20          _xml.signal_autoconnect(self)            self.browser.builder.connect_signals(self)
21            self.window = self.browser.builder.get_object("diagnosewin")
22            self.window.set_transient_for(self.browser.window)
23    
24            try:
25                _icon = gtk.Image()
26                _iconpath = browser.assets_dir+'diagnose'+config.ICON_EXTENSION
27                print "ICON PATH =",_iconpath
28                _icon.set_from_file(_iconpath)
29                print "ICON = ",_icon
30                self.window.set_icon(_icon)
31            except:
32                pass
33            
34            self.blockstatus = self.browser.builder.get_object("blockstatustext")
35    
36          self.window = _xml.get_widget("diagnosewin")          self.imagescroll = self.browser.builder.get_object("imagescroll")
37          self.imagescroll = _xml.get_widget("imagescroll")          self.image = self.browser.builder.get_object("image")
38          self.image = _xml.get_widget("image")          self.blockentry = self.browser.builder.get_object("blockentry")
39          self.blockentry = _xml.get_widget("blockentry")          self.zoomentry = self.browser.builder.get_object("zoomentry")
40          self.zoomentry = _xml.get_widget("zoomentry")  
41            self.var = None; self.rel = None
42          self.varname = _xml.get_widget("varname");          self.varname = self.browser.builder.get_object("varname1")
43          self.varval = _xml.get_widget("varval");          self.varval = self.browser.builder.get_object("varval")
44          self.relname = _xml.get_widget("relname");          self.varinfobutton = self.browser.builder.get_object("varinfobutton")
45          self.relresid = _xml.get_widget("relresid");          self.relname = self.browser.builder.get_object("relname1")
46            self.relresid = self.browser.builder.get_object("relresid")
47            self.relinfobutton = self.browser.builder.get_object("relinfobutton")
48    
49          self.varview = _xml.get_widget("varview")          self.varview = self.browser.builder.get_object("varview")
50          self.varbuf = gtk.TextBuffer()          self.varbuf = gtk.TextBuffer()
51          self.varview.set_buffer(self.varbuf)          self.varview.set_buffer(self.varbuf)
52          self.varcollapsed = _xml.get_widget("varcollapsed")          self.varcollapsed = self.browser.builder.get_object("varcollapsed")
53          self.relview = _xml.get_widget("relview")            self.relview = self.browser.builder.get_object("relview")  
54          self.relcollapsed = _xml.get_widget("relcollapsed")          self.relcollapsed = self.browser.builder.get_object("relcollapsed")
55          self.relvalues = _xml.get_widget("relvalues")          self.relvalues = self.browser.builder.get_object("relvalues")
56          self.rellabels = _xml.get_widget("rellabels")          self.rellabels = self.browser.builder.get_object("rellabels")
57          self.relrels = _xml.get_widget("relrels")          self.relrels = self.browser.builder.get_object("relrels")
58          self.relresids = _xml.get_widget("relresids")          self.relresids = self.browser.builder.get_object("relresids")
59          self.relbuf = gtk.TextBuffer()          self.relbuf = gtk.TextBuffer()
60          self.relview.set_buffer(self.relbuf)          self.relview.set_buffer(self.relbuf)
61    
62            self.im = None
63          self.block = 0          self.block = 0
64            self.apply_prefs()
65    
66          self.prepare_data()          self.prepare_data()
67          self.fill_values(block) # block zero          self.fill_values(block) # block zero
68    
# Line 48  class DiagnoseWindow: Line 70  class DiagnoseWindow:
70          self.window.run()          self.window.run()
71          self.window.hide()          self.window.hide()
72    
73        def apply_prefs(self):
74            vc = self.browser.prefs.getBoolPref("Diagnose","varcollapsed",True)
75    
76            print "VARCOLLAPSED =",vc
77            self.varcollapsed.set_active(vc)
78            self.relcollapsed.set_active(self.browser.prefs.getBoolPref("Diagnose","relcollapsed",True))
79    
80      def prepare_data(self):      def prepare_data(self):
81          # convert incidence map to pylab numarray type:          # convert incidence map to pylab numarray type:
82          print "PREPARING DATA"          print "PREPARING DATA to be loaded"
83          self.im = self.browser.sim.getIncidenceMatrix()          self.im = self.browser.sim.getIncidenceMatrix()
84          self.data = self.im.getIncidenceData()          self.data = self.im.getIncidenceData()
85          print "DATA LOADED"          print "DATA LOADED"
# Line 58  class DiagnoseWindow: Line 87  class DiagnoseWindow:
87          self.zoom=1;          self.zoom=1;
88            
89      def fill_values(self, block):      def fill_values(self, block):
90            
91          try:          try:
92                if self.im.getNumBlocks()==0:
93                    print "NO BLOCKS!"
94                    self.image.set_from_stock(gtk.STOCK_DIALOG_ERROR
95                        ,gtk.ICON_SIZE_DIALOG
96                    )
97                    self.browser.reporter.reportError(
98                        "Can't 'Diagnose blocks' until solver has been used."
99                    )
100                    return;
101              rl,cl,rh,ch = self.im.getBlockLocation(block)              rl,cl,rh,ch = self.im.getBlockLocation(block)
102          except IndexError:          except IndexError:
103              self.blockentry.set_text(str(self.block))              if block >= self.im.getNumBlocks():
104              return                  block = self.im.getNumBlocks() - 1
105          except RuntimeError:                  rl,cl,rh,ch = self.im.getBlockLocation(block)
106                else:              
107                    print "BLOCK INDEX ERROR: block =",block
108                    self.blockentry.set_text(str(self.block))
109                    return
110            except RuntimeError,e:
111                print "ERROR GETTING BLOCK LOCATION:",str(e)
112              self.blockentry.set_text(str(self.block))              self.blockentry.set_text(str(self.block))
113              return              return
114    
# Line 78  class DiagnoseWindow: Line 123  class DiagnoseWindow:
123          nr = int(rh-rl+1);          nr = int(rh-rl+1);
124          nc = int(ch-cl+1);          nc = int(ch-cl+1);
125    
126          #print "STARTING IMAGE CREATION"          print "STARTING IMAGE CREATION"
127          # refer http://pygtk.org/pygtk2tutorial/sec-DrawingMethods.html          # refer http://pygtk.org/pygtk2tutorial/sec-DrawingMethods.html
128          c = chr(255)          c = chr(255)
129          b = nr*nc*3*[c]          b = nr*nc*3*[c]
# Line 102  class DiagnoseWindow: Line 147  class DiagnoseWindow:
147              pos = rowstride*r + 3*c              pos = rowstride*r + 3*c
148              dot = blackdot;              dot = blackdot;
149              var = self.im.getVariable(i.col);              var = self.im.getVariable(i.col);
150              rat = var.getValue() / var.getNominal()              if abs( (var.getValue()-var.getUpperBound())/ var.getNominal() )  < AT_BOUND_TOL:
151              if rat!=0:                  dot = reddot
152                  try:              elif abs( var.getValue() - var.getLowerBound() ) / var.getNominal() < AT_BOUND_TOL:
153                      val = abs(rat)                  dot = reddot
154                      if abs(rat) > 1000:              else:
155                          dot = hotpinkdot                  rat = var.getValue() / var.getNominal()
156                      elif abs(rat) > 10:                  if rat!=0:
157                          dot = orangedot                      try:
158                      elif abs(rat) < 0.001:                          val = abs(rat)
159                          dot = brightbluedot                          if abs(rat) > 1000:
160                      elif abs(rat) < 10 and abs(rat) > 0.1:                              dot = hotpinkdot
161                          dot = greendot                          elif abs(rat) > 10:
162                      elif abs(rat) > 0.001 and abs(rat) < 0.1:                              dot = orangedot
163                          dot = bluegreendot                          elif abs(rat) < 0.001:
164                      else:                              dot = brightbluedot
165                          dot = blackdot                          elif abs(rat) < 10 and abs(rat) > 0.1:
166                  except ValueError, e:                              dot = greendot
167                      pass                          elif abs(rat) > 0.001 and abs(rat) < 0.1:
168                                dot = bluegreendot
169                            else:
170                                dot = blackdot
171                        except ValueError, e:
172                            pass
173              #print "DOT: ",dot              #print "DOT: ",dot
174              b[pos], b[pos+1], b[pos+2] = dot              b[pos], b[pos+1], b[pos+2] = dot
175    
176          d = ''.join(b)          d = ''.join(b)
177    
178          #print "DONE IMAGE CREATION"          print "DONE IMAGE CREATION"
179            
180          self.pixbuf = gtk.gdk.pixbuf_new_from_data(d, gtk.gdk.COLORSPACE_RGB, False, 8 \          self.pixbuf = gtk.gdk.pixbuf_new_from_data(d, gtk.gdk.COLORSPACE_RGB, False, 8 \
181                  , nc, nr, rowstride);                  , nc, nr, rowstride);
# Line 135  class DiagnoseWindow: Line 185  class DiagnoseWindow:
185          self.zoom = -1 # to fit, up to max 16x          self.zoom = -1 # to fit, up to max 16x
186          self.do_zoom()          self.do_zoom()
187    
188          #print "DONE IMAGE TRANSFER TO SERVER"          print "DONE IMAGE TRANSFER TO SERVER"
189    
190          self.fill_var_names()          self.fill_var_names()
191          self.fill_rel_names()          self.fill_rel_names()
192            self.fill_block_status()
193            
194          self.varname.set_text("");          self.fill_selection_info()
195          self.varval.set_text("");  
196          self.relname.set_text("");          print "DONE FILL VALUES"
         self.relresid.set_text("");  
197    
198        def fill_selection_info(self):
199            if self.var:
200                self.varname.set_text(self.var.getName())
201                self.varval.set_text(str(self.var.getValue()))
202                self.varinfobutton.set_sensitive(True)
203            else:
204                self.varname.set_text("")
205                self.varval.set_text("")
206                self.varinfobutton.set_sensitive(False)
207    
208            if self.rel:
209                self.relname.set_text(self.rel.getName())
210                self.relresid.set_text(str(self.rel.getResidual()))
211                self.relinfobutton.set_sensitive(True)
212            else:
213                self.relname.set_text("")
214                self.relresid.set_text("")
215                self.relinfobutton.set_sensitive(False)
216    
217      def do_zoom(self):      def do_zoom(self):
218          if self.zoom == -1:          if self.zoom == -1:
# Line 152  class DiagnoseWindow: Line 220  class DiagnoseWindow:
220              #print "SCALE TO FIX, w=%d, h=%d" % (w,h)              #print "SCALE TO FIX, w=%d, h=%d" % (w,h)
221              if self.nc/self.nr > w/h:              if self.nc/self.nr > w/h:
222                  # a 'wide' image                      # a 'wide' image    
223                  self.zoom = w / self.nc                  self.zoom = float(w) / self.nc
224              else:              else:
225                  self.zoom = h / self.nr                  self.zoom = float(h) / self.nr
226    
227            #self.browser.reporter.reportNote("Diagnose window: preliminary calculated zoom = %f (nr = %d, nc = %d)" % (self.zoom, self.nr, self.nc))
228            
229    
230          if self.zoom > MAX_ZOOM_RATIO:          if self.zoom > MAX_ZOOM_RATIO:
231              self.zoom = MAX_ZOOM_RATIO              self.zoom = MAX_ZOOM_RATIO
232    
233          if self.zoom * self.nc > MAX_ZOOM_SIZE or self.zoom * self.nr > MAX_ZOOM_SIZE:          if self.zoom * self.nc > MAX_ZOOM_SIZE or self.zoom * self.nr > MAX_ZOOM_SIZE:
234                self.browser.reporter.reportNote("image is too big, reducing to MAX_ZOOM_SIZE = %f" % MAX_ZOOM_SIZE);
235              self.zoom = MAX_ZOOM_SIZE / max(self.nc,self.nr)              self.zoom = MAX_ZOOM_SIZE / max(self.nc,self.nr)
236    
237            #self.browser.reporter.reportNote("Diagnose window: matrix zoom = %f" % self.zoom)
238          w = int(self.zoom * self.nc);          w = int(self.zoom * self.nc);
239          h = int(self.zoom * self.nr);          h = int(self.zoom * self.nr);
240                            
# Line 174  class DiagnoseWindow: Line 247  class DiagnoseWindow:
247                    
248          self.image.set_from_pixbuf(pb1)          self.image.set_from_pixbuf(pb1)
249    
250        def fill_block_status(self):
251            print "FILL BLOCK STATUS"
252            s = self.im.getBlockStatus(self.block)
253            ss = "Failed"
254            if s == ascpy.IM_CONVERGED:
255                ss = "Converged"
256            elif s == ascpy.IM_NOT_YET_ATTEMPTED:
257                ss = "Not attempted yet"
258            elif s == ascpy.IM_OVER_TIME:
259                ss += " (time limit)"
260            elif s == ascpy.IM_OVER_ITER:
261                ss += " (iter limit)"
262            self.blockstatus.set_text(ss);
263            
264    
265      def fill_var_names(self):      def fill_var_names(self):
266            print "FILL VAR NAMES"
267    
268          names = [str(i) for i in self.im.getBlockVars(self.block)]          names = [str(i) for i in self.im.getBlockVars(self.block)]
269    
270            #print "NAMES:",names
271    
272          if self.varcollapsed.get_active():          if self.varcollapsed.get_active():
273              res = collapse(names)              res = reduce(names)
274              rows = []              rows = []
275              for k in res:              for k in res:
276                  if k=="":                  if k=="":
# Line 190  class DiagnoseWindow: Line 283  class DiagnoseWindow:
283              text = "\n".join(names)              text = "\n".join(names)
284          self.varbuf.set_text(text)          self.varbuf.set_text(text)
285    
286            print "DONE VAR NAMES"
287    
288      def fill_rel_names(self):      def fill_rel_names(self):
289          names = [str(i) for i in self.im.getBlockRels(self.block)]          print "REL NAMES"
290    
291            rels = self.im.getBlockRels(self.block)
292    
293            print "GOT RELS, NOW GETTING NAMES"
294    
295            names = [str(i) for i in rels]
296    
297            #print "NAMES =",names
298    
299          if self.relcollapsed.get_active():          if self.relcollapsed.get_active():
300              text = "\n".join(collapse(names))              res = reduce(names)
301                rows = []
302                for k in res:
303                    if k=="":
304                        for r in res[k]:
305                            rows.append(r)
306                    else:
307                        rows.append( '%s:\n\t%s' % (k, "\n\t".join(res[k])) )
308                text = "\n".join(rows)
309          else:          else:
310              text = "\n".join(names)              text = "\n".join(names)
311          self.relbuf.set_text(text)          self.relbuf.set_text(text)
312    
313            print "DONE REL NAMES"
314    
315      def set_block(self, block):      def set_block(self, block):
316          self.fill_values(block)          self.fill_values(block)
317    
# Line 211  class DiagnoseWindow: Line 325  class DiagnoseWindow:
325          if c > self.ch or r > self.rh:          if c > self.ch or r > self.rh:
326              #print "OUT OF RANGE"              #print "OUT OF RANGE"
327              return              return
328          var = self.im.getVariable(c)          self.var = self.im.getVariable(c)
329          self.varname.set_text(var.getName())          self.rel = self.im.getRelation(r)
330          self.varval.set_text(str(var.getValue()))          self.fill_selection_info()
         rel = self.im.getRelation(r)  
         self.relname.set_text(rel.getName())  
         self.relresid.set_text(str(rel.getResidual()))  
331    
332      # GUI EVENT HOOKS-----------------------------------------------------------      # GUI EVENT HOOKS-----------------------------------------------------------
333    
334        def on_diagnosewin_close(self,*args):
335            self.window.response(gtk.RESPONSE_CLOSE);
336    
337        # incidence data view
338    
339      def on_varcollapsed_toggled(self,*args):      def on_varcollapsed_toggled(self,*args):
340          print "COLLAPSED-TOGGLED"          vc = self.varcollapsed.get_active()
341          self.fill_var_names()          self.browser.prefs.setBoolPref("Diagnose","varcollapsed",vc)    
342            if self.im:
343                self.fill_var_names()
344    
345      def on_relcollapsed_toggled(self,*args):      def on_relcollapsed_toggled(self,*args):
346          print "COLLAPSED-TOGGLED"          rc = self.varcollapsed.get_active()
347          self.fill_rel_names()          self.browser.prefs.setBoolPref("Diagnose","relcollapsed",rc)    
348            if self.im:
349                self.fill_rel_names()
350    
351        # detailed information about vars and rels (solver-side information!)
352    
353        def on_varinfobutton_clicked(self,*args):
354            title = "Variable '%s'" % self.var
355            text = "%s\n%s\n" % (title,"(from the solver's view)")
356    
357            _rows = {
358                "Value": self.var.getValue()
359                ,"Nominal": self.var.getNominal()
360                ,"Lower bound": self.var.getLowerBound()
361                ,"Upper bound": self.var.getUpperBound()
362            }
363            for k,v in _rows.iteritems():
364                text += "\n  %s\t%s" % (k,value_human(v))
365            
366            text += "\n\nIncident with %d relations:" % self.var.getNumIncidentRelations()
367            for r in self.var.getIncidentRelations():
368                text += "\n  %s" % r.getName()
369    
370            _dialog = InfoDialog(self.browser,self.window,text,title,tabs=(150,300))
371            _dialog.run()
372    
373        def on_relinfobutton_clicked(self,*args):
374            title = "Relation '%s'" % self.rel
375            text = "%s\n%s\n" % (title,"(from the solver's view)")
376            text += "\n  %s\t%15f" % ("Residual", self.rel.getResidual())
377    
378            text += "\n\nRelation expression:\n"
379            text += self.rel.getRelationAsString()
380    
381            text += "\n\nIncident with %d variables:" % self.rel.getNumIncidentVariables()
382            for v in self.rel.getIncidentVariables():
383                text += "\n  %s\t= %s" % ( v.getName(),value_human(v.getValue()) )
384    
385            _dialog = InfoDialog(self.browser,self.window,text,title,tabs=(150,300))
386            _dialog.run()
387            
388    
389        # block navigation
390    
391      def on_nextbutton_clicked(self,*args):      def on_nextbutton_clicked(self,*args):
392          self.set_block(self.block + 1)          self.set_block(self.block + 1)
393    
394      def on_prevbutton_clicked(self,*args):      def on_prevbutton_clicked(self,*args):
395          self.set_block(self.block - 1)                self.set_block(self.block - 1)  
396    
397        def on_prevbigbutton_clicked(self,*args):
398            b = self.block - 1
399            while b >= 0:
400                rl,cl,rh,ch = self.im.getBlockLocation(b)
401                if rh-rl > 0 or ch-cl>0:
402                    self.set_block(b)
403                    return
404                b = b - 1
405            print "NO PRECEDING 'BIG' BLOCKS"
406            
407        def on_nextbigbutton_clicked(self,*args):
408            b = self.block + 1
409            n = self.im.getNumBlocks()
410            while b < n:
411                rl,cl,rh,ch = self.im.getBlockLocation(b)
412                if rh-rl > 0 or ch-cl>0:
413                    self.set_block(b)
414                    return
415                b = b + 1
416            print "NO FOLLOWING 'BIG' BLOCKS"
417        
418      def on_blockentry_key_press_event(self,widget,event):      def on_blockentry_key_press_event(self,widget,event):
419          keyname = gtk.gdk.keyval_name(event.keyval)          keyname = gtk.gdk.keyval_name(event.keyval)
420          print "KEY ",keyname          print "KEY ",keyname
421          if keyname=="Return":          if keyname=="Return":
422              self.set_block( int(self.blockentry.get_text()) )              self.set_block( int(self.blockentry.get_text()) )
423    
424        # zoom in and out
425    
426      def on_zoominbutton_clicked(self,*args):      def on_zoominbutton_clicked(self,*args):
427          z = int( math.log(self.zoom)/math.log(2) )          z = int( math.log(self.zoom)/math.log(2) )
428          z = pow(2,z + 1);          z = pow(2,z + 1);
# Line 262  class DiagnoseWindow: Line 445  class DiagnoseWindow:
445                  print m                  print m
446              self.set_zoom( int(self.zoomentry.get_text()) )              self.set_zoom( int(self.zoomentry.get_text()) )
447    
448        # clicking in incidence matrix to get updated information at RHS
449    
450      def on_imageevent_motion_notify_event(self,widget,event):      def on_imageevent_motion_notify_event(self,widget,event):
451          self.show_cursor(event.x, event.y)          self.show_cursor(event.x, event.y)
452    
# Line 269  class DiagnoseWindow: Line 454  class DiagnoseWindow:
454          self.show_cursor(event.x, event.y)          self.show_cursor(event.x, event.y)
455    
456    
457  # The following is from  def value_human(v):
458        if v==0 or abs( math.log10(abs(v)) )<8:
459            return "%f" % v
460        return "%e" % v
461    
462    #---------------------------------------
463    # Procedures to 'fold' a list of items from a hierarchy
464  # http://www.experts-exchange.com/Programming/Programming_Languages/Python/Q_21719649.html  # http://www.experts-exchange.com/Programming/Programming_Languages/Python/Q_21719649.html
465  # it's still buggy.  # It's still buggy, I think
466    
467  def fold(data):  def fold(data):
468      """ fold sorted numeric sequence data into ranged representation:      """ fold sorted numeric sequence data into ranged representation:
# Line 279  def fold(data): Line 470  def fold(data):
470      '[1,4-6,10,15-18,22,25-28]'      '[1,4-6,10,15-18,22,25-28]'
471      """      """
472      folded = []      folded = []
473      for k, g in groupby(enumerate(data), lambda (i,x):i-x):      for k, g in groupby(enumerate(sorted(data)), lambda (i,x):i-x):
474          seq = map(itemgetter(1), g)          seq = map(itemgetter(1), g)
475          if len(seq) > 1:          if len(seq) > 1:
476              x = '%s-%s' % (seq[0], seq[-1])              x = '%s-%s' % (seq[0], seq[-1])
# Line 288  def fold(data): Line 479  def fold(data):
479          folded.append(x)          folded.append(x)
480      return folded and '[%s]' % ','.join(folded) or ''      return folded and '[%s]' % ','.join(folded) or ''
481    
482  def collapse(names):  def reduce(names):
483      """reduce a list of items into something more readable:      """reduce a list of items nto something more readable:
484      >>> data = 'C.x C.p C.T C.delta[1] C.delta[2] C.delta[3] C.sat.x C.sat.p C.h C.delta[5]'.split()      >>> data = 'C.x C.p C.T C.delta[1] C.delta[2] C.delta[3] C.sat.x C.sat.p C.h C.delta[5]'.split()
485      >>> res = reduce(data)      >>> res = reduce(data)
486      >>> for k in sorted(res):      >>> for k in sorted(res):
# Line 297  def collapse(names): Line 488  def collapse(names):
488      C: T, delta[1-3,5], h, p, x      C: T, delta[1-3,5], h, p, x
489      C.sat: p, x      C.sat: p, x
490      """      """
491      data = sorted([n.split('.') for n in names], key=len)      data = sorted([n.split('.') for n in sorted(names)], key=len)
492      res = {}      res = {}
493      for k, g in groupby(data, lambda x: len(x)):      for k, g in groupby(data, lambda x: len(x)):
494          item = g.next()          if k == 1:
495          assert len(item) == k              indexed = {}
496          key = '.'.join(item[:-1]) or ''              seq = set([get(indexed, item) for item in g])
497          indexed = {}              res['[global]'] = [ i+fold(indexed.get(i, [])) for i in sorted(seq) ]
498          seq = set([get(indexed, item)])          else:
499          for item in g:              for key, g1 in groupby(g, lambda x: '.'.join(x[:-1])):
500              seq.add(get(indexed, item))                  indexed = {}
501          res[key] = [i+fold(indexed.get(i, [])) for i in sorted(seq)]                  seq = set(get(indexed, item) for item in g1)
502                    res[key] = [ i+fold(indexed.get(i, [])) for i in sorted(seq) ]
503      return res      return res
504    
505  def get(indexed, item):  def get(indexed, item):
# Line 316  def get(indexed, item): Line 508  def get(indexed, item):
508          item, idx = item[:-1].split('[')          item, idx = item[:-1].split('[')
509          indexed.setdefault(item, []).append(int(idx))          indexed.setdefault(item, []).append(int(idx))
510      return item      return item
511    

Legend:
Removed from v.286  
changed lines
  Added in v.2495

john.pye@anu.edu.au
ViewVC Help
Powered by ViewVC 1.1.22