Saturday, January 22, 2005
looking back

I've been keeping a "lab notebook" about the Python integration work. I keep it in an outline that I edit in Frontier. It's been a good exercise. I started to review it today, and it's interesting to see how the project has progressed.

One of the things I like the most about reviewing the progress is the evidence of roads not taken. Several places in the notebook I talk about paths of development that ultimately turned out to be wrong. They didn't start wrong though. Quite often they were useful as bootstraps for the project. I used my initial Python Tool work to work around the fact that I didn't yet know how to make the Frontier scripting windows do my bidding. I wrote certain Frontier verbs to help me with table navigation that no longer exist in the project.

The most interesting thing about this project has been watching the scaffolding fall away as the correct way to approach the system became apparent. I love that.

Now I'm to the point where I'm writing Python support code to flesh out the system. It's wonderfully meta.

Keeping a lab notebook has been one of the best choices of the project. It has been useful to keep track of lessons learned, of problems overcome, of progress made. I can look back and see where I was stuck, and see how I got past the obstacles. In many ways it's just as useful for moral support as it is for technical support.

I've been thinking that after Sidewinder makes it into the standard Frontier build, I would format up the notebook and publish it up on the web.



4:59:02 PM    comments ()  trackback []  
example python code in frontier

Just for my own entertainment, and for anyone who is interested in this sort of thing, here is the first slightly non-trivial (only slightly) Python code I played with in the Python/Frontier environment. It is an implementation, in Python, of the UserTalk code that translates an outline of Python code into a string that the Python interpreter can execute. I think the most controversial aspect is that I add three keywords -- "bundle:", "main:", and "loop:" -- which are trivially translated into "if 1:", "if __name__ == '__main__':" and "while 1:" respectively.

Also present in this example is the calling of UserTalk code and the manipulation of internal UserTalk data types within Python.

All of this functionality is present in the current CVS repository, in the "sidewinder-branch" branch.

from frontier import *
import sys

def renderPython(): displayState = ut.op.getDisplay() cursor = ut.op.getCursor() expanded = ut.op.getExpansionState() ut.op.setDisplay(False) ut.op.fullExpand() ut.op.firstSummit() inComment = False commentLevel = sys.maxint l = [] kw = { "bundle:": "if 1:", "main:": "if __name__ == '__main__':", "loop:": "while 1:", } oplevel = ut.op.level opgetlinetext = ut.op.getLineText scriptiscomment = ut.script.isComment opgo = ut.op.go flatdown = evaluate("flatdown") loop: level = oplevel() text = opgetlinetext() bundle: # determine comment state if scriptiscomment() and not inComment: inComment = True commentLevel = level else: if inComment and level <= commentLevel: inComment = False commentLevel = sys.maxint bundle: # translate comments if inComment: commentIndent = "\t" * (commentLevel - 1) internalIndent = "\t" * (level - commentLevel) text = commentIndent + "#" + internalIndent + " " + text bundle: # translate special keywords for k, v in kw.items(): if text[:len(k)] == k: text = v + text[len(k):] break # only one sub allowed per line bundle: # accumulate translated text if not inComment: text = ("\t" * (level - 1)) + text l.append(text) if not opgo(flatdown, 1): break ut.op.setCursor(cursor) ut.op.setExpansionState(expanded) ut.op.setDisplay(displayState) return "\n".join(l) main: s = renderPython() adr = ut.address("scratchpad.rendered") ut.wp.newTextObject(s, adr) ut.edit(ut.address("scratchpad.rendered"))



2:07:28 PM    comments ()  trackback []