Resolver One 1.2: Spreadsheet Modularity
Resolver One 1.2 has been released!
As always, Resolver One is free to try and to use non-commercially and for open source projects. Even better, there is now no need to register on the website in order to download it.
The full list of changes since 1.1 is impressively long, but we have a short screencast outlining the highlights.
As always the updates in the new release are a combination of standard spreadsheet functionality, bugfixes and features that build on the unique programmability of Resolver One. This time there is a special feature, which I think has great potential for changing the way spreadsheets are used.
The headline new features are:
- Referencing cells in other Resolver One spreadsheets in formulae (you have been able to reference cells in Excel spreadsheets for a while)
- Creating dropdown lists populated from cellranges, Python lists or other iterables from user code
- Paste special: control over pasting formulae / values / formatting / comments
- Drag fill - auto-incrementing dates, numbers and formulae where appropriate
- Percent formatting of cells and use of % in formulae and constants
- Cached worksheets that retain data across recalcs
- Header lookups on worksheets and cellranges with any type (not just strings)
- Ability to freeze first few rows / columns
Minor new features:
- Slicing of .Rows and .Cols on worksheets and cellranges
- RepaintGrid function to update display whilst a button handler is executing (a wait cursor will also show whilst a button handler is executing - both are useful for long running button handlers)
- An API to access cells / rows / cols / worksheets / cellranges by index (this bypasses headers where you might have integers as headers and want to lookup by index number)
- Custom numeric types (those that define __abs__) in cells will be treated properly as numbers (right aligned in the grid etc)
- A host of new spreadsheet function
- Improvements to the bloomberg integration for the Financial Edition
The important bugfixes:
- Button click handlers swallow exceptions
- Formulae not visible or editable in cell when it is marked with an error cross (previously you had to use the formula bar)
- Inserting / deleting rows did not always update locations of names
- A few rare crashers fixed
The most important new feature is missing from these lists: RunWorkbook.
There are lots of problems with spreadsheets, largely because they are so successful and get used everywhere. Some of the problems include the need to input data into several different places to keep complex spreadsheet systems in sync, and duplicated spreadsheet logic in multiple places to perform similar operations on different datasets.
Some of the problems can be solved by backing data in a database and using spreadsheets for analysis and reporting. Resolver One works very well with databases, but now offers a new solution - spreadsheet modularity through the RunWorkbook function.
RunWorkbook (which can be used from formulae or user code) allows you to load up (as an object) another Resolver One spreadsheet. As well as referencing values in the loaded workbook, you can pass in values to override data in the workbook. These values will be used for the calculation, allowing you to treat spreadsheets as functions. You can use it to create multiple different reports that share the same data (contained in a single spreadsheet), or create data-analysing spreadsheets where you pass data in to the RunWorkbook call.
This will probably be easier to understand if I show you some simple examples. The basic way to call Runworkbook (a user code example) is:
some_sheet = new_workbook['Some Sheet']
value = some_sheet.A1
data = CellRange(some_sheet.Cells.A1, some_sheet.Cells.ZZ10)
Runworkbook returns a workbook instance that you can use in the same way as the standard Workbook.
As the workbook, or the worksheets it contains can be put in cells you are free to access them from formulae. You can also use the CopyRange function to copy blocks of data out of the loaded workbook.
data_sheet = new_workbook['Data']
source = CellRange(data_sheet.Cells.A1, data_sheet.BottomRight)
CopyRange(source, workbook['Loaded Data'].Cells.A1)
You can pass in values, either by specifying the location or by using names you have defined in the spreadsheet, and then pull values back out. This allows spreadsheets to act as functions. The values you pass in are set in the workbook, the calculation is then done and you can pull out the results. You can even pass in whole blocks of data (cellranges).
If the loaded workbook defines any names (through the 'Edit Names' dialog) then you can access those names as attributes on the loaded workbook: for example new_workbook.result.

