Mark Rees is getting close to releasing a WSGI implementation for Windows based webservers that support ISAPI.
Well, it’s that time of year again, my weblog is a year older as of last Friday, which means I indulge myself another with a post about how cool it is to be weblogging.
But first, “Hi!” to everyone who reads. I appreciate your comments – they brighten my day. An extra big “G’day” to Christine, for her comment. 1
Second, thanks to all my blogging friends. I enjoy reading you, and I also learn from you. Particular thanks to Charles and Simon, whose writing styles continue to inspire me. If I could write half as well, half as much as you guys, I’d feel like a hero.
In addition, Charles continues to give me posting privileges to his quicklinks weblog, which has proved an interesting diversion. It’s also neat because quicklinks has a larger readership than my own weblog, though perhaps smaller than it might be if Charles didn’t allow me to post all kinds of random bizzarities. Thanks Charles!
Onwards to the self indulgence. Things that happened this last year:
My favourite posts from this year were these two exchanges with Carl Fyffe. We both managed to be polite, despite discussing topic we both felt very strongly about, and in the end I came to understand where he is coming from, and why he thinks as he does.
I’m also proud2 of causing the Sydney Morning Herald to pull one of Microsoft’s ads from their website, of dissing Samsung for turning the Olympic flame relay into a mobile advertisement, although that complaint had considerably less effect.
Blogging continues to cause me to improve my writing.3 I’ve read three books on writing this last year, which is two more than I ever have before. My Internet skin continues to grow thicker, but I can use more practice their too :)
Looking forward to this next year, I plan to be posting longer, more in-depth articles, but far less often than I have been. There’s plenty of interesting things going on in the Python and Groovy worlds and I think the world needs to know.
I’ve started a new weblog, where I’ll be posting non-technical items. I’ll post the URL when it has some meaningful content.
And that’s it for this year. Catch you all next year for cardboard.nu’s third birthday post. Happy reading!
1 My weblog is the #1 Google hit for cardboard properties. Hehe.
2 I did mention that this post was going to be self-indulgent, didn’t I?
3 Except that I still don’t feel particularly squeamish about using the word ‘blog’ as either a noun or a verb. In fact, I wouldn’t be surprised if – after only a few drinks – I were to write “my blog bloggishly blogs my blogedly blogging habits,” or something equally stupid.
That's our old wiki.
We don't really use it anymore anyway.
We're going to shut it down someday.
We're using Confluence for our website and wiki.
-- Guillame Laforge's reply to groovy-user when asked about a broken page.
You know a product is good when people start writing poetry about it.
Casey has been teaching Python to high school students as part of the ACS‘s National Computers Science School.
Yay Casey! Yay Python!
Karen and I are finding it really hard to ‘do’ Santa Claus with Mitchell and Connor.
For the last few years Mitchell has been somewhat suspicious about Santa Claus. Two years ago we dismissed his concern, telling him, “If you don’t believe in Santa Claus, Santa Claus won’t believe in you” and if Santa doesn’t believe in you, he can’t bring you presents, can he? One year ago, he wanted to build an alarm to attach to the door on Christmas Eve, so he could catch Santa Claus, and verify it for himself. But this year, Mitchell boldly and proudly declared – within earshot of younger brother Connor – that there is no Santa Claus.
We admonished Mitchell that he should let his brother go on believing in Santa Claus, and Mitchell agreed. But Mitchell can’t keep a secret.
On Christmas morning Mitchell and Connor woke up, grabbed their Santa sacks and openned them on the family room floor, showing off each one as it was pulled from the sack. Being a polite boy, Mitchell couldn’t help himself, “Wow! Thanks Mum!” Karen replied with a meaningful stare, and Mitchell figured out what he’d done wrong. “I mean… thanks mum for all the presents you gave me… before… for my birthday…”
Since Christmas, I’d been wondering whether it was OK to keep “lying” to Connor about Santa Claus, the Easter Bunny and the Tooth Fairy. There are pros and cons, but then Connor made it clear that ongoing deception costs.
Being six, Connor is losing his baby teeth. They go into a glass of water, and the tooth fairy takes the tooth, leaving fifty cents. Always fifty cents. In the form of a single fifty cent coin. That’s the way it works at our house, and I’m pretty sure Connor has appraised his mouth, maybe even taken out a mortgage against it. So last week, when Connor lost a tooth while staying at his grandmother’s, and Grandma asked how much the tooth fairy left for a tooth, Connor said, “four dollars.”
I did a trial port of our application from JDK1.4 to JDK1.5, using Eclipse 3.1M4. The results were encouraging, but we won't be moving across right away.
To give you some idea of the size of our project, it is comprised of two sub-projects: the first is a bunch of utility and helper classes that runs to about 10k lines, and the other is the main application at about 40k lines. We make good use of open source libraries and frameworks, including Spring, Hibernate, Apache Axis and Jakarta Commons.
I first recompiled the utility project under JDK 1.5, coming up with 28 warnings and no errors. A fair number of the warnings were to do with not having a serialVersionUID on a serializable class. I gave up fixing those when it wanted me to put a serialVersionUID in an anonymous subclass of javax.swing.AbstractAction. (As an aside, Eclipse lets you turn off a warning completely, but it would be nice if I could have turned off this warning for subclasses of Swing classes.)
Most of the rest of the warnings were fixed by simply adding type parameters to collection types; for example, List might become List<String>. I also removed unneeded casts, and used the new for-loop syntax wherever appropriate. This is a fairly routine, mechanical process, and I was done in about two hours.
I then loaded up the bigger project and promptly received 31 errors and 400 or so warnings.
The errors were because we use the commons-lang Enum class, and enum is a reserved word in JDK 1.5. The fix was to convert to the new Java enumeration types. This was straight forward, mostly because the JDK1.5 and commons-lang enums are both based on Joshua Bloch's typesafe enum idiom.
Converting from bare types to parameterised types was interesting - it forced me to determine the type of every collection, and it wasn't always obvious. By putting the type of the contained element with the collection declaration, it is easier for somebody casually browsing the source code base to understand it.
One very cute method buried in the JDK1.5 library is Arrays.asList(), which converts an arbitary bunch of parameters into a list. For example, we have this ugly code to build a list of three Strings and pass them to a constructor:
DispatchSourceTextGroup dstg =
new DispatchSourceTextGroup(new ArrayList() {
{
add("FIRE INDICATOR PANEL");
add("CFA-T3106130011-1");
add("FULL CALL");
}
});
Naively converting to generic types yields this typesafe, but even uglier code:
DispatchSourceTextGroup dstg =
new DispatchSourceTextGroup(new ArrayList<String>() {
{
add("FIRE INDICATOR PANEL");
add("CFA-T3106130011-1");
add("FULL CALL");
}
});
Arrays.asList() lets us write this comparatively nice code instead:
DispatchSourceTextGroup dstg = new DispatchSourceTextGroup(
Arrays.asList(
"FIRE INDICATOR PANEL",
"CFA-T3106130011-1",
"FULL CALL"));
My only gripe is that it is not obvious (from this usage) why the method is on the Arrays utility class. Perhaps it could be aliased to Collections.asList() in a future release?
The new for loop syntax gave us some good wins too. For example this nested loop:
public void checkExtrasGuids() {
for (Iterator i1 = extrasMap.keySet().iterator(); i1.hasNext();) {
String kioskName = (String) i1.next();
for (Iterator i2 = ((List) extrasMap.get(kioskName)).iterator(); i2
.hasNext();) {
DispatchExtras extras = (DispatchExtras) i2.next();
checkKioskHasGuid(kioskName, extras.getDispatchGuid());
}
}
}
becomes more understandable:
public void checkExtrasGuids() {
for (String kioskName : extrasMap.keySet()) {
for (DispatchExtras extras : extrasMap.get(kioskName)) {
checkKioskHasGuid(kioskName, extras.getDispatchGuid());
}
}
}
I didn't finish the port of this part of our application, but based on my progress over three hours, it would take two days to complete. My main area of concern is that we may need to move from Hibernate 2.1 to 3.0, which is being developed with JDK1.5 in mind.
JDK 1.5 gives our project some small but definite wins. They would be big enough to justify a switch from JDK 1.4, except for one thing: IBM has released Eclipse 3.0-based Rational tools which have some really neat features for visualising the structure of your application. Based on the trial version that I (finally, with much effort) downloaded, modelling tools will be more useful than language features, so JDK 1.5 can wait until IBM's tools catch up.
The Sydney Python Meetup last night was great. I was initially expecting to meet with four or five others, but in the end we had fourteen. There was a good mix of experienced Python programmers, hobbyists and newbies and the “show-and-tell” was of a very high standard too.
A quick rundown on the presentations:
Casey couldn’t come, because he is teaching at a computer science camp. He sent along this paragraph to read out:
Sorry I can’t make it tonight, I hope you are all having fun. I am spending the week helping my group of twenty year-11 students, generally bright but with little or no programming background at all, build an entire search engine in Python. That’s a spider, an indexer, a search engine, a query engine, and a website, in four days and about 30 hours of lab time. They’re on schedule! I can’t think of another language that you could throw at students of this level and see any results at all, let alone something of this scale. Go Python, go!
Fascinating. I’m hoping Casey will post some more details on his blog.
Owen gave us a run-down on his RailXML project, which will make the entire Sydney train timetable available in XML format. The data is extracted from the CityRail timetable web pages, which is quite a feat. Andrew suggested the Beautiful Soup parser might be helpful. It will be interesting to see how RailXML evolves, and what uses the data might be put to, once available in this easy-to-use form.
Andy gave us a tour of PythonCard, for which he is release manager. Turns out that PythonCard more complete and usable than I thought it might be, so I’ll have to give it a try.
Tim Churches showed us NetEpi the Python application he has been building with the Health Department over the past few years. NetEpi is remarkable for a few reasons:
NetEpi uses the Albatross web framework, and draws graphs using R. (When Tim first mentioned R, we thought he was putting on a pirate voice.)
Finally, Ben Decker presented his work on the DOS port of Python, PythonD. It turns out that DOS alive and well on the PC and is used in various embedded controllers too. Ben’s DOS port includes support for networking, OpenGL, threading (on DOS!), Ncurses, and more. I am impressed.
Thanks to everyone who came along – it was an interesting evening. A big thankyou to those presented. The next meetup will be in March or April. If you’re in Sydney, hope to see you there.
The new year is getting underway and once again I find there are far too many interesting things to do. Real Life™ is also crowding in; I have to make decisions about how to spend the limited time I can devote to my computing hobby. Here are my current lists.
Things that there just isn’t enough time to do:
For a company that makes its money selling business integration products and services, IBM sure has a long way to go.
Take their web site, for instance. I am downloading IBM‘s new IDE, Rational Software Architect. Because of bad design and poor integration, it took me half an hour to register a login that would allow me to begin. I am hoping IBM‘s web people will read this, so I’ll use little words and bullet points.
Your profile is missing information that is required by this offering. Please CLICK CONTINUE BELOW, THEN LOG IN AGAIN WITH THE SAME USERID, CLICK CONTINUE, THEN UPDATE YOUR PROFILE. You will eventually be returned here to continue with this offering. Note that if you have gotten this error for the second time, you may have used a different userid when logging in to update your profile. If so, please click 'sign out' and then try again, being certain to use the same userid you logged in with initially. If you do not remember what id you used initially, close your browser and re-open it, then log in again. Another reason you may still be getting this error is you may not have clicked 'continue' on the next page and completed the update of your profile. Please be sure to keep proceeding by clicking 'continue' when it is presented, and do not back up or you will not correct the situation which is stopping you now.
Shame, shame, shame, IBM. Shame, shame, shame.
1 Despite the fact that at the end of the registration process, the site proclaimed that I was “now registered with ibm.com”. Oh well. It gave me a nice warm feeling at the time.
2 I’ve only encountered two recently. I suspect that there are more.
3 The content of this last sentence may be bleeding obvious to you, but some people at IBM need it spelt out.
I just took the back off our washing machine (11 screws), disconnected two internal hoses, took an electic motor off its mounting, cleaned out a blocked pump and then put it all back together with no missing parts, and no left over parts.
To my complete astonishment, there wasn’t even a small leak when I successfully washed a trial load. The eight-inch high flood wall I had constructed out of dirty towels was for nought.
I am so proud of me.
It wasn’t a one man effort, though. My cat helped out by sitting on the screwdrivers after I openned the case. I was really pleased about that. It’s important to keep the idle screwdrivers warm, especially if you are going to need several sizes and types in quick succession. He also lay down on the socket set when I openned that too.