Dominic Cronin's weblog
The price of freedom
via Ned Batchelder, I came across the story of an American student, Star Simpson, being arrested for wearing an electronic circuit board as a fashion accessory while visiting an airport. She hadn't threatened anyone, but the police afterwards seemed to be giving the impression that they had seriously considered shooting her. Where does this craziness come from? When I visit my home town this coming weekend, it's quite likely that I'll be greeted at the airport by a couple of policemen toting machine carbines. This didn't use to be normal.
Let's get this straight. I was born and grew up in a free country. These days I live in a different country; also free. The police here carry guns, which I dislike, but so far I haven't seen them swaggering around with machine carbines. As a kid growing up in the UK, the prospect of seeing the police kitted up like that was unthinkable. Any applicant to the police force would have been weeded out damn smart if he'd shown the inclination to engage in such machismo. These days, it's just normal.
Many years ago, I visited Canada, (another free country). The local news on the day I arrived was of a local youth who had gone crazy and charged at half a dozen police officers with a knife. The officers in question were armed with side-arm batons, but they just shot him. I thought: cowards. The locals just shrugged as though it was normal, and it was. A good shoot, eh?
In the UK, we got through most of the IRA years without getting too crazy. If, on a tube train, someone inadvertently failed to make their ownership of a bag obvious to their fellow passengers, you might feel the occasional flush of fear, but there was no danger of them being shot for it.
That's my point. The price of freedom is that we all accept a little fear in our lives. Life isn't safe. Living is fatal. If the sight of public servants in kevlar and gunmetal makes you feel safer, then we should feel sorry for you. You aren't safer - and you just gave game, set and match to the people who would disrupt our "free" existence. Arresting a student for having a techno-chic fashion sense is the same thing. It's meant to make people feel safer. It's meant to justify the existence of the airport swat teams and all the bravado. It doesn't make anyone safer or justify anything. If anything, the more a society relies on gun law, the more likely it is that such injustices happen, and the further from freedom we all are.
If she'd been getting on a plane, her clothing would have been scanned along with her other belongings. If it had been a bomb, she wouldn't have been allowed on the plane, and she would have been arrested. What actually happened was that she was meeting someone. She wasn't even going to fly. So then where's the difference between an airport and any other public place?
Terrorist threats are most effectively countered by quiet unassuming intelligence work. The people who do such work presumably are brave and rarely swagger.
I really hope Star Simpson is exonerated of the phony charges of disorderly conduct and "possession of a hoax device". It strikes me that the ones guilty of disorder were the officers who drew their guns in a public place and threatened her life. The second charge sounds easier. She can easily show that her device was genuine. Not a bomb, but definitely a device.
O say, does that star spangled banner yet wave
O’er the land of the free, and the home of the brave?
Now you have two problems
There I was innocently browsing through a post by phil Haaak, when I accidentally clicked through an off-the-cuff incidental link he'd included along the way. Lo and behold I found myself at the blog of the esteemed Jeffrey Friedl (the guy who wrote the book on regexes) reading a post on the origins of the gag about "now, you have two problems".
Geekish humour, I suppose, but very entertaining.
BTW - subscribed, even though there's barely a regex in sight.
Vechtloop
Yesterday, I took part in the Vechtloop, a running event held in Weesp, which is near Amsterdam. I ran in the 15km event, and came in with a (for me) respectable time of 1:18:44.
Although the start involved a bit too much hanging around in the rain, once we got going, the weather improved.
You can see the route here:
http://www.sanoodi.com/route/dominic-cronin/46589/vechtloop-15km/
OK - so now I'm sick of that chinese-ish guy staring at me
I'm re-installing the Orcas beta again. That's OK - it's a Beta - you expect that kind of thing. But hang on a second.... isn't that the same sort-of-chinese-guy-but-with-arnold-schwarzenegger's-chin that was staring at me when I installed VS2005? And the vaguely-chinese-ish girl in the lab-coat? And what about the guy with all the teeth that might be sort-of-indianish-but-maybe-southern-european-with-a-deep-tan?
Oh heck - I don't blame Microsoft per se. My own company's stock-marketing-photos are the subject of a previous rant, but honestly - I keep wondering if any of those people have ever written a line of code, and if not, why TF are they staring out at me as I install my tools?
It just strikes me that Microsoft's marketing department has carefully chosen these images to avoid offending anyone, like say with the notion that a programmer might be a white bloke with a bit of a beer belly - in the second half of his forties. Don't want to do any stereotyping there eh? On the other hand - at DevDays this week, the only good-looking people there were myself and ScottGu. I don't suppose he writes any more code than I do, what with his speaking programme and all.
Anyway - enough! I thoroughly enjoyed Scott's talks - in addition to being a powerful advocate for his products, he manages to pitch it directly at the well-informed-but-caffiene-starved programmer. Nice one Scott.
Muenchian groupings in XSLT
On Friday, a colleage at work asked me how to do something in XSLT. After a minute or so humming and hah'ing I said I'd have to think about it for a while. As it turned out, it took most of the weekend. (OK - as a parent of 2 under-3s, the amount of free time in a weekend is limited, but still, this was a tricky problem.)
The source XML document was something like this:
<list> <item> <Message ID="first" "> <Title>Foo</Title> <Body>You can now find details of the blah blah blah</Body> <Date>20050612</Date> </Message> </item> <item> <Message ID="second" > <Title>Bar</Title> <Body>Flibble de dee</Body> <Date>20050805</Date> </Message> </item> </list>
Of course, there were lot more messages, but the important point was that my colleague wanted to group the messages by month. That meant that any Message whose Date element's first six characters were the same should be displayed together, no matter where they came in the source document.
This turns out to be a non-trivial problem in XSLT, and has been explicitly addressed as a weakness by the people responsible for XSLT 2.0. Anyway - the following works in XSLT 1.1; it's based on the Meunchian grouping technique (aka Fu-Muench-u).
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> <xsl:key name="messages" match="/list/item/Message" use="substring(Date, 1,6)"/> <xsl:template match="/"> <xsl:variable name="messagesWithUniqueMonth" select="/list/item/Message[generate-id()=generate-id(key('messages', substring(Date,1,6)))]"/> <xsl:for-each select="$messagesWithUniqueMonth"> <xsl:sort select="substring(Date,1,6)"/> <xsl:call-template name="doMonth"> <xsl:with-param name="month"> <xsl:value-of select="substring(Date,1,6)"/> </xsl:with-param> </xsl:call-template> </xsl:for-each> </xsl:template> <xsl:template name="doMonth"> <xsl:param name="month"/> <div month='{$month}'> <xsl:for-each select="key('messages', $month)"> <xsl:sort select="Date"/> <p> <xsl:value-of select="Title"/><xsl:value-of select="Date"/> </p> </xsl:for-each> </div> </xsl:template> </xsl:stylesheet>
I had wanted to do something less arcane. I tried various approaches beginning with a variable containing all the dates, and then refining it, but most of the time I ended up with a <xsl:for-each/> unable to consume a result fragment or some such. The Muenchian technique works, even if it is opaque, and nothing else I tried did. I think it's probably possible using a recursive template to create a delimited string of months, but this way is definitely getting added to my toolbox.
For what it's worth, I'll recommend that we don't do this at all. The XML being transformed is already generated programatically, and it should be simple enough to add a month field that will make life a lot simpler.
Agile Correctness
In his post Getting annoyed at Agile Correctness, Sam Gentile blows off a little steam at the people who engage in religious zealotry regarding agile practices. This amused me rather, as I recently had an encounter in which it seemed I was being accused of not being "agile enough".
Me: There are some of these tasks that we definitely need to do first. They are pre-requisites for tasks that need to come later.
Person who shall remain nameless: So you need to know everything before we start? We're in a conception phase!
Me: No - I just said we'll need to do some things first, and then the things that depend on them.
PWSRN: So you need to know everything before we start?
Me: I don't recall any such words leaving my mouth. (While thinking: What part of "we'll need to do some things first" did you manage to mis-translate?)
Whatever! It took a little longer to get there... I guess some people just can't metabolise clue.
A few days later, I got back from a short break to find that they'd arbitrarily switched the first and second elbonation phases, failing to note that this broke at least one dependency. Ho hum.
Separated at Birth?
I know it must be hard to make a favicon (the icon that most browsers will display just to the left of the URL in the address bar), but simply picking a letter and adding bad typography might not be enough. What about these two?
http://www.blogspot.com/favicon.ico
https://partner.microsoft.com/favicon.ico
I think we should be told.
BTW - If you get bothered by questions from your browser at this point, it's not my fault. Microsoft can't be bothered to use a certificate that joins up with the certificate authorities that Windows trusts. Doh!
Smashing the distraction stack for fun and profit
In a recent post, Ned Batchelder, said "I was already three or four levels deep on the distraction stack, so I went and looked." This phrase fascinated me. Those of us who write software, or work with other complex technical tasks, often have to solve problems on several levels simultaneously, and I have long thought of this process as being similar to the way functions are called in software programmes.
Each function in a programme is dedicated to performing some task, but it may well need to call other functions to do this. The computer can only deal with one function at once, so it first needs to save the details of the calling function before beginning to process the function that is being called. The usual way of doing this is in a data structure called a stack. (In other contexts, this kind of structure might be referred to as a last-in-first-out queue, or a LIFO.) If the called function needs to call another function, it too "pushes its state" onto the stack before making the call. As each of the called functions finishes processing and returns, the state of the function that called it can be retreived, and that function can carry on where it left off. When that function in turn completes, its state in turn is sitting on the top of the stack waiting for retreival.
When researching a new technique, or finding the solution to a problem, this is often what you do. You get to a point where you can't carry on your current line of research without first solving some other problem. At this point, you make a mental note of where you are up to, and go off to solve the problem, repeating as necessary, and hoping that you don't have to hold mental state for too many things. As you solve each of the secondary problems, you back up to the point at which you got stuck, and at which you are now presumably not stuck any more.
Of course, it's not just when solving problems (in which case you pretty much have to follow this through to the bitter end). Sometimes, you are studying, and you find something that you should understand before moving on. This can lead to the same process of parking your mental state and taking some detour. There is often a choice as to whether you should do this now (stack-based processing) or queue the problem elsewhere for off-line processing. Whether you do this will generally depend on why you're doing what you're doing at the time. In Ned's case, he decided to indulge himself and go and check up an arcane detail of the HTML specification. Under other circumstances, you might have to carry on in the interests of progress and deny yourself the satisfaction of full knowledge.
From now on, when I'm busy with private-time research projects, and free to enjoy the diversions, I'll revel in the notion that I'm somewhere in the distraction stack.
Bare-behind programming in ASP.NET
When is a Parser Error not a Parser Error?
..... when it's a BadImageFormatException, of course.
So what's he raving on about now, you may well ask? Well nothing much except an error that cropped up today when I was fiddling around with ASP.NET. Since I got my MCAD certification a couple of days ago, I've decided to take a break from the exam track for ju-u-u-st long enough to get some sanity back on the geekery front. As I'm now fully qualified to tell the world that I'm an ASP.NET expert ;-) I figured I'd spend a little time just screwing with stuff and generally trying to break things. Following my nose, if you like.... The good old fashioned way.
So there I was trying to figure out what the complete bare-ass minimum ASP.NET application would look like, partly with a view to figuring out what sort of technique to follow when developing stuff to port over to my mono server. Interesting enough. Coded up a page:
<%@Page Language="C#" Inherits="Minimal" CodeBehind="Minimal.aspx.cs%>
<html><head><title>Minimal ASP.NET page</title></head>
<body><asp:Literal>Hello, World!</asp:Literal></body>
</html>
The code behind file just has:
public class Minimal : System.Web.UI.Page {}
Hit F5 to run in Visual Studio. KAPOW! I'm a coding genius! It works! Up pops the browser with "Hello, World!" Great!
Ummm - hang on a second. View Source.... Phew - the <asp:Literal/> tags aren't there. Job's a good-un.
OK - so stick it up on the Mono site. Should just work..... just copy over the aspx file and the cs file... Open up a browser.... Surf on over.... BOFFF!! (BOFFF is the sound that bugs make. Don't ask me why!)
Let's have a look then...
Error parsing a resource required to service this request. Review your source file and modify it to fix this error.
Cannot find type Minimal
Hmmm... maybe Mono is broken. Let's try it on a proper ASP.NET server. BOFFF!
Yup! Broken there too. What's going wrong?
It turns out that CodeBehind doesn't mean a thing to an ASP.NET server, not any kind of ASP.NET server, not Mono, and not Microsoft. CodeBehind is just a Visual Studio thing. When you hit F5 in Visual Studio, it compiles it up into a dll and drops it in your bin directory. (Hey - don't look at me like that! Whaddaya mean I should know that? I don't NEED to know that, man - I'm an emcad fer chrissakes!!! )
Ohhh-Kaaayyy - let's pop over to the Windows server image and fix that.... tum te tum...
.Net framework SDK command prompt...
cd C:\minimal
mkdir bin
csc /t:library /out:bin\minimal.dll minimal.aspx.cs
Cool - that builds OK - job's a goodun.
Hang on though - quick test.
BOFFF! Bah - getting sick of this - what now?
Error parsing a resource required to service this request. Review your source file and modify it to fix this error.
Parser Error Message: Could not load type 'minimal'.
OK - then fire up fuslogvw and check what's going wrong with the load. Ah - there's an error logged in one of the output files.
0x80131107 - WTF is that!! Quick google - aha "BadImageFormatException". Well to cut a long story short, I had compiled the dll using .NET 2.0 and the web site was configured for 1.1 ho hum.
OK - back to mono - well apart from having to add a reference to System.Web (which presumably is included by default on the Microsoft sytem)
So that worked - OK - but was it the minimal-est possible way of doing it. No - I found a couple of other ways of doing it too. It was a fun day.
If you want the functionality that I had imagined CodeBehind should take care of, use the Src attribute in your @Page directive. That way - ASP.NET will compile your bare-behind class on the fly. If you don't have any code-behind functionality, you can just code Inherits="System.Web.UI.Page", and stuff like <asp:Literal/> will just work. Actually - you can even do without the Inherits; an ASP.NET page gets compiled as a System.Web.UI.Page anyway.
But why? You may ask - well how can I explain this. Did you ever see American Chopper on Discovery channel? It's pretty entertaining to watch a bunch of guys building a motorbike starting with a sketch on the back of a fag packet. Part of the reason it's entertaining is that they are thoroughly competent. They don't get stuck. When the gizmaflotch won't fit behind the whoffle sprocket, one of them will fire up a cutting torch or a grinding machine and remove the offending lump of metal. They can do that, because they aren't scared of it. They know that if they ruin it, they can weld another bit back on, or re-build that whole part of the bike if necessary.
So that's it I suppose - I'm practicing my welding.
Microsoft Press - hall of shame
Tomorrow I'm doing the last exam for Microsoft Certified Application Developer (MCAD). I've been using the official training pack from Microsoft Press, and frankly, it's appalling. Examining people's programming ability via the medium of multiple choice is dubious enough to start with, but if you're going to do it, at least make sure the answers are correct even under the most pedantic interpretation possible. To be fair, my experience of the actual exams has been that this is the case, but this little example from the sample exam in the training kit should give you the flavour of what I've found myself up against.
You create a Web custom control named Toggle that users can turn on and off.
The Toggle Control includes a Button control named toggleButton. You write an event handler named toggleButton_Click for the toggleButton.Click event. This event adjusts the BorderStyle property to signify whether the Button is toggled on or off. You want to add code to the Toggle class so that when the toggleButton is clicked, pages that contain instances of Toggle can process custom event handling code. You add the following code to the Toggle class:
public delegate void ChangedValue(object sender, EventArgs e);
public event ChangedValue Changed; protected virtual void OnChanged(EventArgs e) { if (Changed != null) Changed(this, e); }
You need to add code to toggleButton_Click so that pages conaining instances of Toggle can handle the ChangedValue event and process custom event handling code. Which of the following enable you to do so? (Choose the correct answer.)
* OnChangedValue(EventArgs.Empty)
* Changed(sender, e); * OnChanged(this, e);
* ChangedValue(this, e);
The answer given as correct is the first one, but as far as I can see, it should be something like:
OnChanged(EventArgs.Empty);
I don't write events and wire them up with delegates every day. It took me a little while to figure out that all the anwsers were wrong. (Personally I find some of the conventions here a little alien. I'm used to a world in which event handlers have names like OnThingHappened. With the .NET framework, OnThingHappened is part of the event raising mechanism: Something happens, so your class calls its OnThingHappened member, which raises the event, which some other code will have subscribed to.)
It's not just an isolated example either. One of the programming labs for ASP.NET begins with a "Switchboard" page, with links to the other pages. In the switchboard page, various DataSets are populated and stored in the Cache. In the other pages, these values are unceremoniously whipped out and used, regardless of the fact that there's no guarantee they'll be there. Bear in mind that half the reason anyone would be studying this stuff is that they probably aren't yet an expert. By the time I'd dug into the subject a little, it turned out that you can only use the web application cache for what it says on the box - caching. It's a performance tweak, and you shouldn't be using it to get data from one page to another. There are probably thousands of applications in production right now based on this fundamentally flawed technique.
Microsoft Press... hall of shame!