Archive

Archive for August, 2002

Upload problems

August 30th, 2002 No comments

For the last few days I’ve been having ADSL upload problems, which may cause subtle problems with this site. At first I thought it was the server, which had to be rebooted a few days ago for the first time in about 2 years. But, although it’s having a few teething problems readjusting to life in the modern world, I’ve discovered that Radio also has problems uploading to my company server as well. For a while I thought that maybe something had happened with Radio, but then we discovered that any upload of over about 8k is having problems (the problem doesn’t affect small files, and thus tools like ping weren’t showing any difficulties). It also doesn’t cause any problems with downloads.

So, in the meantime, I’ve had to change Radio to post to an internal server, then then manually gzip and split the files, and scp them up to here by hand. I’m only maintaining my index.html and rss.xml like this. Daily archives, and category archives will reappear once normal service is resumed.

Sorry for the inconvenience.

Stupid Employer Decisions

August 29th, 2002 No comments

Employees at the Jim Beam bourbon distillery are being limited to four bathroom breaks per 8 1/2 hour shift, only one of which can be unscheduled. Extra trips to the bathroom can result in reprimands. Workers with six violations can be fired.

When will employers stop this sort of idiocy? The company claims that this had to be put in place “because some workers abused the privilege of unlimited bathroom breaks”. But, of course, fails to explain why the company couldn’t just deal with those employees instead of punishing everyone.

It was as if it was just a spur-of-the-moment, not-thought-through-properly, type of thing either. They actually consulted with a urologist first!

Pity they didn’t consult with someone with any sense, who might have pointed out just how much productive work someone would do in an hour when the only thing on their mind was just how much time was left until their next allowable bathroom visit…

[via b-may]

Is Good Enough Good Enough?

August 24th, 2002 2 comments

Brian, a long-time friend, collaborator, housemate, and provoker of many interesting ideas and crazy schemes, with whom I have unfortunately lost touch recently, has started a blog.

Today he raises the question about whether a Jack-of-all-Trades is forever doomed to be master of none.

Brian places the issue squarely at the door of ‘drive’: I’m a great teacher … but it bores me now.

Most people just aren’t driven to be great at the things they do. Many aren’t even driven to be anything more than adequate. Once you reach an acceptable level of something, the rewards for getting better start diminishing. As Brian goes on to say, this time about programming: I’m sitting comfortably at the top of the steep part of the learning curve, with no desire to go further.

In many ways however, how you view this curve depends on where you set your sights. When I was at school, I played a lot of chess. Within the school, I was the best: I captained the chess team, and ran the chess club. I also played at BB level, where, again I became the number 1 player on the team, and for several years in a row we were the best team in Ireland. I also won the individual tournament three years in a row.

In both these circles I would have been seen as ‘great’. It didn’t take me to venture too far outside these though to start losing on a regular basis. Our school chess team didn’t usually fare to well in the league, and whilst I won a reasonable percentage of my games, I was far from invincible. When the BB team travelled to the UK finals as Irish champions, we always lost.

I started playing tournament and league chess in Belfast, and again lost frequently. Over time I got better, and got to the point where even in these circles I could be considered ‘good’. But I lost the drive to get better. I used to think it was down to the fact that I had finally beaten both my mentors after years of trying, and had no immediate achievable goals left. But this couldn’t be true. There was much further I could have gone, with obvious feedback as to whether or not I was succeeding. I now think it was because I had realised that I had gone about as far as I could go on natural talent. My mentors had been trying to get me to read chess books for years, but I never liked them (other than the excellent How To Cheat At Chess and its sequel Soft Pawn).

As far as I could see, it was precisely because I didn’t know all the standard openings that I was able to beat the players who thought that all they had to do was learn them off, and didn’t know how to play against all my unorthodox openings.

