Thursday, December 30, 2010

Don't work more: work better

Sustainable pace is one of the practices of XP; having provided the link, and assuming you know what it is, I won't further indulge on the subject. Why am I talking about it then?

Because, thanks to Paolo, I am reading The Little Big Things by Tom Peters, and I stumbled upon the following sentences (re-translated in English from the Italian version), that according to the author apply in hard times as well as in good ones:
  • Get to work earlier than usual.
  • Leave later than usual.
  • Work more.
  • Volunteer to do more.
Now. This sounds quite different from sustainable pace. It also sounds different from the slack periods that the very same author reports as very important just a few pages earlier.

Why should we work more? I can understand that arriving earlier and leaving later leaves you some time all by yourself in the office, which is when you tipically can perform better because you can get some uninterrupted quality time. But you cannot count on such a short amount of time to complete everything you're supposed to do during a whole day.

And how about your canonical eight hours? Are they all wasted as "the big slack time between early morning and late evening"? Nope, you're supposed to work. Does this come as a surprise? That's very strange, because it is precisely what you are being paid for. So why add the extra hours? You're not being more productive, you're just spending more time at the desk. No, really, Peters goes as far as saying "work more for less". No way. At least, things being as they are now.

Let's get back to sustainable time. Suppose you're a workaholic: you spend at least 12 hours a day at the office, trying to compensate with brute force for your laziness. You are often so tired that your judgment is hiding somewhere under your shoes, and you can't tell whether you still have to bang your head on the wall on little and useless details or you can pass to something else. Or, better yet, call it a day. This is not committment, this is a physical dependency. How long do you think you can sustain it before reaching a burnout? Not very much. You're doomed. And you've wasted your time, not to mention the money of your employer.

Moreover, this is also very bad for morale: not only yours, as you obtain very little despite your enormous efforts, but also of the people surrounding you. People will start feeling guilty because they work less than you do, so they'll feel compelled to stay just because you do, even if they don't have anything to do but keep their chairs warm. Isn't that absurd? Yet, here in Italy you are too often judged by the time you spend at your desk. Even if you don't produce anything worth your time.

I'm sure Mr. Peters didn't mean "waste your day spending more time at the office", but unluckily it is exactly what is going to happen.

Get yourself a life! Strive for excellence, and work better: if you do it you will achieve the same results in less time. Absurd? Yes, it is: actually you will get much better results in much less time.

A simplified example for programmers? concentrate and try to make your code easily readable, not only by you but also by other people (which also means you, as you will not even remember you wrote that piece of code in a couple of months). Write automated tests. Refactor. Eliminate duplications. Do I hear "it will take more"? Yes, it will take more. But just on the barrelhead. As I read today on twitter:

Programming is like sex: one mistake and you’re providing support for a lifetime. (Michael Sinz)

Do your maths...

Monday, December 20, 2010

Meet Flatworm

I'm OK with flat files, but why should you use a fixed-length record when every row is formed by 1320 chars, most of which are blank? Isn't it an enormous waste of resources?

Anyway, should you need to deal with flat files (it seems like no programmer can keep them at bay... does this ring a bell?) after some investigation I stumbled upon Flatworm, an interesting library that lets you read from a flat file, be it fixed-length or separated by a separator character, and instantiate the appropriate beans. It also supports repeating segments or multi-line records. Nicely enough, it also work the other way around, which it what I was primarily interested in.

All you have to do is provide a descriptor in XML format, sit back and relax. Let's see how it works.

Let's suppose we need to produce a fixed-length file with the following format:
XXvalueOne  valueTwo  
i.e. a fixed record identifier and two fields of 10 chars each.

