Python Programming, news on the Voidspace Python Projects and all things techie.

IronPython in Action: New Chapters and WPF

emoticon:contour the last few days I've been off work trying to get a chapter on Windows Presentation Foundation finished. I haven't got as much of the writing as I would have liked done, but I have finished the research and completed two of the three examples. WPF is great for creating funky user interfaces, and comes with some great controls. Despite the emphasis on XAML it is also easy to use from code. Here's a screenshot of the second example:

WPF User Interface Screenshot

More importantly, two more chapters of IronPython in Action are available in the Manning Early Access Program. I'm pretty proud of these chapters. Chapter 7 is on testing with IronPython (including functionally testing a GUI application) and chapter 8 is about deeper aspects of Python and interacting with the .NET framework. The information in section 8.4 is vital to any non-trivial interaction with .NET so I'm glad it has gone live:

  1. Agile Testing – where Dynamic Typing Shines
  • The unittest Module
    • Creating a TestCase
    • SetUp and TearDown
    • Test Suites with Multiple Modules
  • Testing MultiDoc
    • Using Mock Objects
    • Modifying Live Objects: The Art of the Monkey Patch
  • Functional Testing
    • Interacting with the GUI Thread
    • An AsyncExecutor for Asynchronous Interactions
    • The Functional Test: Making MultiDoc Dance
  1. Getting Deeper into IronPython: Metaprogramming, Protocols and More
  • Protocols instead of Interfaces
    • A Myriad of Magic Methods
    • Operator Overloading
    • Iteration
    • Generators
    • Equality and Inequality
  • Dynamic Attribute Access
    • Attribute Access through Builtin Functions
    • Attribute Access through Magic Methods
    • Proxying Attribute Access
  • Metaprogramming
    • Introduction to Metaclasses
    • Uses of Metaclasses
    • A Profiling Metaclass
  • IronPython and the CLR
    • .NET Arrays
    • Overloaded Methods
    • 'out', 'ref', 'params' and Pointer Parameters
    • Value Types
    • Interfaces
    • Attributes

The one concrete thing I will report about WPF and IronPython is how to create Image controls using images from the filesystem - because I wasted so much time trying to get this to work. You need to use a bizarre relative URI format to specify the location of the image file. The code looks like this:

from System.Windows.Controls import Image
from System import Uri, UriKind
from System.Windows.Media.Imaging import BitmapImage

image = Image()
bi = BitmapImage()
bi.BeginInit()
bi.UriSource = Uri("pack://siteoforigin:,,,/imagedirectory/image.jpg", UriKind.RelativeOrAbsolute);
bi.EndInit()
image.Source = bi

You don't need this 'site of origin' magic when using compiled XAML, but you do when using the XamlReader or creating images from code. You can read all the gory details here: http://msdn2.microsoft.com/en-us/library/aa970069.aspx

WPF FlowDocuments are cool by the way, very high level document viewing controls for very little effort - but another new markup to learn (a subset of XAML) to use them.

Like this post? Digg it or Del.icio.us it.

Posted by Fuzzyman on 2007-12-14 18:03:55 | |

Categories: ,


PyCon 2008: IronPython and Resolver Talks!

emoticon:ghostradio Well, the accepted talk list for PyCon 2008 is up!

The good news is that only one of my talks got accepted (preparing for just one talk is a lot less scary). My talk is Python in your Browser with IronPython & Silverlight, the second one on the list!

Silverlight is a new browser plugin from Microsoft. It is intended for media streaming, games and rich internet applications. It is cross-platform and cross-browser and comes with a rich programmers API.

Through the Dynamic Language Runtime, Silverlight is fully programmable with IronPython - meaning that at last client side web applications can be written fully in Python. This talk will explore some of the things that you can do with IronPython in the browser.

This includes making web apps run faster, writing 'rich' applications (or games), and embedding a Python interpreter into web pages for tutorials and documentation.

It is a good year for IronPython talks (and so it should be). As well as my talk there are:

  • IronPython: The Road Ahead (48 - Jim Hugunin)
  • End-user computing without tears using Resolver, an IronPython spreadsheet (65 - Giles Thomas - the Resolver boss!)
  • Using .NET Libraries in CPython (103 - Mr. Feihong Hsu - a talk on Python.NET which definitely deserves more attention and is related to IronPython)

There is also a talk by another Resolver developer (not on IronPython though):

  • Getting started with test-driven development (5 - Jonathan Hartley)

It should be a great conference. Smile

sigh I was installing IronPython Studio whilst writing this entry. The .NET 3.5 Setup told me I needed to close just about every application that was running before it could continue - including closing .NET 3.5 Setup. Somehow I didn't think that would work! Good old Microsoft.