I had worked out that I was better than most of my peers because I understood how chess worked. Most players at school level tried to work out who was leading in a game by counting the value of the pieces on the board (pawn = 1 point, knight = 3, rook = 5 etc.) The better ones knew that you had to score passed pawns differently than doubled pawns, or that in the endgame bishops of the same colour were different from bishops of opposite colour. But they never really knew why. Or how to tell who had the better position in general, regardless of the numerical strength of the pieces.

It took me years to realise that although my understanding usually trumped someone’s rote learning, someone else’s understanding plus learning would usually trump my understanding.

My teachers at school had tried to point this out to me in an academic setting: my school reports were full of comments like “Tony could do much better at this subject if he stopped relying so heavily on natural ability”. But I never understood this. Most of the time this sort of comment was beside an ‘A’ grade. If I could get an A with virtually no work, why would I ever want to actually put effort in?!

These teachers failed to demonstrate what the payback would be for that effort. I read their statements as saying I would get better marks – but I was already getting good enough marks, so I couldn’t see the point. They missed the chance to teach me about the joys of mastery of a craft. They failed to imbue me with the desire to always set my sights higher, to realise that good enough is never good enough.

It has often been said that the more you know of something, the more you realise how much you don’t know. True mastery is always that next step further away. But you don’t even need to actively pursue that mastery. It has also been said that whilst there is always an excuse for not coming up with a great idea, there is no excuse for not copying it as quickly as possible. In practice my chess experience rarely holds. Basic competence coupled with the ability to learn from, and steal from, as many sources as possible, will usually trump basic understanding. In the age of the Internet, this ability is available to us more than ever before.

And in computer programming, this is probably even truer than most areas. A Perl programmer, for example, who has a deep knowledge of what’s available on the CPAN and who has the basic competence to write the glue code that ties together 5 or 6 different modules will, for 90% of the projects in which Perl is used, be at least 10 times more productive, and produce much more maintainable and accurate code, than an ‘expert’ Perl programmer who knows enough to write all this himself (and so does so).

I’d always be wary now of hiring someone who doesn’t read widely in their field. I read somewhere recently that 80% of computer programming professionals haven’t read a related book since they graduated. Even more scarily, I believe this was including reference books. That probably only leaves about 5% who actively read books with the abstract notion of “getting better at my trade”. I think I’d rather hire those people, and work with them on collectively always getting better, than hire someone with outstanding natural talent, who’s probably going to reach a pinnacle, and find it difficult to get any further.

Brian finishes by querying whether he is able to “build the discipline, patience or ambition to become really good at something”. I’d challenge him to go pick one of the areas in which he’s “good enough” and explore that next part of the learning curve. It only looks flat. And whilst the immediate rewards aren’t as obvious, looking back they’re always worthwhile.

Tags:

googleTitleSearch redux

August 23rd, 2002 No comments

The googleTitleSearch macro caches the results each time it searches Google in Radio Userland’s inbuilt database. This means that it doesn’t have to rerun the search every time you publish your blog. However, it also means that the See Also: becomes fixed at the point you publish, which isn’t always what you want – particularly if you’re commenting on something recent that Google doesn’t know much about yet, or if the links in question are no longer relevant, months later.

So, I changed the script to store the date that the query was run, and then rerun it if once a day for the first week, and then again if we’re republishing in more than a month’s time.

I also decided to refactor the code quite a bit, so I could learn more about Radio’s macro system. I learnt a lot about nested functions, and arrays, and how much I really miss map-style functions for dealing with lists!

The new code:

