Wednesday, January 7, 2009

Things you won't believe until you find out for yourself. - Heiko's guide to programming.

Just how hard can it be to write a program that plays a nice sounding chord every few minutes ?
Answer: no worries mate, do it in a day!!!

Real Answer: Well, not that easy. At least not as simple as I first thought. I wanted to make a program that would play the sound of a set of chimes every 15 minutes, like an old Grandfather clock, the program would be called: the TimeChime program.

When I started I expected it would be so simple I could finish the program in a day. That was mid 2007. Many interruptions later, it was finished in March 2008. In my own defence I should say that I don't program for a living, I teach it instead.

I found out that contrary to my optimistic and na├»ve assumptions you can’t just call a sound file and hope it will run and exit nicely. No no no !!! I needed to figure out how to call another program from my TimeChime program and make it do what I wanted it to. That took a lot of time and didn’t always work, the whole show would often just ‘hang’.

That’s when I found out that ‘pipes’ were a lot better than ‘system calls’ and that running the whole process in a second thread gave me a really neat way to kill any processes that didn’t toe the line (“There iz only ONE Way, and zat is my vay”).

Using the good old ‘try – catch’ pair helped a LOT as well. All of those fairly advanced techniques were required just to make a program that played a couple of sound files every 15 minutes. I had no idea it was that complicated when I started.
In the process I learnt a lot, or rather I remembered a lot from my programming days which I had forgotten. I learnt all the old lessons again.

Lesson 1: NO Theory please we've got to get some real work done ! I realized (again) that when you write software for a living you don't read theory, at least I don't. I don't go to lectures run by people like myself teaching about programming.
I don't read manuals and I certainly can't even begin to make sense of those Microsoft data pages on what or how to use a function or API.
Instead what I do first is search for anything and everything that is in any way similar to what I want to do.
Then I copy their code. Yes, I copy ! Now don't get me wrong, its not copying large chunks of code and passing them off as my own, - large chunks of code are called 'libraries' and everyone uses them all the time.

All I need to see is an EXAMPLE - copy it and run it ! Give me a small demo program that uses the functionality I'm looking for and which works, and the rest is history, I'm off and running.
In the TimeChime program all I needed was a small 5 line program that showed me how to create and use a thread, - spare me the theory, just show me. I'll figure out the theory much easier once I SEE the example.
Then I needed a way to call an external file and get the operating system to run it. I didn't have a clue where to look. So the first thing was finding the technical jargon words, then finding examples at actually worked. Voila, done ! Sounds easy but took days and quite a bit of asking around.

And that takes me to the other often neglected key about programming. Programming is a SOCIAL ACTIVITY ! Yes we all know about the image of programmers as antisocial and awkward and all that. Apart from the fact that the image is wrong, programmers are actually a very gregarious bunch.
That's because programming is simply not possible to do in isolation.
How will you get your hands on all those examples ? Unless you are one of the rare geniuses, who CAN actually make sense of data sheets and Microsoft function descriptions, you will have ask other people for help. It's great if you have other programmers who are present in the flesh, that can be a real bonus. For most of us it's a matter of becoming part of those online forums. While I remember, there is an etiquette about using those forums, please remind me to rave about that another time.

Lesson 2: Pessimism can be useful: Of course I should have mentioned earlier on that the very first step in any programming task I do is, to look for what scares the living daylights out of me. I look for the things that really I have no clue about and that make or break the project.
When I wrote the windows AutoTester I knew I had to find a way to call the operating system from my program, make it run another, second program, get the output of that second program and bring it back to MY program. In other words I wanted my program to behave like a computer user who clicks on a program or a file and runs it, gets the output and then takes some actions depending on the output. That's all. Is that asking too much ?

Sure, for the AutoTester there is also a whole lot of database management stuff, and admin work which the program has to do, but that is all just sheer hack work. If can't solve the core issue of running another second program from MY program and reading the output, I might as well not bother starting. No point taking off in a plane if you don't have enough fuel to get to the next landing strip.
So that's why I focus on the really scary bits. After they are taken care of the rest is "carry water and chop wood" as they say. Not to be underestimated, but its the second thing, the first thing is the core task, get that done and then the rest is a matter of hard work only.

How do I find the scary bits ? I go through the steps, break it down until I'm confident I can handle all the parts.
Do I ever miss anything ? Yes, but not too often. There is always an expected problem ready to pounce, after all remember Murphy's laws ! :-) But this method has stood me in good stead.
In June 1997 I was on my way to Tokyo. I knew they wanted me to write a windows GUI program. I had no idea how to do that. Borland Builder 1.0 for drag and drop GUI design had just come out, and I bought a copy at Panthip Plaza in Bangkok on the way. That saved me.

Lesson 3: Debugging - how to make it less painful: I have been through the laborious and frustrating -want-to-throw-computer-through-window phase too many times. So I like to make life simpler for myself. I set up a simple way to turn debugging on and off by using

#define DEBUG 1

