C# in Depth

Cover of C# in Depth
Order now (3rd edition)

Graphing dynamically with IronPython and Silverlight

In chapter 14, I promised a dynamic graphing demonstration. Silverlight makes it relatively easy to work with dynamic typing, although you do need to know where to get the right bits from.

In this demo, I'm using Silverlight 4 and the .NET 4 DLR. To use that combination I'm using the alpha build of IronPython, which you can download from the IronPython codeplex site. Once you've downloaded and installed the alpha build (which as far as I can tell can co-exist perfectly happily with other versions) you'll find the libraries you need to add references to in something like "c:\Program Files\IronPython 2.7\Silverlight\bin" (depending on your Windows installation; on my box they're actually in "c:\Program Files (x86)"). I believe these require Silverlight 4, so if you're using Silverlight 3, use IronPython 2.6 (but the build which targets .NET 3.5). You don't need to download IronPython in order to see the demo at the bottom of this page, but you do have to have Silverlight 4 installed.

Anyway, the basic idea is to let you write some Python to represent a function, click a button and let it draw a graph for you. I haven't included any axes or anything like that, although the app does scale the results so it always fills the relevant bit of the screen. In fact, most of my time was spent getting the Silverlight scaling and translating to work - once I'd got the right libraries, the bit of code which called into Python was extremely easy to get working. Here's what that piece of code looks like:

ScriptEngine engine = Python.CreateEngine();
ScriptScope scope = engine.CreateScope();
engine.Execute(Formula.Text, scope);
// First approach: get the DLR to build us a delegate from the function
Func<doubledouble> function;
if (!scope.TryGetVariable<Func<doubledouble>>("f"out function))
{
    Status.Text = "No function f defined";
    return;
}
// An alternative approach, using C# 4's dynamic type
// dynamic function;
// if (!scope.TryGetVariable("f", out function)) ...
// Then use dynamic typing from C#.
double step = (maxInputX - minInputX) / 100;
for (int i = 0; i < 101; i++)
{
    values[i] = function(minInputX + step * i);
}

There's not a lot of it, is there? Note that although we only call one function, the IronPython script that's executed can have multiple functions, execute code immediate and so on. It really is a full script - we're just pulling out one function (f) afterwards.

Of course, the full code is available if you want to play with it. Be warned: I wasn't setting out to create a nicely-designed Silverlight app. I was really only interested in getting the dynamic typing working from Silverlight. It's completely untested (in terms of unit tests), there's no separation between the UI and the data, or anything like that. Please don't think I write all my code like this... but it does make it easier to follow just the bit we're interested in here.

Without further ado, here's the app to play with. Please mail me if you want more explanation - I realise this is a fairly brisk description :)