Oh, and I just discovered iSolitaire solitaire game for the iPhone. Fantastic.

Like this post? Digg it or Del.icio.us it.

Posted by Fuzzyman on 2007-12-12 12:25:11 | |

Categories: , ,


Resolver Hacks Update

emoticon:new_document Last week the Resolver Beta was released. Since then we've had several hundred (3-400 currently) downloads, which is great.

The version released was 1.0 beta 4 [1]. This includes quite a few major changes since I last updated you about progress with Resolver. One of the major changes was that we made the API for working with spreadsheet objects simpler from user code [2]. This was a lot of work, but I think it was worth it. The very worst side effect was that it broke most of my examples on the Resolver Hacks website.

Today I have finally got around to updating it and putting new screenshots in (Resolver got prettier):

There are around thirty pages of articles and examples to get you going with Resolver. Some of the most useful ones are:

Some of the features that are new in Resolver in the last few months include:

  • Undo and redo for all spreadsheet actions (that took a long time)
  • Unpacking Arrays into Selection (an array or cellrange in a cell can be unpacked into a selected area with Ctrl-Shift-Enter - this took even longer than Undo and Redo!)
  • Cell references and ranges can be inserted into formulae using the cursor keys
  • Pasting 'patterns' into selection when selection is a multiple of clipboard contents
  • Drop down lists of items in cells
  • Performance improvements for large spreadsheets (several very nice optimisations here - but there is still plenty to work on)
  • View by type (date, number, string etc) and origin (constant, formula or set from user code) - a basic auditing mode to see what types cells contain and where the values come from
  • Exception tracebacks are printed to the output view (including exceptions raised in cells and worksheet formulae - fiddly to get right but very useful)
  • The directory of the current file is added to 'sys.path'
  • Pretty (!?!) coloring of the different user code sections in the code box (I didn't specify this user story!)

Plus of course lots of other minor features and bug fixes, almost too numerous to mention. Smile

Even since the beta we have added several new features (once a couple of big changes were finished a few weeks ago we really got on a roll). Hopefully these will be available in beta 5 later this week. If you have already downloaded Resolver you should get notified when the update is available.

[1]This first three betas went to our private beta testers.
[2]You can now set values in cells with user code like: workbook['Sheet1'].A1 = 3. Previously this would have returned a cell object and you would have had to set the Value attribute on it. You can still get access to the cell objects now through the Cells indexer on worksheets, cellranges, rows and cols.

Like this post? Digg it or Del.icio.us it.

Posted by Fuzzyman on 2007-12-11 00:06:17 | |

Categories: ,


Resolver Sponsoring PyCon

emoticon:bluetooth Resolver is sponsoring PyCon 2008! This is great news as it means that there is at least half a chance that Resolver will pay for me to go. Wink

You can see our logo up there on the PyCon 2008 Homepage. We're below google but I think we're still gold sponsors. Looks like there are some benefits to commercial software development... Smile

The PyCon 2008 Program Committee promised they would let us know today about the talk proposals. The proposal system is still in shutdown, so I guess they're still working on it. Tough job, and I'm not holding my breath, but I really want to know which of the Resolver guy's talks got accepted...

Oh - Ars Technica have just released part 5 of their awesome series on the Amiga: A history of the Amiga, part 5: postlaunch blues. The Amiga was a truly beautiful piece of technological architecture and this series captures the spirit.

Unfortunately some of my ebay items had non-paying buyers, so I've relisted. Sad

Like this post? Digg it or Del.icio.us it.

Posted by Fuzzyman on 2007-12-10 22:50:49 | |

Categories: , ,


Resolver and the TechCrunchies

emoticon:clock Resolver is obviously a great startup, with an awesome application (I hope you've tried it). You can show your appreciation (or just help us out) by nominating 'Resolver Systems' in the Crunchies! Smile

The TechCrunch Crunchies are awards for the most innovative technical, creative and business accomplishments. We'd love to see Resolver nominated for the Best international start-up, but there are lots of other appropriate categories too.

We're on a weekly release cycle now by the way, so there should be the next beta available around Wednesday. We've just reached a stage where we have about eight updates waiting to be checked in, so there should be some nice new features and defect fixes.

Oh, and whilst we're not on the subject... if you're advertising tech jobs this month, there are some great discounts available on the Hidden Network Jobs Board:

  • 100OFF0712 - $100 discount ($199 listing), usable once per client
  • 200OFF0712 - $200 discount ($99 listing) , usable once per client

Like this post? Digg it or Del.icio.us it.

Posted by Fuzzyman on 2007-12-09 18:27:47 | |

Categories:


London Geeks, Scoble and Resolver

emoticon:speaker So, Friday night I had a good time chatting to Robert Scoble, Dave Sifry and Dave Winer... Smile

Actually it's true. They're all en-route to Le Web 3 conference and stopped off in London. A bunch of London geeks got together at a geek dinner organised by Hugh MacLeod. Giles Thomas and I meant a load of interesting people (including the alpha geeks), like Mike butcher from TechCrunch UK and Nick Falstead the founder of fav.or.it. The split was about fifty-fifty between developer geeks of various sorts and those involved in social networking (not sure what I think of people who earn a living showing companies how to leverage social networks and blogs), including a guy with a bike shop round the corner who has a popular blog on cycling.

The photowalk afterwards was cool, Dave Siffry (founder of Technorati) told us about his next big idea, but kinda long - we ended up in Picadilly around half one.

Here are the two most important pictures from the photowalk:

Michael with Scoble

and:

Michael with Scoble

You can see more from: Dave Sifry and Tim Watt

Yesterday Scoble interviewed three of us from Resolver. It hasn't gone up yet, but he mentioned it so he can't have thought we were too bad [1]. As we just released our beta this would be great publicity.

As this blog entry has two embarrassing pictures, it might as well have a third:

Destiny Publicity in Northampton

This is from a few years ago. Our Church did several nightclub events called Destiny and this was some us doing publicity in Northampton town centre. I think it was before I was married - I was certainly less fuzzy back then. Very Happy

[1]Actually he seemed very impressed. As it is outside his normal web and social networking 'field of interest' we wondered what he would think.

Like this post? Digg it or Del.icio.us it.

Posted by Fuzzyman on 2007-12-09 17:31:54 | |

Categories: ,


Mock Update - Version 0.3.1

emoticon:paper My Mocking and Patching library has been updated again, this time with a couple of suggestions from Kevin Dangoor.

Mock is a module for unit testing. It is particularly useful for mocking and patching dependencies to reduce test complexity.

Changes in 0.3.1:

  • patch maintains the name of decorated functions for compatibility with nose test autodiscovery.
  • Tests decorated with patch that use the two argument form (implicit mock creation) will receive the mock(s) passed in as extra arguments.

The best way to explain these changes is to show how they work. Suppose you want to unit test create_reader method of SomeClass in the following code:

from datareader import DataReader

class SomeClass(object):

    def create_reader(self, filename):
        handle = open(filename, r)
        self.reader = DataReader(handle)

We want to test that create_reader sets a reader attribute with a DataReader instantiated with a filehandle from the filename passed in.

We can test this very easily with the help of the patch decorator to patch out the dependencies:

from mock import patch
from someclass import SomeClass

class SomeClassTest(TestCase):

    @patch('__builtin__', 'open')
    @patch('datareader', 'DataReader')
    def test_create_reader(self, mockOpen, mockDataReader):
        mockDataReader.return_value = sentinel.Reader
        mockOpen.return_value = sentinel.Handle

        instance = SomeClass()
        instance.create_reader(sentinel.FileName)

        self.assertEquals(mockOpen.call_args, ((sentinel.FileName, 'r'), {}), "open called with wrong arguments")
        self.assertEquals(instance.reader, sentinel.Reader, "DataReader not set on instance")
        self.assertEquals(mockDataReader.call_args, ((sentinel.Handle,), {}), "DataReader not instantiated with file handle")

The way we used to do this kind of testing at Resolver would look something like the following (using the Mock class but not the patch decorator). Because the dependencies need to be patched at the module level the patching needs to be undone afterwards - which means we need to store the original value and do the patching in a try-finally block.

from someclass import SomeClass
from mock import Mock, sentinel

class SomeClassTest(TestCase):

    def test_create_reader(self):
        import datareader
        import __builtin__

        oldDataReader = datareader.DataReader
        oldOpen = __builtin__.open

        mockDataReader = Mock()
        mockOpen = Mock()

        mockDataReader.return_value = sentinel.Reader
        mockOpen.return_value = sentinel.Handle

        datareader.DataReader = mockDataReader
        __builtin__.open = mockOpen

        try:
            instance = SomeClass()
            instance.create_reader(sentinel.FileName)

            self.assertEquals(mockOpen.call_args, ((sentinel.FileName, 'r'), {}), "open called with wrong arguments")
            self.assertEquals(instance.reader, sentinel.Reader, "DataReader not set on instance")
            self.assertEquals(mockDataReader.call_args, ((sentinel.Handle,), {}), "DataReader not instantiated with file handle")

        finally:
            datareader.DataReader = oldDataReader
            __builtin__.open = oldOpen

Now that's a lot of code. Smile

Like this post? Digg it or Del.icio.us it.

Posted by Fuzzyman on 2007-12-09 16:10:23 | |

Categories: , ,


Hosted by Webfaction

Counter...