- You can also pass in overrides that will be used when the workbook is calculated. There are several ways to pass in overrides, but the easiest is to define names that either point to a cellrange or a single cell. You can then use those names as keyword arguments in the call to RunWorkbook:
- result = RunWorkbook('spreadsheet.rsl', input=23, source_data=some_cellrange).result
As well as passing in single values (for names that point to single cells), you can pass in whole blocks of data as cellranges. Cellranges are copied into the workbook before being calculated.
This makes spreadsheet modularity much easier (it makes it possible!) - complex spreadsheets can be broken down into smaller spreadsheets, which are then simpler to understand and can be reused. It also allows you to test your spreadsheet logic by passing in test data and checking that the spreadsheet produces the correct results. We are building systems on top of this to makes spreadsheet testing even easier.
We've already started work on version 1.3, and hope that the release cycle will be much quicker this time. We're building some custom solutions for customers on top of Resolver One. Using your product doesn't half concentrate the mind on what features you need to add!
Like this post? Digg it or Del.icio.us it. Looking for a great tech job? Visit the Hidden Network Jobs Board.
Posted by Fuzzyman on 2008-08-16 20:37:51 | |
Categories: Work, IronPython Tags: resolverone, spreadsheets, modularity, release
Django on Jython, Python Implementations and Performance
Django now runs on Jython which is great news. Jeff Hardy is also making progress running Django on IronPython. As usual the news sparked a plague of comments on Reddit. There seems to be a lot of confusion about the different implementation of Python, and which bits of CPython acts as the reference implementation. (Even Ruby is getting a language specification...)
CPython is the reference implementation but several aspects have been explicitly described as implementation details. These include:
- Stack frames
- Bytecode instructions
- The Global Interpreter Lock
- Reference counting for garbage collection
Jython and PyPy do use Python stack frames, and so tend to have less issues than IronPython when running Python applications that depend on certain obscure implementation details. (IronPython doesn't and is faster in consequence.)
PyPy has implemented the GIL (mainly as a matter of convenience) - Jython and IronPython don't have a GIL and can scale multi-threaded code across several CPU cores.
None of PyPy, Jython and IronPython use reference counting for garbage collection. This means faster garbage collection but non-deterministic calling of destructors - which would normally be called immediately the reference count drops to zero in CPython (it also means no uncollectable cycles either which can happen in CPython when you have cycles involving destructors).
IronPython uses native .NET strings, and so all strings are Unicode. In my experience this has made working with strings much more pleasant in IronPython - roll on Python 3. This also used to be the case with Jython, but I believe that Jython now has byte strings. This makes it easier to get Django running, as Django 1.0 uses the difference between byte-strings and Unicode strings to determine whether it is serving text or binary data.
IronPython does a lot of magic to allow you to store binary data in strings (it can still be a cause of bugs - but they are bugs and should be reported to the IronPython team), but you can't dispatch on type. This makes it questionable whether an unpatched Django will ever run on IronPython without some other flag (or way of patching in a compatible 'bytes' type implementation). Jeff certainly seems to be making good progress though.
A new page popped up recently on the Python wiki (relevant I promise):
This is my answer to the question Why is Python slower than xxx Language ?:
Python as a language is a set of rules (its syntax and semantics) and so doesn't have a 'speed'. Only a specific language implementation can have a measurable speed, and then we can only compare performance with a specific implementation of another language. In general you can't compare the speed of one language to another - you can only compare implementations.
Having said that, as a dynamic language Python will typically perform slower for specific benchmarks than standard implementations of some other languages (although it is faster than plenty of others). As a dynamic language a lot of information about the program can only be determined at runtime. This means that a lot of common compiler tricks, that rely on knowing the type of objects at compile time, can't work. Despite this there are a lot of things that can be done to improve the performance of dynamic languages (beyond the performance of statically typed languages many believe), several of which have been done before in virtual machines like Strongtalk and are being explored for Python in the PyPy JIT tracing compiler.
Like this post? Digg it or Del.icio.us it. Looking for a great tech job? Visit the Hidden Network Jobs Board.
Posted by Fuzzyman on 2008-08-14 21:56:09 | |
Categories: Python, IronPython, General Programming Tags: pypy, jython, performance, django
Generators, finally and Iterator Finalization
Raymond Chen has run a series of posts on the implementation of iterators (generators in Python speak) in C#. The C# compiler creates an inner class that acts as a state machine, which is nothing like as elegant as the Python implementation of course.
Today was part 3 in the series:
This entry concentrates on an additional place (to the expected) that a finally block can be entered: inside the finalizer of an iterator. I was intrigued, and discovered that the same is true in Python. If you have a generator with a finally block, and the iterator is garbage collected before the generator is exhausted, then the finally block is executed:
[GCC 4.0.1 (Apple Computer, Inc. build 5367)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> def f():
... try:
... for i in range(5):
... yield i
... finally:
... print 'done'
...
>>> it = f()
>>> it.next()
0
>>> it.next()
1
>>> del it
done
This is the right decision of course. Something that is the wrong decision (in my opinion) is that if a finally block is entered because of an exception, and there is a return in the finally block then the exception is swallowed instead of being raised. Either a return in a finally should be disallowed (as it is in C#) or the exception should be raised.
The Python implementation of generators is particularly elegant because of the way functions / stack frames are implemented. As an overview... a stack frame has a code object associated with it. This has the bytecode sequence (as a byte-string) and a counter that points to the current bytecode instruction. Every time a new bytecode is executed the counter is incremented. When the function returns, nothing holds a reference to the stack frame anymore and it is garbage collected (actually they are expensive to create - so a pool of zombie stack frames is kept for reuse).
When you create a generator it holds a reference to the stack frame, and every time you call next execution continues at the next bytecode - until a yield or return is hit. The stack frame is kept alive until the generator is garbage collected.
Like this post? Digg it or Del.icio.us it. Looking for a great tech job? Visit the Hidden Network Jobs Board.
Posted by Fuzzyman on 2008-08-14 21:09:59 | |
Categories: Python, General Programming, Hacking Tags: generators, iterators
Paths with Spaces on the Mac
Part of the power of systems that inherit a legacy from UNIX is their rich and flexible scripting system. Many desktop applications use this somewhere under the hood - either providing wrapper scripts as part of the application or even to implement core functionality.
A disadvantage of this is that it is much easier to make your application sensitive to (i.e. broken for) paths that contain spaces - simply forget to put quotes in the right places.
This is a problem that afflicts Windows less, simply because a Windows programmer is less likely to implement core functionality by delegating to the shell. Additionally the default home directory and install path for applications both have spaces in them [1], which apart from being annoying when you do use the command line also means applications are more likely to be aware of spaces in paths.
Of course 'shelling out' is a technique that can work cross platform, and the only time [that I can remember...] I had a problem caused by quoting errors in shell scripts on Windoze was the PyLint shell script [2].
The core of Mac OS X is based on BSD, and so it is a modern UNIX 'variant', which makes it much easier to develop cross platform applications that run on Linux and Apple Macs.
The X11 server that comes with Mac OS X is developed separately as the XQuartz project. I recently tried to use some application that depended on a more recent version of X11, so I installed XQuartz. Which promptly broke X11 completely for me...
As you can doubtless guess, the reason XQuartz broke is that my user profile is on a drive with spaces on it. It seemed completely obvious to me that when I added a second drive (and moved a bunch of stuff onto it) it should be called 'Second Drive'...
It took a while to work out the problem (the error log showing the broken path was a good clue) and the solution was to use an updated version of the startX script that will be fixed in the next release.
I had a nice email from one of the developers suggesting that having paths with spaces in was a bad idea. This seems odd to me - if your application can't handle spaces in paths then your application is broken and it isn't the user's fault. All programmers on UNIX type systems should work from paths with spaces on to make sure their applications can handle them... (Maybe only as a punishment if shell quoting bugs are found in their scripts / programs.)
Still, I assured him that the only program I had ever had a problem with was XQuartz and I was worried about potential problems caused by renaming the drive.
Of course I was wrong, XQuartz wasn't the only program I've had problems with due to spaces in the paths. A couple of weeks ago I reported that I couldn't get FileZilla to work on my machine, and that no-one else seemed to have the same problem. Guess what it was actually caused by...
Naturally by the time I worked it out and reported it, it was already fixed...
Oh, and I do use the command line quite a lot on the Mac and no the space doesn't tend to annoy me - shell completion is nice.
| [1] | Good old 'Documents and Settings' and 'Program Files'... |
| [2] | When I started at Resolver Systems my boss installed Python into 'Program Files'. |
Like this post? Digg it or Del.icio.us it. Looking for a great tech job? Visit the Hidden Network Jobs Board.
Posted by Fuzzyman on 2008-08-04 11:28:58 | |
Categories: Computers, General Programming Tags: mac, shell, scripts
Updating 1st Gen iPhone to Unlocked and Jailbroken 2.0
Around October of last year a bunch of us at Resolver Systems got imported iPhones and promptly jailbroke and unlocked them. The unlock process at the time was fairly arduous, so most of us have been running the OS version 1.0.2 since then.
When the iPhone 3G came out I was sorely tempted, but my phone contract isn't up until next year. So last Sunday, when I should have been doing more sensible things like making edits to chapter one, I spent a frustrating few hours upgrading my first gen iPhone from 1.0.2 to 2.0. The first two hours were spent trying things that didn't work, so in case I save anyone two frustrating hours here's how I did it.
This is a Mac only solution. It was made complicated by the fact that the jailbreak we used rewrote the baseband to do the unlock. In order to upgrade I needed to fully 'revirginize' the phone, including restoring the baseband firmware.
The steps are pretty straightforward. It did take two hours, but most of that was unattended. To do the 'virginizing' (including restoring baseband) I followed the hackthatphone flowchart:
I started at the Downgrade to 1.0.2, jailbreak and activate step. This requires the 1.0.2 OS, a specific version of iTunes (7.4.2) and a specific version of iNdependence (the Mac hacking software). Fortunately the flowcharts gives links to all of these.
In order to install the older version of iTunes you'll need to blow away MobileDevice.framework. I would also rename your iTune library folder so that you can rename it back once you have reinstalled the latest version of iTunes again.
Whilst I was running iNdependence it would periodically hang on me. Killing it and restarting it worked fine (and is the advised solution in the README!) - so long as you see the screens shown on the flowchart you know you are going in the right direction.
Once I had restored 1.0.2 and the original baseband I could upgrade back to iTunes 7.7, which promptly offered to upgrade my iPhone to 2.0. This failed (but downloaded the 2.0 OS image) as my SIM card wasn't supported - it needs to be an O2 SIM and needs to properly activate again.
This is where the PwnageTool comes in. I used PwnageTool 2.0.1, but you will also need bl39.bin / bl46.bin, which are easy enough to find via google. Some people have had problems with this, so at your own risk...
I followed a neat (and short) video tutorial on using the PwnageTool expert mode: PwnageTool Expert Mode
This creates a custom OS image for you that iTunes can 'restore' to your phone. Once loaded it activates and unlocks the phone and includes an 'installer like' application called Cydia. There is a new version of installer in the works, and many of the applications for jailbroken 1.x iPhones are still being ported over: Installer 4.
The new OS is great, with some nice touches like you can always see the last character in a password text box. This is useful because even though I am getting used to typing on the iPhone (I prefer texting on the iPhone to an ordinary mobile phone with a numeric keypad) it is hard to be 100% accurate. I've not noticed any bugs, but there is the occasional pause when opening applications.
As for applications, well. With 1000 apps in the AppStore, most of them are crap. Of the ones that aren't, or may not be, crap - most of them don't interest me. Even so, there are still some very interesting ones and they are a huge step-up from the 1.x apps.
I have only paid for two applications:
-
I've only just got this. So far it looks fantastic.
Solitaire
This is the version of Solitaire that I used to play a lot (for free) as a jailbroken app on my previous version. It's very cheap (about $5) and has had two games added. It has actually lost a couple of features for the Klondike game I play (I don't use the others), but it is still very good. Solitaire and as an iPod is all I was using my iPhone for before this upgrade - now it's my main phone.
I also have a few free apps. My internet connection on my phone (an extra ten pounds a month for allegedly unlimited internet use with Orange) doesn't get switched on until next Saturday. It will only be after that that I work out which applications are really useful. The ones I am using so far are:
Twinkle
Twitter client, very nice.
JirboBreak
A 'breakout' style game. It has a nifty control mechanism, an on screen thumbpad - you roll your thumb left and right to control the paddle and the game pauses if you take your finger off the screen. It took me about three games before I really got the hang of it, but it's a great implementation of breakout and very addictive.
Stanza
Nice ebook reader with online repository of free books to download. Good stuff from Cory Doctorow included!
The Facebook App
Straightforwardly good.
The google app
This just redirects you to Safari for most things - but it does include google chat.
I've also installed MoPhoto and ShoZu for uploading images to Flickr and Facebook (etc) and viewing them as well. I haven't really tried them much to see if I really need them. Naturally I also have a terminal from Cydia and will be trying this technique (3proxy) for tethering an iPhone internet connection to a laptop (mine is edge rather than 3G but still worth it).
Like this post? Digg it or Del.icio.us it. Looking for a great tech job? Visit the Hidden Network Jobs Board.
Posted by Fuzzyman on 2008-08-03 20:32:17 | |
Dependency Injection and Mock(ing) for Testing
This blog entry is about changes to Mock - A Lightweight Mocking Framework for Testing, one of the projects (and thankfully small) that I will be working on once 'the book' is finally out of the way.
Suppose you have the following code, how do you test some_method:
def some_method(self, arg):
self.other = OtherClass(arg)
Well, we could just call some_method, but what if OtherClass is expensive to construct (or establishes a database connection) and we'd really rather not do that in a unittest?
We can't straightforwardly mock, because the construction of the class is internal to the method. One technique is to use dependency injection, where the dependency class is passed in. We can even make it the default value of a keyword argument:
def some_method(self, arg, Dependency=OtherClass):
self.other = Dependency(arg)
Now it is trivial to test some_method. We can pass in a mock object as the 'Dependency' and test that the body of the method acts on it as it should. The problem I have with this approach is that we have now added code that sets up the default dependency (the default value of the keyword argument), effectively another layer, that we should test as well. (If we only with an explicitly passed in dependency then we test under different conditions to how the code is called in production.)
This approach has other advantages however. The dependency on OtherClass is no longer 'hardwired' and we could use another class or callable at runtime if we wanted to change the behaviour. Of course this could be catering to a future and purely imagined usecase, and YAGNI applies. There is a lot more to dependency injection than this simple example, and it can be an extremely useful technique, if you need it.
At Resolver Systems we take an alternative approach to testing this kind of code, generally mocking instead of using dependency injection. When I discussed with one of my fellow developers whether we should use more dependency injection to reduce the amount of mocking needed in our tests, his response surprised me:
As far as I can tell, dependency injection just screws with your interface.
And it's true. In this example, the first version represented the code we wanted to write. We only modified it, changing the interface in the process, to make it easier to test. Not only does reading the code now give us a distorted view of its use, but tools that use introspection (like automated documentation tools) will also pick up on the changed API.
A standard Python way of testing the first version of the code is to mock out OtherClass at the module level. Because names are resolved dynamically, instead of being statically bound, if we patch the class for the duration of the test then our mock will be used when we call some_method. Unfortunately the code to do this requires a bit of ugly and tedious boilerplate:
original = SomeModule.OtherClass
SomeModule.OtherClass = Mock()
try:
something = SomeClass()
something.some_method(arg)
# test our Mock is used in the correct way
finally:
SomeModule.OtherClass = original
Most mocking frameworks are based on the 'record - > verification' pattern for testing. Not only do I find this backwards (I prefer the 'action -> assertion' pattern) but it means you often have to record every step in a test, when you are only interested in testing a corner case - one part of the unit behaviour.
Mock is a very lightweight mocking framework for unit testing. It also includes a decorator that makes it trivial to mock out classes in a module without the boilerplate.
def test_some_method(self, MockOtherClass)
MockSomeClass.return_value = sentinel.Instance
something = SomeClass()
something.some_method(sentinel.Arg)
MockOtherClass.assert_called_with(sentinel.Arg)
self.assertEquals(something.other, sentinel.Instance)
The patch decorator monkey patches SomeModule.SomeClass only within the scope of the test and passes in the mock it creates to the test method. Actually the example above uses a couple of nice features of Mock (and its patch decorator) that aren't quite available yet. The code doesn't look very different with the current version though.
Of course in Python, modules are first class objects and are effectively singletons. This is one reason why the singleton pattern is so rarely useful in Python. It also means that changing module level attributes for tests is mutating global state. Forgetting, or botching, restoring state after your test will leave your patch in place for subsequent tests and cause you some very weird problems. This is reason enough for some people to say that it should never be done. One real consequence is that you can't run tests in parallel - but whilst running tests in parallel is fine, would you really do it using several threads rather than several processes? That's a recipe for disaster all of its own... Using patch ensures that the patching is undone whether the test passes or fails.
I originally created the Mock module to make some common testing patterns we use at Resolver Systems simpler. Since then we've made several improvements to Mock that have never been synced back in (plus I've had patches and feature requests from other users of Mock):
- A patch (1 line!) from Kevin Dangoor for nose compatibility (preserving line numbers in patched methods)
- Add the assert_called_with method
- Add a side_effect attribute - a callable used every time a Mock is called. This allows you to do nice things like raise an exception if a mock is called, or return members of a sequence for repeated calls rather than just a fixed value.
- Make the default return value a Mock (unless None is explicitly specified)
- Modify patch to allow a single string argument specifying what should be patched
Apparently this is my 1000th blog entry (on this blog). The first was on January 23rd 2005, which makes for an average of more than five entries a week over three and a half years! [1]
Another project I omitted from my list of projects I'm interested in was Tweezer. Tweezer is a very nice looking Twitter client by Ed Leafe, built on the Dabo framework. It's still missing some features, but I'm looking forward to hacking on it...
| [1] | Over the last year I've also averaged more than five entries per week on the IronPython URLs blog, but as that is a link and news aggregator they tend to be a lot shorter. |
Like this post? Digg it or Del.icio.us it. Looking for a great tech job? Visit the Hidden Network Jobs Board.
Posted by Fuzzyman on 2008-08-01 11:26:12 | |
Categories: Python, Projects, Hacking, General Programming Tags: testing, mocks
Try Python (Python in the Browser) and Silvershell
One of the longer term projects I'd like to work on is the Try Python tutorial. The website currently just shows Python in the Browser, which is an interactive Python interpreter running in an HTML textarea on the webpage. The nice thing is that it is possible to preload samples into the interpreter and use it as live examples for a Python tutorial. This would be a great way to teach Python, requiring only a browser with Silverlight 2 [1].
Creating an effective tutorial is actually quite hard work, so it would be nice to build off an existing project. Crunchy is a related project that includes some tutorials already, but the 'textarea' type approach looks closer to the real Python interpreter than the single text entry field that Crunchy currently uses. I wonder whether integration with Crunchy would be an effective way to go - I really want to spend my time on making the tutorial effective rather than working on the implementation details of the interpreter.
That aside, "Python in the Browser" is currently not as visually appealing as it could be... There are at least three different ways for me to remedy this.
- Borrow the Javascript from Jimmy Schementi's Try IronRuby.
- Borrow the Javascript from Why the Lucky Stiff's Try Ruby.
- Rebuild on Silvershell.
I've had permission for both 1 and 2, but Silvershell is a relative newcomer to the game. It is the creation of Dan Eloff, and rather than using the browser DOM and Javascript for the UI it uses Silverlight itself.

As you can see it is very visually appealing. It also has some nice features like auto-indentation and completion (neither of which would be particularly difficult to add to PiB). The only difficulty is that it might make it harder to simulate several interpreters in a page as it certainly used to be difficult to relocate the Silverlight control in the page [2]. Dan suggests we could solve that by locating the control in an iframe (my instinct was to spell that iFrame...) and relocating that.
Anyway it will be fun to experiment and I hope to end up with a useful set of resources for learning Python online.
| [1] | And once Silverlight 2 is out of beta it will almost certainly be pushed out over Windows update like Silverlight 1. Not long ago Silverlight 1 downloads were running at a million a day [citation needed] so I don't expect deployment to be an issue. |
| [2] | Well, it used to hard crash the browser anyway... |
Like this post? Digg it or Del.icio.us it. Looking for a great tech job? Visit the Hidden Network Jobs Board.
Posted by Fuzzyman on 2008-07-30 21:38:38 | |
Categories: Projects, Python, IronPython Tags: crunchy, silvershell, silverlight, tutorials
Too Many Projects, Too Little Time
One annoying thing about spending the last year writing, is that I haven't been able spend much time on other projects (although I did recently manage to push out a ConfigObj release).
I've already spent (in my mind) the spare time I will have once the book is done three times over. Projects I have waiting in the wings include:
-
This is a Python documentation tool that Resolver Systems uses to auto-generate our Spreadsheet API Documentation from ReST docstrings. I've had permission to release this as Open Source, at least partly because I wrote half of it on my own time one Christmas. It's features (which are the reason we wrote a new documentation tool) are:
- Runs under IronPython and will generate docs for code written in IronPython (using introspection)
- Allows you to specify which parts of your API should be public
- Can raise an error if any public class / method / property does not have a docstring
- It is very small (only a few hundred lines of code) and easy to customize
- Fully tested of course
-
This is (or will be) a compatibility layer for the .NET base class libraries so that IronPython code can be run under CPython. This will be useful for me if we make a source release of the Resolver One Library packages. This will allow you to integrate Resolver One spreadsheets, or even the whole calculation engine, into standard Python applications.
As we haven't yet made a source release, it isn't the highest priority.
-
This project was started by Ivan Porto Carrero, the author of IronRuby in Action. It allows you to create user controls in XAML, for Windows Presentation Foundation and Silverlight, that are written in DLR languages (using normal XAML syntax for setting properties).
Ivan has got it working with IronRuby and I've promised to get it working with IronPython.
-
An IDE for Dynamic Language Runtime languages (IronPython & IronRuby), compatible with both Mono and .NET. Ben Hall has made a great start on this project. I'm not sure how much time I will have to contribute to this, but I'm watching it with great interest.
In fact there are several more (well three...) that deserve blog entries of their own.
One final one that I might take on is a report generation tool for Resolver One. My Dad works in Industrial Safety and Reliability Engineering and often has to produce hazard reports. The standard tools are custom applications (inflexible and unfamiliar to users) or Excel (not really suited to the purpose but much more flexible than the custom applications). If I can create a report generation library for Resolver One that produces Word documents, then not only will it be useful for me but I can build a tool for him that is as flexible as Excel but customized for the hazard reports he needs to produce.
Like this post? Digg it or Del.icio.us it. Looking for a great tech job? Visit the Hidden Network Jobs Board.
Posted by Fuzzyman on 2008-07-29 23:19:01 | |
Categories: Python, Projects, Hacking, IronPython
Last Chapter of IronPython in Action Finished
The last chapter of IronPython in Action is finally done. There is still work to do before the book is complete (appendices, index, updating the first chapter in light of the last year in IronPython), but chapters 12 (Databases and Web Services written by Christian Muirhead) through to 15 are now ready to go to the final review phase. This will take a couple of weeks and after making any necessary changes it will then go through for publishing - which could take anything up to three months!
Chapter 15 has been one of the most fun chapters to write. It shows how to use IronPython as a scripting engine in .NET applications (from C# or VB.NET). The chapter table of contents is:
15 Embedding the IronPython Engine
15.1 Creating a custom Executable
15.1.1 The IronPython Engine15.1.2 Executing a Python File15.2 IronPython as a Scripting Engine
15.2.1 Setting and Fetching Variables from a Scope15.2.2 Providing Modules and Assemblies for the Engine15.2.3 Python Code as an Embedded Resource15.3 Python Plugins for .NET Applications
15.3.1 A Plugin Class and Registry15.3.2 Auto-discovery of User Plugins15.3.3 Calling the User Plugins15.4 Using DLR Objects from Other .NET Languages
15.4.1 Expressions, Functions and Python Types15.4.2 Dynamic Operations with ObjectOperations15.4.3 The Builtin Python Functions and Modules15.5 Summary
The chapter works through four examples:
- Creating a custom executable that launches a Python application
- Using IronPython as an embedded scripting engine - setting up the execution environment and setting and fetching variables in the execution scope
- Python for 'user plugins' in an application - including error handling, auto-discovery of plugins, exposing an API to the hosted Python engine and so on
- Interacting with dynamic objects from C# and VB.NET - creating instances of Python classes, calling functions and methods etc
Like this post? Digg it or Del.icio.us it. Looking for a great tech job? Visit the Hidden Network Jobs Board.
Posted by Fuzzyman on 2008-07-29 22:09:53 | |
Categories: IronPython, Writing, General Programming Tags: ironpythoninaction, book, .NET, csharp, VB.NET
PyCon UK: Talk and Tutorial Lists Up
PyCon UK is drawing closer, it's on 12th-14th September and now that most of the organisers are back from EuroPython [1] the list of talks and tutorials is now up.
This is our second PyCon UK conference, and this year we start with a full day of tutorials on the Friday (don't forget to include the tutorials when you book).
- Timetable for the tutorials day
- Abstracts of currently accepted talks
- Booking form (early bird rate is still open - but not for too much longer)
Christian Muirhead (my co-author for IronPython in Action), Menno Smits (another colleague) and I will be doing a four hour tutorial on developing with IronPython - so if there is anything you would like to see covered then get in touch!
We have some great talks and tutorials planned.
The tutorials (the list is shorter):
- Developing with IronPython
- An Introduction to Python (John Pinner)
- Building Solutions with Reportlab (Andy Robinson)
- Generator Tricks for Systems Programmers (David Beazley)
- Practical Python GUI Programming with PyQt4 (Mark Summerfield)
- An Introduction to Django (Jacob Kaplan-Moss)
Notable talks (way too many to list all of them):
- Stretching Pyglet's Wings (Jonathan Hartley - an erstwhile colleague)
- Amazon Web Services in the Cloud (Simone Brunozzi from Amazon.com)
- Practical concurrent systems made simple using Kamaelia (Michael Sparks)
- Talks on PyPy and py.test
- Core Python Containers - Under the Hood (Raymond Hettinger)
- Python 2.6 & 3.0 (Raymond Hettinger)
- Python & WMI (Tim Golden)
- Testing with Mock Objects (Simon Brunning)
- Functionally Testing GUI Applications (Me!)
- What's new in Django 1.0 (Jacob Kaplan-Moss)
- Using And Customising The Django Admin Interface (Simon Willison)
As you can see we have some national and international Python stars speaking, not to mention keynotes by Ted Leung (Sun) and Mark Shuttleworth (Canonical).
Neither the list of tutorials nor talks is final (so still time to submit). Menno has submitted a talk on Python programming with the OpenMoko phone and we're expecting to have a tutorial from 'a google guy' on developing for App Engine.
On the OpenMoko, it is nothing like as usable as the iPhone (more on that later) - but perhaps eventually. In the meantime, it is extremely interesting as an embedded Linux device with mobile phone, wifi and bluetooth capabilities.
Oh, we also have talks on SCons, Pylons, Google AppEngine, testing tools, Python in education at Leeds university, Python in science and so on. See you there.
| [1] | Not including me unfortunately... |
Like this post? Digg it or Del.icio.us it. Looking for a great tech job? Visit the Hidden Network Jobs Board.
Posted by Fuzzyman on 2008-07-28 23:41:11 | |
Categories: Python, IronPython Tags: conferences, pyconuk, uk, openmoko
Feature Freeze for Resolver One 1.2 Release
The first major update to Resolver One after our public release in January, was version 1.1 in June. The focus of the 1.1 release was performance improvements. Overall we achieved a 30% performance improvement, but for some specific bottlenecks we made massive improvements [1]. As a result of this focus the list of new features in 1.1 wasn't very impressive.
The same is definitely not true of the list of improvements in the forthcoming 1.2 release. As you might expect, the list is a combination of implementing standard spreadsheet features, bugfixes and new features that build on what is unique about Resolver One.
The list doesn't include the major new feature of 1.2. It's a bit special (if you're into spreadsheets), and in my opinion is game-changing for developing spreadsheet applications. We're keeping it under wraps until the release.
Other than this there are still some impressive new features:
Major Features
- Create dropdown lists in cells from cellranges (or any iterables) in user code
- Paste special: paste formulae/values/formatting/comments
- Drag down (or up or left or...) from bottom right of cell to fill a larger range with auto-incrementing values (effectively fill down for numbers and dates etc)
- Percentage formatting for displaying value - numbers are multiplied by 100 and get a "%" at the end.
- Percentages become legal syntax in formulae or as constants (direct values) in cells.
- Persistent worksheets stored across recalcs
- Support referencing cells in other Resolver One spreadsheets
Minor Features
Worksheet header lookups now by value, allowing integer (etc) headers
Support slicing on .Rows and .Cols iterators for Worksheets and CellRanges
For example: worksheet.Rows[3:12] will return rows 3 through 11 inclusive. You can also slice with headers rather than indices.
Wait cursor when running click handlers for users' buttons
Ability to make visible changes to the grid during a button handler
Custom Numeric Types right aligned in grid and used by SUM (recognised because they define __abs__)
Performance boost - due to an upgrade to PLY 2.5
A whole bunch of standard spreadsheet functions
There are a couple of other features already underway that will hopefully make it in as well.
You can see almost the full list of new features, including bugfixes and improvements in the Financial Edition of Resolver One, in the entry on Resolver Systems News Blog:
The new version should be available within the next two weeks (hopefully sooner but you know how it goes). As always the desktop version of Resolver One is free for non-commerical and Open Source use.
Once the release is out of the way I'm hoping to find time to write up some new articles on Resolver Hacks. One article I'd like to write is an example CRUD application using Resolver One, showing some 'best practices' [2] for developing applications with Resolver One. Particularly the use of the persistent worksheets that cache between recalcs are ideal for this.
While we finish off version 1.2 we're already planning 1.3, and William is making massive progress with Ironclad...
| [1] | Indexing worksheets with headers went from being n-squared to O(1) for example. |
| [2] | I know, I know. Better practises? |
Like this post? Digg it or Del.icio.us it. Looking for a great tech job? Visit the Hidden Network Jobs Board.
Posted by Fuzzyman on 2008-07-28 22:38:49 | |
Categories: Work, General Programming Tags: resolverone, spreadsheets, news
For buying techie books, science fiction, computer hardware or the latest gadgets: visit The Voidspace Amazon Store. If you're looking for a new techie job, try the Voidspace Tech Job Board. This is part of the Hidden Network of technology and programming jobs.




IronPython in Action