News

Programming by intuition

According to dictionary.com, programming is the creation of a sequence of instructions to enable a computer to do something; intuition is the act or faculty of knowing or sensing without the use of rational processes, and the knowledge gained by the use of this faculty. I make the claim that all of the best programmers are able to perform programming by intuition and that these are the people that you want to employ in your company or have as colleagues.

The motivation for this article comes from both my own frustration and joy in writing programs and the experiences others have shared with me on the topic. I hope you will agree that many, if not all, of the APIs we use never work as described or documented out of the box. On the other hand, almost everything will eventually work and perform the exact tasks described by the vendor. The job of the intuitive programmer is to take software that on the surface doesn’t appear to do what it is supposed to do and make it work.

First, let me say that I don’t blame anyone for this problem. It’s simply a fact of life that every developer has to deal with. We are constantly piling abstractions on top of abstractions. As I am sure many of you would agree, at some point this abstraction hill will turn into a mountain and collapse under its own weight; for now, however, we are safe. So onward and upward we go.

Let me give you a little example of what I mean. I recently purchased some hardware to hook up one of those cool little bullet cameras to my PC. Buying and installing the hardware was no problem. Then it came time to install the software. First, I had to install Microsoft’s DirectX 9.0 and then Windows Media Encoder 9.0. Next, it was the DAO/MDAC Component Package. After that, it was the card’s drivers and software to make it work -- well really play -- with the camera. This was all on a clear version of XP, with nothing additional installed, and the service pack. Do you think it all worked?

The answer is, amazingly, yes. However, it only sort-of worked. The software that came from the card’s manufacturer kept freezing. So assuming I had the latest and greatest version of everything, what was I to do? To start, I used my intuition. We all know that many companies can’t write drivers. This seemed to be the case here. I went out on the Web and found an open-source driver for my card, installed it and everything worked perfectly, thank you very much. But it still raises a familiar question. While everything worked in the end, why did I have to go and find another set of drivers? Don’t companies test this stuff? We all know the answer to that one. If you don’t, I strongly suggest that you check out the JUnit testing framework (http://junit.org/index.htm). You will be glad you did … and so will everyone else using your software.

Next, it was my turn to add to the mountain. I wanted to write my own camera application, so the Java Media Framework (JMF) (http://java.sun.com/products/java-media/jmf) seemed like an obvious choice. The download was quick, the installation painless and I was ready to program. I downloaded the cross-platform Java edition thinking that I wanted my application to run everywhere; but it didn’t … not even on my own platform. I then thought that I would just un-install it and install the Windows Performance Pack version instead. After un-installing the cross-platform Java version I had to reboot my machine, so I turned it off to go to lunch. That was a big mistake. When I booted up again I received -- you guessed it -- the blue screen of death. I was back to square one. As it had only taken me the morning to get to where I was, I figured I might as well burn up the afternoon, too. I re-installed XP, the card software, the open- source drivers and the “correct” version of the JMF, and it worked -- or at least it didn’t crash. Next was an attempt to write some software to see a screen with images from my camera.

I applaud the people at Sun and those who worked on the JMF. It worked the first time. I was able to get a viewable screen up and working with my media player in no time. At last, one little success. Sometimes things do actually work.

I then decided to try sending some bytes of information to a server using Servlets. All I wanted to do was a POST, and I didn’t care about the response, or so I thought. The code for this task is as follows. While I have not shown the actual bytes I wrote, I can say that they were correct.

URL url = new URL("http","localhost", "/servlet/cameraServlets.UploadServlet");
HttpURLConnection connection =
(HttpURLConnection)url.openConnection();

connection.setDoOutput(true);
connection.setDoInput(true);
connection.setUseCaches(true);
connection.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + CONTENT_BOUNDARY);

DataOutputStream dataOutputStream =
new DataOutputStream(connection.getOutputStream());

//Field 1 a Field of data
dataOutputStream.write (…..)
“…”
//Field 2 a Field of data
dataOutputStream.write (…..)
“…”

//Field 2 a Field of data
dataOutputStream.write (…..)
“…”

dataOutputStream.flush();
dataOutputStream.close();

The problem I had was that nothing was sent to the server. What would you do? As it turned out, one thing I should not have done was to flush the stream. It was not really my problem, but apparently the results are undetermined when you flush. The part that I was missing was the following:

connection.getInputStream().close();

That’s right. You have to get the input stream even if you don’t want the result to force the sending of the request. This is probably documented somewhere, but it was non-intuitive to me, at least at first. But I figured it out on my own and by asking around. If you have a hunch, go with it. It might just work.

But it didn’t stop there. I then wanted to decrypt into a byte array some bytes I had previously encrypted. Since I knew the number of original bytes (~5K), I made sure to use a byte array large enough to read them back. The code is roughly as follows:

File desFile;
FileInputStream fileInputStream;
CipherInputStream cipherInputStream;
byte [] bytesRead = new byte[10000];
int numberOfBytesRead;

desFile = new File(fileName);
Cipher desCipher = Cipher.getInstance(DES);
desCipher.init(Cipher.DECRYPT_MODE, generateSecretKey());

fileInputStream = new FileInputStream(desFile);
cipherInputStream = new CipherInputStream(fileInputStream, desCipher);
cipherInputStream.read(bytesRead, 0, 10000);

As usual, the code did not work. The problem was that I was thinking about what happened when I originally wrote the bytes out to the file. I managed to write everything out using one write statement. I just thought I could read everything using one read statement. However, my read only gave me 508 bytes. Where was the rest? I know the file was about 5K. It was there in the file, I just needed to keep reading. Don’t let what you think might happen get in the way of what actually happens.

I am happy to report that most code and APIs do work. It’s just up to you to figure out how. Maybe we shouldn’t have to, but it’s a fact of life. If you want to program, you will have to use your own intuition a lot of the time. Every good programmer I know has this ability. I guess that’s one of the things that makes the job interesting.

About the Author

Dwight Deugo is a professor of computer science at Carleton University in Ottawa, Ontario. Dwight has been an editor for SIGS and 101communications publications, and serves as chair of the Java Programming track at the SIGS Conference for Java Development. He can be reached via e-mail at [email protected].