Saturday, June 30, 2007
I received new phone books yesterday. I immediately threw them into the closet that contains four years' worth of phone books that I keep meaning to recycle. I have about ten cubic feet of books. All the books are still in the plastic bags.
Does anyone actually use phone books anymore? I can't remember the last time I looked up a number or address in a book. I suspect it was in the 1990's. I do use phone books as impromptu stepladders, monitor stands, and replacement table legs, but there are better alternatives.
Phone books are just really-heavy junk mail. I'll have to look into whether I can request to no longer receive them. I'll get on that right after I recycle the ones I have.
Wednesday, June 27, 2007
(For programmers only)
I've had to become familiar with yet another "legacy codebase." There is no documentation, other than the code itself, and all the people who worked on developing the code are either gone or are too busy with other projects to give me an overview and tour. So I've been on my own.
In such situations, I usually start by finding the main() function and tracing the paths of execution through the code. If you're lucky, main() has a couple of lines of initialization code, a simple loop, and a few lines of cleanup code. If you're unlucky, main() is 2,000 lines long with eight levels of indentation and lots of variables with names like x, tmp, temp, and temp2.
But I couldn't find the main()! When I searched through the code directories (all 72 of them), I did find a few main() functions, but they were all in source files called test.cpp. "That must just be test code," I thought.
I was mistaken. As it turns out, every single executable's main() resides in a source file called "test.cpp."
Why? Because the first guy who wrote an executable program that linked with all these libraries made a simple test program, quite reasonably named "test.cpp." And then everyone else just copied that guy's files when they needed a new executable.
I understand why somebody might want to copy a working program to create a new program, but I had to ask why nobody bothered to rename each copy to something more descriptive. The answer: "Because then we'd have to change the copied Makefiles, and that's too much work."
Now that I get paid by the hour, I don't let such answers bother me.
Monday, June 18, 2007
Replaced flux capacitor
When I returned to my apartment after work today, I found a service-request form indicating that the maintenance guy had fixed my air-conditioning system by replacing the flux capacitor.
This is curious, because the flux capacitor is the device that makes time travel possible for the DeLorean in the Back to the Future movies. I've searched the Internet, but can't find anything about applications of this technology to real-life A/C systems.
The other curious thing is that I have not requested service on my A/C recently.
I have had problems. The A/C will run for a hour or two and then stop. It would restart if I turn off the system, wait a few seconds (until I hear a "click") and then turn it back on, but then it would stop again an hour or two later. If left to itself, it will stay off indefinitely. This meant that during hot summer months, I would usually awaken at around 3:00 AM every morning sweating, and return from work every day to find my apartment at 95 degrees.
I put in some service requests the first summer after I moved in, but all they did in response was to turn it off and back on, and then say "Look, it works now." I also got a very-helpful lecture on how to use a thermostat, with special emphasis on the differences between the Heat and Cool switch positions.
In their defense, I will admit that the A/C was always working when they left. It only failed when I was trying to get some sleep.
Now, two years later, my flux capacitor has been replaced. I don't know why they suddenly decided to fix it.
The Comments section of the service form indicates that the part replaced is the "XXX Capacitor," where XXX is an unreadable word but looks like it might be "Bon" or "Ron." My best guess is that the guy intended to write "replaced bad capacitor," which makes sense. Unless it was a bad flux capacitor.
By the way, the problem with my A/C persists. Maybe I need the dilithium crystals replaced next.
[UPDATE: I called Tuesday morning to make a request that they fix my now-broken A/C. Tuesday evening, it still wasn't working. So after another warm sweaty night, I went into the office on Wednesday morning in a foul mood and made demands. Wednesday afternoon, they replaced the flux capacitor (again), a relay, the fan motor, the transformer, the A/C filter, and the thermostat. Now, it seems to be working.]
Saturday, June 16, 2007
Super Sugar Crisp
I believe that America lost something when Post changed the name of "Super Sugar Crisp" to "Golden Honey Crisp" or whatever they call it now, and when "Sugar Bear" became "Golden Bear."
Here's one of the old boxes:
I remember this box. I got the Frankenstein glow-in-the-dark monster.
Thursday, June 14, 2007
Londo and G'Kar
I've been watching all the old Babylon 5 episodes via Netflix. When the series was originally airing, I stopped watching some time during the third season.
I didn't care much for the Delenn-and-Sheridan romance. The Vorlon-vs.-Shadows subplot got old. I didn't like Garibaldi's and Franklin's problems. These all annoyed me.
But, every time Londo Molari (Centauri) or G'Kar (Narn) were on screen, it was wonderful.
J. Michael Straczynski was a genius. The story started with G'Kar being the "bad guy" and Londo being a buffoon. But as the story progressed, G'Kar became more of a stately and sympathetic character, while Londo became a tragic figure. It really was brilliant. I don't know how much credit goes to the writer, and how much goes to the actors, but the developments were extraordinary for television.
"Wonderful" is the only term I can use to describe the Londo-and-G'Kar story. Babylon 5 had a lot of problems, but this is something that was done right.
Wednesday, June 13, 2007
Stick Figures in Peril
I saw this on Jim N Texas's blog. It's a collection of pictures of signs illustrating all the dangers of modern life. It's good for many laughs.
I've wondered why there aren't any "Beware of Spinning Propellers" signs at the airport with illustrations of stick figures being ground up into little square bits of meat.
Peachtree Race Number
Received my race number for the Peachtree Road Race today.
Tuesday, June 12, 2007
Adobe Camera Raw with Photoshop Elements 4.0 for Mac
For anyone with a Nikon D80 who uses Photoshop Elements 4.0 for the Mac, here are some tips if you have problems opening NEF files (Nikon's RAW format):
- The version of that plug-in that comes with Photoshop Elements is old, and does not support the D80 raw format. The automatic software update feature of Photoshop Elements doesn't update the Adobe Camera Raw plug-in.
- The D80 raw file format is supported by version 3.6 or later of the Adobe Camera Raw plug-in. As of 2007/6/12, the most current version of the ACR plug-in is 3.7. (There is an ACR 4.1 version available, but it only works with Photoshop CS3, not with Elements 4.0.) You can download it from Adobe support. Copy the file to the directory /Library/Application Support/Adobe/Plug-ins/CS2/File Formats
- If, when opening a NEF file, you get a simple dialog that only allows changing of white balance and exposure compensation instead of the Camera Raw dialog pictured in Adobe's documentation, it may be because you installed PicturePerfect or some other Nikon software that installs its own plug-in which disables Adobe's Camera Raw plug-in. Check the second section of Three Common Problems with Adobe Camera Raw . . . for a solution. (Basically, if ou have a "Nikon NEF Plugin," you need to move, rename, or delete it.)
[UPDATE 2007/6/18: The upgrade to Elements 4.01 for the Mac is now available, and Camera Raw 4.1 works with that.]
Sunday, June 10, 2007
I took a recreational kayaking class. "Recreational" is the term they use for people who aren't doing anything competitive (racing) and who aren't doing anything crazy (whitewater). The purpose of the class was to learn the basic strokes and control of a kayak.
The class went from 8:00 AM to about 4:00 PM, with a break for lunch. There were seven students, and two instructors. We met at the "put-in" point on the Chattahoochee River. The first couple of hours were spent on land. We first unloaded all the equipment, then waited while a few people dropped off their vehicles at the "take-out" point a few miles downstream. Then the instruction began.
The equipment is pretty simple to understand. First, you've got a kayak, which is a small narrow boat with a small cockpit, a seat, and a couple of pegs to put your feet on. For serious kayaking, you wear a skirt that seals the cockpit from water, but we didn't need that for our class. The kayak has some inflatable airbags in the bow ans stern that will prevent the boat from taking on too much water if it capsizes or goes under a wave. Kayaks range in size from long "sea kayaks" to the very-short whitewater kayaks. Recreational kayaks are between those two extremes.
Next, you've got a two-bladed paddle. The blades are offset at an angle from one another so that when you've got one in the water, the other blade is not flat against the wind. Kayakers must twist their wrists as they go from one side to the other so that the blade in the water is at the right angle. Serious kayak racers have their blades at a 90-degree angle to minimize wind drag, but to avoid wrist injuries, most kayakers use a less extreme angle.
Finally, you've got a "personal floatation device" (PFD), which is a fancy name for a lifejacket. Depending upon the weather and likelihood of getting wet, one might also want a spray jacket, thermal underwear, a wetsuit, or a drysuit, but it was a muggy 90-degree day, and nobody planned to flip their kayak, so we all had minimal clothing.
The instructors covered some safety information. We were told that if we fell out of the kayak, the best thing to do would be to float on our backs with feet pointed downstream and out of the water. Smashing against rocks with one's buttocks may not sound pleasant, but it is preferable to hitting your head/face against them by trying to swim face down. You also don't want your feet to get caught on anything because you could get stuck and then get pushed underwater by the current.
The instructors talked a little about how to control the kayak, but it was surprisingly little information. Instead, they told us to get into the kayaks and do our best to paddle out and meet just past a bridge downstream.
I quickly concluded that there must be something wrong with my kayak, as it would always turn when I wanted to go straight, and go straight when I wanted to turn. The other students' kayaks were similarly defective. But we all managed to reach the designated point, and then the instructors taught us the basic strokes.
This took a couple of hours, and by the end we were all in fairly good control. We stopped at a park and took a break for lunch, then got back in the kayaks.
The afternoon was spent in some small rapids. These are known as "Class 1" rapids. The classification system goes up to 6, but anything over 3 is for experts.
The instructors covered some features of rapids before we got into them. One feature is rocks. Obviously, one does not want to hit rocks, but a good feature of a rock is that behind each rock is an area of calm water known as an "eddy." Eddies are good places to rest or to wait for the rest of your party. The only problem with eddies is that at the boundary between the eddy and the fast-moving current, the current pushes one away from the eddy, so it takes some finesse and strong paddling to get into an eddy and to exit one gracefully.
Another feature of rapids is a "strainer," which is something that lies across the path but which the water does not go around. An example would be a fallen tree. Strainers are bad, because a boater can get trapped, unable to get out due to the strength of the current. Stay away from strainers.
We went through a few rapids, and it was fun. However, I had the distinction of being the guy who fell out of his boat. I got turned sideways while going through some bumpy water and started tilting back and forth. During the safety lecture earlier, the instructor had mentioned that if you fall out of the boat, it's better to fall upstream than downstream, so that the boat stays downstream of you and will hit rocks and such, instead of sandwiching you between itself and a rock. So, when I started getting unstable, I deliberately leaned upstream to avoid falling downstream, and I guess I leaned too far.
I managed to hang on to my paddle, and grabbed the capsized kayak. This was right in the middle of some rapids, so I had little choice but to aim my feet downstream and keep them out of the water, as instructed earlier. My butt did hit a few rocks as I went down the rapids, but the rocks were all smooth and covered with moss, so there was no pain or damage.
When I got clear of the rapids, the instructor was rowing up to me. He tied a line to my kayak and towed it and me toward the shore. I dragged the kayak up on the beach, drained the water out of the kayak, and then put the kayak back on the water and got in.
We went through the rest of the rapids without incident. We weren't making good time; the river is low these days and the current doesn't flow very fast. So, for what seemed like an hour or so, we rowed and rowed and rowed until we got to to the take-out point.
We packed everything up and shuttled back to the put-in point, and that was it.
It was fun, but I was completely exhausted when I got home. I remember getting out of my car when I got home. The next thing I remember is waking up on the couch three hours later. Even after that nap and some dinner, I still felt woozy.
My legs were very sore for a couple of days. One might think that a kayaker doesn't use their legs, and that their arms would get sore, but that's not how it works. If you are paddling correctly, you twist your hips and torso, and so you rely on the strength of your legs to hold you in your seat.
A few days later, I feel fine. I'm thinking about signing up for the whitewater course. I'm sure I'll end up falling out of the boat again, but as they say, if you don't fall out, you aren't trying hard enough.
Friday, June 08, 2007
Python Server Start
Here's another one of those code snippets that I think I might want to find again someday. Nobody else will care.
This is a Python script that opens a port and accepts connections from clients. This is just a starting point for all the little mock servers I write with Python for testing and diagnostics. I'm tired of copying and pasting the little bits of various Python tutorials that I usually do whenever I have to make a new one of these, so here is my new standard starting point.
I can hack this up by changing the data_received() method to deal with requests coming from the client, and can also hack up run() to get the server to send data to the client unsolicited.
[UPDATE: See more advanced version: Python Server Start, Take 2]
#!/usr/bin/python """ Simple server This is a simple Python script that simulates a server. It is intended for use with the unit tests; this is not production code. Currently, it has these features: - Starts listening for connections on port 64123 - Prints all data received from clients """ import sys import os import socket import threading defaultAddr = 'localhost' defaultPort = 64123 class ClientThread(threading.Thread): """ Thread for handling communication with a single client. """ def __init__(self, client, address): threading.Thread.__init__(self) self.client = client self.address = address def run(self): running = 1 while running: data = self.client.recv(1024) if data: self.data_received(data) else: print "Connection", self.address, "closed" self.client.close() running = 0 def data_received(self, data): """ Called by run() when data is received """ print "Data received %s: [%s]" % (self.address, data) def RunServer(): """ Open server socket and accept connections """ s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) print "Bind to %s:%d" % (defaultAddr, defaultPort) s.bind((defaultAddr, defaultPort)) s.listen(5) print "Listening for connections..." while 1: (client, address) = s.accept() print 'Accepted connection from', address ct = ClientThread(client, address) ct.start() # # MAIN # if __name__ == "__main__": RunServer()
Monday, June 04, 2007
One Month to the 10K
I ran a few times a week, and eventually did get to the point where I could run six miles without stopping. Unfortunately, the running took a toll on my aging body, leaving me with sore joints. Playing racquetball didn't help either. So, for the past few weeks, instead of running I've been riding the stationary cycles and elliptical machines at the gym. I've been doing this five times per week, an hour at a time, so I hope I've maintained my endurance. The low-impact nature of the machines has allowed my joints to heal enough that they don't hurt any more.
I've lost almost twenty pounds along the way. I hate shopping for clothing, but the need to buy a few smaller pairs of pants was a welcome chore.
Anyway, now I've got about four weeks to prepare for the actual event. My plan is to intensify the gym workout for a couple of weeks, and then ease into some actual running the two weeks prior to the race.
There's an evil voice in my head that keeps telling me that I've already demonstrated that I can run the distance, so I should just call the goal "complete" and stay in bed on the Fourth. I'm trying not to listen to that voice.
Sunday, June 03, 2007
With enough photoshop-fu, any idiot can look cool.
If you want to see a lot of other idiots mugging for the camera, check out Flickr photos tagged with "bluesteel"
If you don't know what "Blue Steel" is, you need to rent the movie Zoolander
Saturday, June 02, 2007
I'm not blogging much, because I'm spending all my free time with my camera. I've reached the point that I understand all the camera's features and settings. I am now concentrating on consistently getting good exposures (not too dark; not too light) and composing good pictures.
One challenge I've undertaken is to take one "good" picture per day for a year. By "good," I mean it's a picture that I spent some time thinking about and trying to perfect.
I got this idea from the Project 365 page on the Photojojo site. I'm not really following the spirit of the project as described on that page, as I am focusing on learning to take good pictures, rather than trying to document a year of my life. But who knows, maybe I will be able to look back on the pictures and remember what I did each day.
My set of pictures can be found here: Project 365. As of now, there are 26 pictures. I don't know whether I'll have 339 more ideas for pictures to take, but I'm going to try.