Admit it. You're dying to know. How did the cross-country move, with four cats on a packed American Airlines Luxury Liner (if ever there was a misnomer, that's it) go, you're wondering? The short version of the story is that we all survived. The longer version of the story is, well, longer. In case you ever get the urge to take on a similar challenge, I'll provide some insight into long-distance moves with small pets. (For background, please see last issue's column.)
If you'll remember from the previous episode, because of airline regulations, the allowed limit is one pet carrier per adult, so we had to enlist two friends to carry two of the four cats. We couldn't honestly ask our friends to fly in coach if we were going to upgrade to first class, and we certainly didn't want to fly in coach, and you can only carry two animals in first class, so the fair thing to do seemed to be to upgrade our friends to first class, and park our rears, along with the appropriately sized under-seat cat boxes, in steerage. Therefore, two adults and two specially selected cats got first class tickets. The rest of us were relegated to coach.
Before reaching security, we had the confrontation with the snippy ticket agent. Although we had purchased tickets for all the adults in the party, we still had to check in the cats. You really have to imagine the scene at the American Airlines ticket counter: Four adults, all their bags, plus four wailing cats in identical carriers. People scrambled to find some other place to be, attempting to avoid whatever crisis we were due to cause. Some airlines don't transport pets. Some only transport them in the pressurized, heated (How much pressure? How much heat? How would your cold, struggling-for-breath kitty tell you that she'd been tortured for three hours?) baggage compartment. Others, like AA, allow them in the passenger compartment for a hefty fee. My one-way ticket (and if that isn't sad, what is?) was only $99. Each cat cost $80 to transport (not to mention the required $35-per-cat veterinarian-supplied health certificate, without which your pet is staying behind, and $50 per cat airline-approved carrier). Three hundred and twenty dollars later, we just had to ask: "Why does it cost so much to replace one carry on bag with one cat?" The response from the snippy agent: "American Airlines is in the business of transporting humans and their baggage. We handle pets as a special favor to our flyers. We don't have to do this." Translated: "Because we can."
As a side note, unless you like inflicting bronchial pain upon your friends, it's probably best that you find a pet transporter that isn't highly allergic to the transportee. My poor pal Doug has always suffered from watery eyes, sneezing, and other pains when he has come to visit, for the fourteen years we've known him. His significant other, Diane (the artiste who transformed our clutter into a designer showplace such that someone might buy it) loves cats and would have several if she could. They volunteered for mule duty out of friendship, but we knew it might be a sneezy trip. The only real problem occurred at the security gate. Apparently, you can't just put a live animal in a box through the x-ray machine. To be honest, we had deduced this before arriving at the gate, and we had figured that we'd have to carry the cats through manually. We also deduced, however, that one of us for whom the fur wasn't toxic could go back through the portal and rescan with the fourth cat, so that Doug could avoid touching the poisonous creature. No such luck?the rule is one carrier per adult; one animal through x-ray with same ticketed adult. Holding Cleo in both hands as far as he could from his body, Doug rushed through security and then ran for the bathroom to wash up. No harm, no foul?but the folks behind us in the line we fuming as we held up the proceedings, dealing with the near crisis.
Drugs are good. Drugs saved us on this trip. (Not for me, silly, for the cats. But I came close to borrowing one of the little green pills provided by the vet.) After getting through security, we shoved half a tab of some wonder drug provided by the local vet down each cat's throat, and within minutes, each was a bit woozy. Soon thereafter, the cats each dozed off. End of story, as far as the cats go. Lights out, no movement, everybody happy in dreamland. If only I had consumed one of the same.
Doug, Diane, Sydney and Cleo (the lucky first-class cats) boarded first, and the rest of us followed, waving as we passed through calm, spacious first class. It's astounding the level of squalor that faces you as you cross that imaginary line between the cabins. Amazingly, the drugged Homer and Melony fit perfectly under the seat in front of me (although it seemed placing the carrier in the overhead bin would have made everyone much happier), but where was I to go? Cat carriers don't leave much room for human feet. You've all flown, and can probably imagine much of the remainder of the story. Plane takes off. Seat in front of me immediately leaps into its fully reclined position. Seat back to nose, working becomes impossible. Reading becomes difficult. Systematic and rhythmic kneading of the seat in front with my knees doesn't solve the situation. Cats are oblivious, but I have four hours in coach with a polyester face mask, counting the seconds until we land. All this was uncomfortable enough, but it got worse. Much, much worse.
Several minutes into the flight, the woman across the aisle from me and one row back, the poor soul who had seemed slightly infirm getting on the plane, began to be ill?really, seriously, noisily ill. Attempting to gain some privacy, she hid under a blanket for much of the trip, but the thin material did nothing to mask the unmistakable sound. I won't describe the rest of the senses involved, but let's just say that I can only surmise that this was the longest four hours of her life (not to mention mine and the rest of the people surrounding her). Afterwards, we conjectured that only someone suffering from the effects of long-term chemo-therapy could be this ill, for so long. We now (in retrospect) wish her the best of health, and hope that all is well. At the time, we were thinking otherwise. I can't tell you how much I hated this poor, sick woman during the flight. Now I'm just embarrassed having even had such thoughts. But contemporaneously, I was quietly praying for an ejector seat to magically appear. Me, or her. Didn't matter.
The Timing of it All
If I'd had some sort of time measuring facility, I could have kept track of how long the miserable woman spent attempting to clean house. (You can just feel it, can't you? "Myrna, he's attempting to steer this disgusting story into something vaguely technical again!") Over the years, I've concocted my own classes for measuring elapsed time, usually in order to measure comparative timings of programming tasks. The .NET Framework 2.0 adds a bundle of new classes, and rather than creating your own elapsed time measuring tool, you can use the new System.Diagnostics.Stopwatch class to do your timing work. (Funny, I had always named my similar class Stopwatch, with almost identical methods. I published it as part of VB courseware I wrote for AppDev, years ago. I'm wondering if the Framework team got hold of my courseware and copied the class' shape? Nah, I'm guessing not.)
I've often been interested in determining the relative speed of alternate methods of solving a particular programming problem. My own Stopwatch classes used the Win32 API's GetTickCount (or the more accurate QueryPerformanceCounter) method to do its job. The .NET Framework 2.0's Stopwatch class does similar work, but without my having to write any code. In addition, the System.Diagnostics.Stopwatch class attempts to use a high-performance system timer if possible (that is, on Windows PCs) and automatically uses a less accurate timer if it must (on mobile devices, for example). I love it when a class I find in the Framework does exactly what I need, in an elegant and well-documented fashion. This class fits that description?the documentation is completely clear, and the members of the class provide all the necessary functionality.
The System.Diagnostics.StopWatch class provides a number of simple instance methods, (Start, Stop, and Reset) all accepting no parameters, all doing exactly what you'd expect. The Start method gets the timer going, measuring elapsed time. The Stop method stops measuring elapsed time, but maintains the current count of elapsed time. The Reset method both stops and resets the elapsed time counter back to 0. The class also provides a shared/static StartNew method, which both creates a new instance of the class, and starts it measuring elapsed time. This method returns the new instance, like this:
Dim sw As System.Diagnostics.StopWatch = _ StopWatch.StartNew()
You'll also find a shared/static GetTimeStamp method, which returns the current time stamp, in case you need that information. The class also provides several properties that can return the elapsed time as a TimeSpan (the Elapsed property), or in milliseconds or timer ticks (ElapsedMilliseconds and ElapsedTicks). Finally, you can retrieve the IsRunning property to determine if the StopWatch instance is currently measuring elapsed time.
In addition, the StopWatch class provides two read-only public fields, Frequency and IsHighResolution. Frequency returns the frequency of the timer as the number of ticks per second, indicating the precision and resolution of the timer. The higher this value, the more resolution provided by the timer. On my computer, the value is 3579545, which indicates the number of ticks per second. This number is determined by the hardware and the operating system, and is constant for a given installation. The IsHighResolution field returns True if the elapsed time is measured using a high-resolution performance counter. If this value is False, the class indicates that you're measuring elapsed time using the system timer.
Typically, you'll call the Start method to start measuring elapsed time, and call the Stop method to pause or stop measuring. For example, to perform a simple comparison to verify that using the StringBuilder class for multiple string manipulations is more efficient than using the String class directly, you might write code like the example in Listing 1.
As you can see, StringBuilder provides a far more efficient solution when concatenating a large number of strings together, and the StopWatch class makes it easy to determine the behavior. Had I been able to extract my computer from its hiding place (or even been able to extract myself from my seat), I could have easily created a stopwatch to measure the amount of time the unfortunate traveler spent suffering, but I could only imagine during the ordeal. You won't have to suffer the flight, or suffer creating your own StopWatch?it's easy and built in, using the .NET Framework 2.0.