Weirdest KDE appearance in the news yet is....
... asking the president of Kazakhstan how to patch it under FreeBSD (which I must confess I have no idea, unless you answer "using patch"?).
More info here.
... asking the president of Kazakhstan how to patch it under FreeBSD (which I must confess I have no idea, unless you answer "using patch"?).
More info here.
I was able to hack a bit at StupidSheet this morning, and there are some real advances.
In fact, it's a barely functional spreadsheet already! Hell, it has at least one feature OOcalc lacks, and one both OOcalc and KSpread missed.
Check it out in this video (9.5MB):
Sorry, dead file
Sorry if the audio is out of sync and/or too low. And you probably can't stream it, you need to download it first. And maybe it will 404 on you. If that's the case, wait a few minutes and insist.
For my spreadsheet project, I had to redo something I had forgotten about: cell displacement. I did that once when the formula language was python.
At the time, I parsed the python using the tokenize module and Ka-Ping Yee's regurgitate.
Python->Tokens->Displace cells->regurgitate->Python
Since I have lots of other things to do, I decided to do it the same way, and wrote the equivalent of regurgitate for Traxter, my formula language.
It turns out it was not really hard, but I had to redo parts of the parser so it kept more information about the source.
After that it was simple, you see, Traxter compiles to Python. That means all I had to do was another (very similar) backend, and there it is, a Traxter-to-Traxter compiler. Or decompiler. Or something. And relative cell references are working again (and now with the right syntax).
It promises:
Native look&feel for your apps on all major platforms
Works for graphical and terminal apps
Open Source
Low overhead
Universal binaries that work on Windows, Mac and Linux
Seems too good to be true, but it is supposed to be released next month.
The whitepaper (which reads mostly like an ad)
After hacking for about two hours the cell dependencies yesterday using dicts, I found myself saying "how can I check if the dependency graph is cyclical?"
And of course it hit me. That's the dependency graph. Use a graph library!
I looked for about 2 minutes before finding one that's probably not optimal, but is damn simple and in the public domain: graph_lib.py by Nathan Denny.
First interesting data point, the first two lines on the file (yes, I found out there is a later version):
#--Version 1.0.0 #--Nathan Denny, May 27, 1999
Yup. In two days this piece of code is turning 8 years old and untouched. But it works just fine and dandy!
Here's the piece of code that makes the engine run which has grown from a humble 10 LOC to almost a whooping 40 LOC:
class SpreadSheet(QtCore.QObject): _cells = {} tools = {} graph=Graph() def __init__(self,parent): QtCore.QObject.__init__(self,parent) for name in dir(functions): self.tools[name]=eval('functions.'+name) def __setitem__(self, key, formula): key=key.lower() c=traxcompile('%s=%s;'%(key,formula)) self._cells[key] = [c[key][0],False,compile(c[key][0],"Formula for %s"%key,'eval')] # Dependency graph if not self.graph.has_node(key): self.graph.add_node(key) for edge in self.graph.in_arcs(key): self.graph.delete_edge(edge) for cell in c[key][1]: self.graph.add_edge(cell,key) try: print 'GRAPH(TOPO): ',self.graph.topological_sort() self._cells[key][1]=False print 'GRAPH(BFS) : ',self.graph.bfs(key) for cell in self.graph.bfs(key)[1:]: self.emit(QtCore.SIGNAL('changed'),(cell)) except Graph_topological_error: # We made the graph cyclic # So, mark this cell as evil self._cells[key][1]=True # And remove all incoming edges to go back to # status quo for edge in self.graph.in_arcs(key): self.graph.delete_edge(edge) def getformula(self, key): key=key.lower() return self._cells[key][0] def __getitem__(self, key ): print self._cells[key] if self._cells[key][1]: return "ERROR: cyclic dependency" else: print 'evaluating [%s]: '%key,type(self._cells[key][0]),self._cells[key][0] return eval(self._cells[key][0], self.tools, self)
This engine supports:
User defined functions (just add them in formula.py)
Cell dependencies with detection of cicles, of any length
Unlimited size spreadsheets
Notification of cell changes to other modules
Automatic recalculation
A custom formula language (ok, that's not in this piece of code ;-)
The whole project is now 1167 LOC, of which 591 are generated or graph_lib, which means everything including the traxter "compiler" and the UI is less than 600 lines of code.
Not too shabby.
My goal is a functional spreadsheet with a working GUI and supporting the most common functions and pieces of the formula language in .... 2000 LOC, and I am willing to work on it for about two weeks.
Let's see how it turns out. Of course anyone with 5 free minutes can contribute his favourite spreadsheet function (I already have sum ;-)