I just love reading the headlines and looking at the cover picture of that "newspaper" every week as I'm buying my groceries. It's like the Mad Magazine of supermarket tabloids. Other headlines this week:
Go on, grab a copy and read it... you know you want to...
The history of the application is that it's about 5 or 6 years old, and there have been at least 6 different internal developers who have worked on this project as a full-time job at one time or another (not to mention any consultants who have played a part). As such, the code and the organization and the logic of the application are just all over the place. It's a monster. It works, but if something goes wrong then I always have to spend a lot of time sorting through all the pieces to try to figure out what broke (and worrying that my fix might break something else).
In other words, it's a building full of broken windows.
Now, just in the interest of self-defense here, ever since I started this job 3 years ago, I've been told that the application was going to undergo a total redesign "real soon". As a result, I didn't worry too much about cleaning up the old code or standardizing everything or re-engineering the processes, because I figured we were a few months away from building a whole new beast anyway. So I went into maintenance mode -- fix the things that need fixing, add features that the users are screaming for, and make sure nothing breaks.
The problem is, we were always a few months away from starting the redesign. We were always waiting on something, and since the old application still worked there was never any real push to get the internal code rewritten. And the broken windows never got repaired.
The thing that really bothers me right now is that I have to hand over this messy application to someone else, and they'll probably hand it over to yet another person at some point, and ultimately it will be a bad reflection on me. Yes, that's very selfish, but it makes me look bad and I don't like it. After all, I'm the one who was responsible for the application (not from the beginning, but for a good amount of time), and I'm the one who should have properly fixed the things that were being held together by duct tape and band-aids. Future developers won't care that we were on hold in some ways for years, waiting to start a redesign that kept getting pushed back; all they're going to see is the application in its current state -- working, but built with Frankenstein-like code.
Of course, I'm probably a much bigger critic of the application than other people are, because I've been staring at it for 3 years and I'm a little bit picky about how I think things should be written and designed. Things that look ugly to me might look fine to other developers. I don't know. In fact, if you take all the different pieces of the application individually, many of them look fairly thought-out and well-written. Taken as a whole, though, there's not much consistency anywhere.
It's almost like having a whole pile of musical instruments, and individually all of the instruments sound good and play well. But then someone comes along with a welding torch and fuses them all together to make one of those one-man-band contraptions that you can strap to your back and play a banjo and a bass drum and a horn and 20 other things at the same time by jumping around and throwing your body in different directions. It's still the same set of instruments, and they're still playable, but taken as a whole they've become a musical monstrosity.
In any case, with two weeks left in the job, there's not much I can do about it now. All I can do is consider it a lesson learned. Applications require constant re-engineering as they grow, and a "temporary" application, if it works, is rarely temporary.
Without going into how good or bad that situation is as a whole, I'll just say that one of my primary concerns in the next two weeks (before I start my new job) is leaving behind as much information as possible for whoever takes over this project in the future. So far, I've been trying to break everything down into two categories:
Obviously I want to focus on documenting the difficult things, and address the easy things if I have time to at the end. The trick is, where do you draw the line between "easy" and "difficult"? Some of the code we use should be fairly easy for an experienced programmer to pick up, but very cryptic for someone with little or no experience. Certainly I should assume that my predecessor will have a good level of programming knowledge, right?
Another problem is that I actually do have a decent amount of documentation, but in some cases I'm the only one who knows where it is or what's in it. Sure, we have a searchable knowledgebase for the project (and I've made more than half the entries in there), but there's plenty of data that's outside the knowledgebase as well.
So, here's the basic outline of my plan. There are obviously other things I could do that would be helpful, but I've only got two weeks. I also got some great suggestions as responses to a post I made to the LDD forums on this subject, and I've incorporated them here:
This seems like kind of a long list for 2 weeks, but frankly a lot of this stuff already exists, it just needs to be organized and consolidated. I think that the organization of the information is as difficult (and important) as anything else. I could produce plenty of information in a few mouse-clicks if someone asks, but it might take someone else an hour to find the same thing -- if they even knew it was there in the first place. Putting all the information in one place and making it searchable certainly helps, but it's not perfect...then again, I suppose nothing is...
But that being said, I am going to talk about a few work-related topics over the next week or so. Nothing about any specific companies, mind you, but maybe some general thoughts and ideas.
What makes this a relevant topic for me is that I'll be starting a new job at a new company in a few weeks, and so my mind is pretty occupied with jobs right now, and I hope that writing it down here will be sort of theraputic. It's strange that I don't feel stressed about the change on a conscious level, because I think it's a good decision and it's good timing and I'm leaving on good terms. But on some unconscious level I can tell that I'm very stressed about the whole thing, because for the past few days (I gave notice on Wednesday) I've been really tired and I haven't been able to focus very well -- not that "I'm outta here, and I'm going to stop working immediately" lack of focus (I'm not that kind of person), but more the "Did I get any coffee yet? I can't remember if I got coffee yet...and where are my keys?" type of thing.
So anyway, that's the intro. If you don't care about this sort of thing (maybe you're independently wealthy and you just hang out on the beach all day reading obscure technical blogs on your sandproof wireless titanium PDA), then I apologize in advance for boring you with this subject over the coming days.
I just read an article in Scientific American called The Infinite Arcade Machine, talking about Aaron Mahler and the MAME Project (Multiple Arcade Machine Emulator), and man is that stuff cool (here's the FAQ). I'm not even a gamer and I got all excited at the prospect of firing up an old Galaga or Donkey Kong game and going to town. I'll have to see if Joust is out there too -- I used to love playing that at the skating rink.
On a related note, Bob Congdon had a good link this past weekend about a story where Electronic Gaming Monthly magazine asked some of the younger generation (ages 9 to 12) to play some "classic" video games and give their opinions about them. Kids today... When I was their age, TV's didn't even have video inputs...
( 6 - 1 )*@Random + 1;
Based on the Domino Designer Help File, I know that's the right way to create a random number between 1 and 6, but then I realized that the numbers I got weren't Integers, and a dice roll of 2.398475 doesn't really make much sense, and I'd almost never get a 6. So I changed the formula to:
@Round(( 6 - 1 )*@Random + 1);
That worked better, but there was something about it that just didn't "feel" right to me. I didn't think that the 1 and the 6 would have a proper distribution, because you'd only get a 1 with the range of numbers from 1 to 1.49999, and you'd only get a 6 with the numbers 5.5 to 6, while the numbers 2, 3, 4, and 5 would have twice that range (like 2 could be anything from 1.5 to 2.49999). I did some calculations, and it turns out that with the method above, 1 and 6 would each have a 10% chance of being chosen, while the other numbers each had a 20% chance.
So I thought about it a little, and realized:
@Integer(( 5.99 )*@Random + 1);
would work much better for me. Using that formula, all the numbers shared a 16 2/3% chance of being chosen, just like they should. If you don't believe me, I included an agent in the latest version of the Games Database for you to test with.
Also in the latest version of the Games Database (version 1.2), I added a dice rolling game called Scatter House Match. It's actually kind of a stupid little game (the short list of rules are right in front of you when you open the form in the database), but it's a decent start if you want to program a real game like Yahtzee.
Well here you go. My latest download offering is: Games for Lotus Notes/Domino. I've actually only got one game in the database right now (Tic-Tac-Toe), but I'm working on a couple of others. For card games, I just downloaded the PySol cardsets, which are nice GPLed images of decks of cards, but I'm still looking through the GPL license to see what I need to do to "legally" include one or more of the cardsets in my database.
In the meantime, maybe this will give you some ideas for games of your own. Single-player (or playing against the server) dice and card games should be pretty easy, based on the techniques I used for the Tic-Tac-Toe example. For your gaming pleasure, I even set up the Tic-Tac-Toe game so you could either play it using the Notes client or as a web page.
Oh, and by the way, if you decide to put this database on one of your servers at work, you might want to rename it. I dunno, maybe "Budget2002.nsf" or something -- just be inconspicuous...
SUNDAY UPDATE: I added a simple dice-rolling example too.
The important concept that's being demonstrated there, however, is copying information from a memory buffer to a String. Occasionally when you make a call to an API function, instead of getting a string or a type or a variable back, you simply get a pointer to a location in memory. In that case, you have to copy from the memory buffer to an appropriate variable before you can access the information.
I like to use an undocumented Notes API function called Cmovmem to do this, because it can be used on multiple platforms (as long as you declare the function properly). It is essentially equivalent to the RtlMoveMemory function in the Windows kernel32.dll file, although the parameter order is a little different.
First, I had this diagram of the basic elements of an NSF file, so I stuck it on the end of the What Is Lotus Notes page in a short section: What Is A Notes Database. Still pretty basic information, but if you ever have to do a quick overview or a presentation, it might be handy.
Second, I remembered a PDF that I read a few years ago called Inside Notes, that had really good technical information about how the various parts and pieces of Notes databases, clients, and servers fit together. It's a really good reference document, and at over 200 pages, it's a lot more detailed than anything I'll ever write.
So, if you feel up to it, grab a big mug of coffee and read my answer to the question of What Is Lotus Notes?
So I just posted another tip: A Trick for Creating API TIMEDATE Structures in LotusScript. If you've never had to deal with TIMEDATE structures in LotusScript, this will make no sense to you at all, but if you have...
So, I went looking for a good multi-tab "shell" to sit on top of IE, because I've just reached the point where I have to browse using multiple tabs these days (it's no longer a preference, it's a necessity). I figured that if I could imagine it, someone has already developed it, so I did a quick search on the Internet.
One thing that's really cool is the multiple home page option, where you can open several home pages in different tabs when the browser starts. This is especially nice for me, because I typically need to access the same set of pages throughout the day, so it's great to have them all open in different tabs right when I launch my browser.
"What a great feature for Firebird to have," I thought. "Maybe I should send in an enhancement request."
But then I did a little digging, and it turns out you can already do this in Firebird. Just separate multiple URLs with a pipe in the Home Page Location(s) option of Tools - Options - General (like http://www.yahoo.com|http://www.nsftools.com). As a shortcut, you can also just open all the pages you want as your home pages in different tabs, and then click the "Use Current Pages" button in Tools - Options - General to set them all as your home pages.
Of course, this kind of thing doesn't make me want to switch from Firebird to Avant Browser, it just makes me appreciate Firebird even more. It's got features I didn't even know I needed, and the features and layout are very unobtrusive (especially next to Avant Browser).