By range checking everything and I mean every argument passed to a function both BEFORE its passed to the function and once its IN the function itself.

Any errors are immediately flagged, and printed with filename and line number using
___FILE___ and __LINE___

I even go to the trouble of creating special error logging and display functions that are called the instant anything goes the tiniest bit off the track I want it to follow.
Why ?
Because I'm a control freak ?
No, because I want an easier life.

If I find out the second a parameter goes out of range it's much easier to pin down where it went wrong and why. What usually happens is that something goes wrong, which is not picked up, but affects something else, that is not picked up. By the time the chain of bugs grows and is noticed it's a long way from the place where the trouble started. You don't really want to have IO problems and messy databases before you realize something is wrong.

This is the way to have such an easier life as a programmer.
How much of my code is error checking code ? definitely more than 50%, probably 60 to 75%.

I didn't start like this. I had not read anything about debugging and error logging. These things came out of the school of hard knocks, great frustration and painful silly errors.

Lesson 4: The slow way is faster –o- Less is more - and other clever Zen Koans.
The principle is simple:
Compile and run EVERY time you change anything ! that means anything, even stuff you are SURE won't make any difference. Trust me everything makes a difference. (Everything is part of the whole and even one grain of sand changes the mountain forever - Thank you Grasshopper... for more of that Zen stuff... )

This brings me to the three golden rules of programming:
1) compile and run and test EVERY STEP
2) compile and run and test EVERY STEP
3) compile and run and test EVERY STEP
Yes, you can be lucky and write 10 lines of code and they work ! Just as you can be lucky and win the lottery.
More often than not when I write 10 lines of code I spend an hour or more debugging it. If I had written and compiled it after every line I would have easily picked up the error in line 3 and be done in 20 minutes.

Lesson 5: Ignore all advice and find out for yourself. Whenever I came across articles of advice like this one, I used to ignore them. These things were almost as bad as reading instructions manuals. Everyone knows that reading a manual is like cheating in way and lets face it: we’re all clever and smart enough to write code and figure out things for ourselves.

So yes, ignore all the above, find out for yourself. If you do happen to read up to this point, some of it might have sunk in and made the learning a bit faster. I hope so.

And one last thing: Why did I choose to write the TimeChime program ? Because I really like those Grandfather clocks that chime every quarter hour. I saw a Yahoo widget that did just that but I didn't want to run the Widget engine, and wanted to play different sounds and when they played them.

----------- DOWNLOADS -----------

TimeChime program
A simple program that plays a chord of chimes every few minutes.
Developed: Melbourne 2007, 2008 - using DevC++ and nothing else.
Full version: Download exe here
Full version: Download eee here
Source code included.

Other software milestones/pebbles:
(- note: this is now old software and will look old and dated, but was once state of the art. )

AMI program - Measures the transient conductivity of acupuncture points in the tips of the fingers. From this it makes an inference about the health of the meridian and the organ to which those points belong. -
Developed: Tokyo 1997 at the Tamamitsu Shrine Inokashiara Koen, Tokyo - using Borland C++ Builder and graphics libraries.
Demo version only: download exe here
Demo version only: download eee here

Adaptive Patient Controlled Analgesia Program.
Imagine the worst pain possible, then imagine the most powerful pain killer. Patient Controlled With Analgesia (PCA) patients press a button and an infusion pump injects pain killer directly into their bloodstream. The principle is demonstrated in this demo version.

Developed: Version1: Melbourne 1991 - 1995 in C++, University of Melbourne and The Royal Melbourne Hospital. Not for public release.
Version2: Melbourne 1998 - 1999 Borland C++ Builder and graphics libraries. Mondo Medical PTY, (venture capital company).
Demo version only: download exe here
Demo version only: download eee here
Adaptive PCA was Heiko's PhD research project: For thesis click here.

What’s an ‘eee’ file ?
The download files are givens as zip packaged containing .exe files or .eee files.
At the "paranoid" setting some security software prevents the download of .exe files. If this is a problem simply download the zip package with the file that has the .eee extension, save it to disk, and manually change the extension to .exe then run it in the usual way by double clicking on it. Example : download the Zip package containing Ami.eee then rename it to Ami.exe and run it like a normal .exe file.

Any DLL or other files should be kept in the same folder as the .exe files for the programs to run properly.

Disclaimer: All software was clean, secure and working when created, i.e. no spyware or malware has been intentionally introduced. However in these days of dearth of commonsense and complicated crazy legal scare mongering, no warranties of any kind are given or implied. Use as is, at your own risk.

And spelling out some more commonsense: All software is for demonstration of my programming skills only and is not intended to give any kind of medical advice or recommendations - again one would hope that this should be commonsense for the average man-in-the-street.

© 2003-2005,2006 heiko rudolph

Sometimes the threads on the loom suggest the picture to come. Then we know that our children-to-be Hope for us in the bardo. For them we weave until out arms grow tired.

from: The years of Rice and Salt - by Kim Stanley Robinson

No comments:

Post a Comment