First of all you have to provide the descriptor:
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE file-format SYSTEM "http://www.blackbear.com/dtds/flatworm-data-description_1_0.dtd">
<file-format>
<converter name="char" class="com.blackbear.flatworm.converters.CoreConverters" method="convertChar" return-type="java.lang.String"/>
<record name="whatever-record">
<record-ident>
<field-ident field-start="0" field-length="2">
<match-string>XX</match-string>
</field-ident>
</record-ident>
<record-definition>
<bean name="whatever" class="my.package.Whatever"/>
<line>
<record-element length="2"/>
<record-element length="10" beanref="whatever.propOne" type="char">
<conversion-option name="justify" value="left"/>
</record-element>
<record-element length="10" beanref="whatever.propTwo" type="char">
<conversion-option name="justify" value="left"/>
</record-element>
</line>
</record-definition>
</record>
</file-format>
Then you can write a simple class that, given an iterator of whatever you have to export, creates a file and populates it:
public class SimpleExporter {

FileCreator fileCreator;
Iterator<Whatever> iterator;

public SimpleExporter(
Iterator<Whatever> iterator,
final String configFile,
final String outputFile)
throws FlatwormCreatorException {
this.iterator = iterator;
InputStream config = Thread.currentThread().
getContextClassLoader().
getResourceAsStream(configFile);
fileCreator = new FileCreator(config, outputFile);
}

public void execute() {
try {
fileCreator.setRecordSeperator("\r\n");
fileCreator.open();
while (iterator.hasNext()) {
Whatever whatever = iterator.next();
fileCreator.setBean("whatever", whatever);
fileCreator.write("whatever-record");
}
fileCreator.close();
} catch (IOException ex) {
Logger.getLogger(SimpleExporter.class.getName()).log(Level.SEVERE, null, ex);
} catch (FlatwormCreatorException ex) {
Logger.getLogger(SimpleExporter.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
Exceptions should be managed row by row, but just stay with me for the example, OK?

For the sake of this example the Whatever class is just a POJO, so it's not worth reporting it here. So what have I done? I just created a FileCreator object passing it an InputStream to the descriptor and the path for the output file. That was not hard, was it?

If your bean has inner properties you can simply use a dot notation:
<record-element length="10" beanref="whatever.outerProperty.innerProperty" type="char">
Playing around I had some little tricks to learn: maybe there's a better way, but they work :-) for example I had to write several fields which are not present in my beans. For this I simply added a "filler" property of type String and used it in all such cases, adding a comment in the desctriptor to specify what I was substituting.

Another problem emerged when the properties in my bean were null; to fix this once and for all I simply extended the CoreConverters class adding null-safe operations:
@Override
public String convertChar(String str, Map<String, ConversionOption> options) {
return super.convertChar(str == null ? "" : str, options);
}
That said, I found the library really useful as it saved me a lot of time.

Thursday, December 16, 2010

Did you really mean "variable"?

As seen in a request for support:
Where does the system get the $ExternalParty$ variable? is it variable or fixed?

The sentence has been translated, but in no way altered in meaning.

Wednesday, December 15, 2010

How to stretch a flat file to a fixed length with awk

I never fail to wonder at the power of unix commands. Today's story is related to the need to manage a supposed-to-be fixed length flat file in which some records end many characters before the desired length is reached.

In such cases awk does a hell of a job with just a one-liner:
awk '{printf "%-116s\n",$0 }' RS="\r\n" input.txt > output.txt
That's it :-)

Tuesday, December 14, 2010

Gmail Notify plugin

Let me start with a disclaimer: this post is not against the tool, but against what I see as a toxic habit.

This NetBeans plugin enables notification in the IDE when new Gmail messages become available. I am sure many people will find it very useful, yet I am trying to draw my personal battle line. We are overwhelmed by distractions, and adding another one would only worsen the situation.

Do I really need to check that e-mail immediately, or can I safely ignore it for another 15 minutes? If you use the pomodoro technique you organize your work in short 25 minutes stints, so the average delay is absolutely trifling. The same holds true if you use similar time management techniques.

Interruptions break your flow, and getting back to what you were doing becomes increasingly hard. That's why you should strive to manage interruptions, not to be ruled by them. A notifier is an interruption, and as such should be dealt with.

I normally check my e-mail(s) between pomodoros, and that's not a secret for anyone: I am not at the service desk, so my "flow" periods are not 5 minutes bursts: there are days in which I don't even check the trouble ticketing system. I admit this could sound excessive, but there are many other brilliant people on the responsibility chain before me, and this could loosen the stiffness in your back a little. I am confident that if a pressing situation arises I'll be reached by a telephone call, and if the situation requires it I'll manage the interruption catching it and trying to solve the problem as soon as possible. I'd like to say "as soon as it is needed", but you might have noticed that saying no is not so easy. It is even less so when we're saying no to ourselves.

Yet, if we want to put the most precious resource we have to good use, we have to learn how to do it.

Wednesday, December 1, 2010

Verbal Communication

Humans used to have such a marvelous oral tradition; myths and history were passed orally from one generation to the next. Until an Athenian ruler started writing them down Homer's The Iliad so that it would not be forgotten, stories like Homer's were told, not read. Our memories must have been a lot better back then and must have started to fade sometime in the 1970s because by then we could no longer remember even short statements like "The system shall prompt the user for a login name and password". So, we started writing them down.

And that's where we started to go wrong.

This is an excerpt from Mike Cohn's "User Stories Applied", which I encourage you to read.

What's wrong with written requirements? Actually they have advantages as well (traceability is an example), but they are based on a flawed assumption: they capture every detail of what must be developed. This is practically impossible, with the only exception of very trivial systems. Nevertheless, we do want to write something down, at least to be sure not to forget important things. So what do we have to write down?

User stories are very useful for many reasons, but one of them is that they favour high-bandwith face-to-face communication; actually stories are reminders for conversation. This calls for (I'd like to say force but it would be too optimistic) the customer and the team to interact frequently, thus leading to a product that is just what the customer wants instead of - at best - what is captured on a ton of paper that nobody reads.

This might not be true for every domain; some specific software would probabily require a very complete and detailed document, but this does not apply to anything I've had to develop so far (but I wouldn't be able to say anything about software for pacemakers). Yet, I think any written documentation is not complete unless it also describes how to test a feature. That is definitely what I'd like to have, rather than a series of "the system shall...". Oh forgive me, it is "the System shall...", capital S, we don't want to underestimate the beauty and the power of our product (which by the way does not yet exist if not in our dreams of glory).

Is time spent on requirements completely wasted, then? I think it is not. Requirements do not come out of thin air, so at least all the conversations held in requirements workshops can help the developers (but most of all the customers) to clarify what the business rules and information flows really are and what the system will really need to do in order to support them.

And this only emerges through verbal communication.