1
2
3
4
5
6
7
8
9
10
11
on googleTitleSearch (adrpost) {  if not defined (adrpost^.title) and not defined (adrpost^.link) { return "" };
  on htmlForResult (adr) {    on chooseToolTip(adr) {      if sizeOf (adr^.summary) > 0 { return adr^.summary};      return adr^.snippet};
    on chooseTitle (adr) {      if sizeOf (adr^.directoryTitle) > 0 { return adr^.directoryTitle };      return adr^.title };
    on tidyTooltip (tip) {      return string.replaceAll(searchEngine.stripMarkup(tip), """, "&quot")};
    on tidyTitle (title) {      title = searchEngine.stripMarkup (title);      return string.trimWhiteSpace(string.replaceAll(title, "...", "")) };
    local (url = adr^.url);    local (title = tidyTitle(chooseTitle(adr)));    local (tooltip = tidyTooltip(chooseToolTip(adr)));    return "<a href="" + url + "" title="" + tooltip + "">" + title + "</a>"};
  on resultsAsHTML (theResults) {    local (adr, htmlHTML = {});    for adr in theResults { htmlHTML[0] = htmlForResult(adr) };    return htmlHTML };
  on daysAgo(aDate) {    return (long(clock.now()) - long(aDate)) / (60 * 60 * 24) };
  on haveResults (result) {    if not defined (result^) { return false };    if result^.searchComments == "Sorry, no content found for this URL" {      return false };    if not defined (result^.searchDate) { return false };    local (lastCheck = daysAgo(result^.searchDate));    if (lastCheck > 1 and lastCheck < 7) or lastCheck > 30 { return false };    return true };
  on join (aString, anArray) {    local (i, returnString, arraySize = sizeOf(anArray));    for i = 1 to arraySize - 1 { returnString = returnString + anArray[i] + aString };    return returnString + anArray[arraySize] };
  local (seeAlso = "");  try {    local (adrSearchResult = @adrpost^.googleTitleSearchResult);    if not haveResults(adrSearchResult) {      if defined (adrpost^.link) {        adrSearchResult^ = google.search ("related:" + adrpost^.link)};      if not haveResults(adrSearchResult) {        adrSearchResult^ = google.search (adrpost^.title)}};    adrSearchResult^.searchDate = clock.now();    seeAlso = join(" | ", resultsAsHTML(@adrSearchResult^.resultElements)) };  return seeAlso };

Library Usability

August 22nd, 2002 No comments

Recently I rejoined Queen’s University Library. No bookshop in this country seems to carry a decent selection of books, so I spend a fortune buying books online that I’ve never even had the chance to skim through first. So, as the university does a special rate for graduates, I figured that it might save me buying some books that turn out to be useless (I’ll still buy all the ones I borrow and like – I prefer having my own copy). It also gives me access to a good selection of books that are out of print, and a great archive of journals.

The library is spread around the city at about 5 or 6 locations, but so far I’ve only really been using the Main Library on the main university campus. It has most of the business books, and most of the theology and philosophy books, and I’ve had a lot of fun working my way through some of business journals that aren’t available online.

Today I decided I’d investigate the Science Library, about a mile away from the Main Library, which houses the computer books. Mainly I was trying to get a copy of Jerry Weinberg’s “Quality Software Management” series. I used the catalog to find the location (QA76.76.D47 for any library geeks amongst you), and walked down to where that location should be. I managed to find the first volume (Systems Thinking), but not vols 2 and 3, which have the same shelfmark. I scanned the surrounding shelves, in case they’d been mis-shelved, but to no avail. It’s out of term so there was only one person that I could see sitting around, and she didn’t seem to have the books, so I was stumped. The catalog had said they weren’t on loan, so where were they?

I returned the catalog just to double check, and discovered that, yes, they books were available, and yes I had the correct shelfmark, but no, I didn’t have the correct library – volumes 2 and 3 both lived in the Main Library!

I spent 5 years at QUB as an undergrad, 3 as a postgrad, and worked in both the Main Library and the Science Library for about 3 months, and never once knew that the Main Library also held computer books! I knew that some lived in the David Bates Library (a building that seems to be modelled after an Escher painting, or designed by someone on bad drugs), but it turns out that there’s a small selection (maybe about 5% of the computing books?) in the Main Library as well.

However, there seems to be no sensible reasoning behind which books go where. As well the bizarre split of the Weinberg books, the Science Library has Tom DeMarco’s Why Does Software Cost So Much? (a book I’ve been trying to get hold of for quite some time), but Peopleware lives in the Main Library. The Science Library seems to hold all the Python books (in fact, most of the specific language books), whilst the Main Library holds the Perl books! (including, interestingly, Dave Cross’s Data Munging With Perl)

As I wanted all 3 volumes of “Quality Software Management” (actually, I wanted all 4 volumes, but they only have the first 3), I had to visit both libraries. I asked at the issue desk of both how it was decided which library got which book. At the Science Library they were totally stumped. Their first answer “depending on subject matter” instantly crumbled when I explained how 3 books in the same series, by the same author, with the same shelf-mark, were in 2 different libraries. In the Main Library however, they seemed to have a more plausible answer: “it depends on which department orders them”.

I can almost see how this makes sense. Students tend to mainly use only one of the libraries, depending on their course, so if a certain department orders books for its students, it’s plausible that they’d want those books to be in the library that those students frequent (if students actually frequent libraries …)

This is fine for required reading texts (although most of those are usually held in departmental libraries), but gets really confusing really quickly for general books.

And don’t get me started on how unfriendly their on-line catalog is!

I did discover The Little MLer though, which I’ve never even heard of before. I’ve recently read The
Little Lisper
and The Seasoned Schemer, and really enjoyed the Q&A style of them, so I decided to borrow this one, which is written in the same style.

And I discovered that the Science Library has an almost complete back catalog of Byte, Joop, Proceedings of the ACM to browse at a later date…

Online or Invisible?

August 21st, 2002 4 comments

A few days ago I brought a stack of old issues of ‘Look And Learn’ into the office, so that Marc could share in my happy reminiscing of the days when children’s magazines were filled with 1000+ word articles on interesting subjects. And we got to wondering just why there’s nothing like this available today. A random issue picked from the pile has articles on the power struggle after Nero’s death, the Boxer Rebellion, “When Woden Went To War”, a ‘Blue Angels’ display over Niagara Falls, how the monsters in horror films are made, the Vedda tribe of Sri Lanka, the peregrine falcon, the invention of the telephone, and brief bios of Catherine The Great, Robert Edwin Peary, and Professor Edward George Challenger

You couldn’t even get any magazine discussing this range of topics today, never mind one aimed at children (presumably children under 10, at that, although I can’t remember what age I was when I read it).

As these discussions have a tendency to do, we got sidetracked into a discussion on how the dead-tree encyclopedia market has collapsed, and how even beyond that, if information isn’t available on-line now, to many people it just doesn’t exist. (CiteSeer, the excellent service for finding scientific literature references, even has a link at the bottom of every article page, to Online or Invisible, the title of which speaks for itself!)

Marc didn’t believe that there would be anything in Look and Learn that couldn’t be found on-line, so we selected an article pretty much at random, from one of the issues, a 2 pager from May 1977, on “Tribe Without a Future”, on the Kurelu people of New Guinea.

Google returns 22 matches. Almost all of them are references to a book by Peter Matthiessen: “Under The Mountain Wall” Stone Age New Guinea”, describing his time amongst the tribe in 1961. None of them tell us anything about the tribe itself.

The “Look and Learn” article states that “although their roots date back as far as prehistoric times, the future of the Kurelu remains a great question mark which can only be answered by those who govern the future.”

Well, it’s 25 years on from that now, but if you want to know their fate, you’ll have to work harder than a visit to Google.

Tags:

Increase Online Revenue With Contingency Design

August 19th, 2002 No comments

New Architect shows (with examples of the good, the bad, and the ugly), why contingency design is important, and what you should do – including some nice tips I haven’t come across before (like ww.amazon.com [sic]).

This is another one of those areas where people seem to be paralyzed by their inability to create a 100% solution, and so never even get a 20% solution never mind an 80% one. You don’t have to spend hundreds of thousands of dollars on a state of the art search engine. A simple solution is to just log all the searches that fail, work out what they should have matched (usually it’s a simple mis-spelling – particularly if your search engine is picky about punctuation), and then add something that automatically maps all future searches for that term to the ‘correct’ version. 20 minutes a day working your way down the most popular mis-searches will catch 80% of your problem cases in 6 months …

[via Tomalak]

How to Read Blogs

August 17th, 2002 No comments

Scott comments on the update frequency of blogs: daily, I run thru a list of links and when I suspect they won’t be updated, I just skip over them.

Like Scott, I also don’t like aggregators. I played with them for a while, but they just didn’t fit the way I like to read, and, yes, I like to read “in context”, so to speak – I like browsing outwards from people’s blogrolls etc when I have some spare time.

Ever since I changed my blogroll to show me the last time something was updated, it’s been amazing. I no longer waste time visiting blogs that haven’t updated, and I also get to see when the less frequently updated blogs have changed. For me it’s the perfect solution.

Unfortunately it relies of having server side scripting capabilities (see my earlier description of how I did it), which probably rules out most Radio users. But I expect to see it in Movable Type any day now …

Tags:

More Dijkstra

August 17th, 2002 No comments

We now know that electronic technology has no more to contribute to computing than the physical equipment. We now know that a programmable computer is no more and no less than an extremely handy device for realizing any conceivable mechanism without changing a single wire, and that the core challenge for computing science is a conceptual one, viz. what (abstract) mechanisms we can conceive without getting lost in the complexities of our own making.

But in the mean time, the harm was done: the topic became known as “computer science” – which, actually, is like referring to surgery as “knife science” – and it was firmly implanted in people’s minds that computing science is about machines and their equipment. Quod non.

(These days I cannot enter a doctor’s, dentist’s, or lawyer’s office without being asked my advice about their office computer. When I then tell them that I am totally uninformed as to what hard- and software products the market currently offers, their faces invariably get very puzzled.)

This was written in 1985, and I don’t think things have changed much! I still have to explain to people on a regular basis that I don’t actually know very much about computers per se, and probably can’t tell them what’s wrong with their printer/email/word processor/whatever.

Tags:

googleTitleSearch

August 15th, 2002 No comments

For a while now, I’ve been using Jake’s googleTitleSearch macro to auto-populate the “see also” links after my posts. But I’ve been noticing more and more that all the links that Google is offering for some titles are the same – particularly when I link to articles at sites which operate on multiple URLs. I’m sure Google will sort out this problem eventually, but in the meantime I’ve made a few changes to the macro so that if I create a link for a post, it will do a google search on what is related to that, instead.

The macro, with my changes highlighted:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
on googleTitleSearch (adrpost) {
  local (htmltext = "");
  if defined (adrpost^.title) or defined (adrpost^.link) {
    try {
      local (adrSearchResult = @adrpost^.googleTitleSearchResult);
      if not defined (adrSearchResult^) {
        if defined (adrpost^.link) {
          adrSearchResult^ = google.search ("related:" + adrpost^.link)};
        if not defined (adrSearchResult^) or adrSearchResult^.searchComments == "Sorry, no content found for this URL" {
          adrSearchResult^ = google.search (adrpost^.title)}};
      local (adr);
      for adr in @adrSearchResult^.resultElements {
        try {
          local (url = adr^.url);
          local (title, tooltip);
          if sizeOf (adr^.directoryTitle) > 0 {
            title = adr^.directoryTitle}
          else {
            title = adr^.title};
          title = searchEngine.stripMarkup (title);
          title = string.replaceAll (title, "...", "");
          title = string.trimWhiteSpace (title);
          if sizeOf (adr^.summary) > 0 {
            tooltip = searchEnging.stripMarkup (adr^.summary)}
          else {
            tooltip = searchEngine.stripMarkup (adr^.snippet)};
          tooltip = string.replaceAll (tooltip, """, "&quot");
          htmltext = htmltext + "<a href="" + url + "" title="" + tooltip + "">" + title + "</a> | "}}};
    if sizeOf (htmltext) > 0 {
      htmltext = string.mid (htmltext, 1, sizeOf (htmltext) - 3)}};
  return (htmltext)}