Say you were a young college student taking a programming class, and your aging computer science professor’s first assignment was for each student to write a program to print out their name and telephone number.

Struble's Assembler Language Programming

That wouldn’t be the least bit sus, now would it?

Apparently, back in 1984 it wasn’t! Lemme tell you a story…

I was recently bedridden with both a back injury and my first case of Covid. And having already purged many of my old books, I really had to stretch (metaphorically, of course) to find something to entertain myself with.

One book that followed me through my migrations – from Maine to (five different locations in) Massachusetts, then Pittsburgh, and finally Texas – was a college textbook that was highly cherished by most of the CS majors I knew back then: George Struble’s “Assembler Language Programming for the IBM System/370 Family”.

Yes, I was so bored that I started re-reading a 40 year old textbook on one of the driest topics in all of computer science, for a computer that no longer exists!

Chapter 1 is a snoozer (not unlike the rest of the book). It’s all about how mainframe computers used combinations of ones and zeroes to encode numbers and characters. Like any textbook, the end of Chapter 1 had a dozen exercises for the student to solve, to promote active learning and demonstrate a practical understanding of what’s been taught.

Here’s the text of Problem 1.3: (emphasis mine)

Each byte of storage in the IBM System/370 contains eight bits of information and one parity bit. The parity bit is redundant; it is used only to guarantee that information bits are not lost. The parity bit is set to 1 or 0 so as to make the sum of 1’s represented in the nine bits an odd number. For example, the character / is represented in eight bits (in EBCDIC) by 01100001. The parity bit to go with this character will be 0, because there are three 1’s among the information-carrying bits. The character Q is represented by 11011000, and the parity bit is set to 1, so there will be five 1-bits among the nine. These representations with parity bit (we call this “odd parity”) are also used in magnetic tape and disk storage associated with the IBM System/370. Using the character representation table of Appendix A, code your name and telephone number in eight-bit EBCDIC representations, and add the correct parity bit to each character.

That’s right: on just the third exercise in the entire book, Struble is asking the student to provide their personal contact info, presumably to their instructor. I can only imagine the repercussions if a professor presented this exercise to his or her class today.

To be fair, when Struble’s book came out (in 1969, then revised in 1974 and again in 1984) such an assignment simply wouldn’t have set off the red flags it does today. The author and his editors probably felt safe in the assumption that women wouldn’t be taking hard-core mainframe assembler classes. And for the odd exception, what harm could possibly come from a young coed revealing her phone number to an upstanding member of the academic community?

What harm, indeed.

I’m not one to condemn past generations for not living up to more modern social norms, but still… Today that exercise just screams of inappropriateness and invasion of privacy. For me, reading that was a head-scratching moment of astonishment from an unexpected source, a true blast from my past.

Say an alien civilization conquered Earth and forced us to use their measurements, outlawing familiar units like the mile, degree, pound, and gallon. Imagine how disruptive that would be!

Akshually, not very disruptive at all, based on my experience. This year I decided it was finally time to drop those long-outdated “imperial” units and resolved to go full-time 100% metric only.

Fun and exciting approaches to study the metric system

Why? Well, as an international sport, cycling and bicycles are primarily metric in nature. In any field where measurements matter, metric is used… even in the United States. By law, metric became the preferred measurement system in the U.S. back in 1975, and we’ve had sixty years to get used to the idea of using modern, standardized, universally-recognized units. Our quaint idiosyncratic measurements have become less and less defensible with each passing year. This is just my way of saying “Really, don’t you retrogrades think it’s about time?”

I am reminded of a bike ride I did up Gun Hill in Barbados back in June of 2000, when I was a novice first getting back into riding a bicycle. When I rode that hill under the hot tropical midday sun, it seemed way steeper and harder than the 210-foot ascent that my map indicated. Then I realized that Michelin travel map wasn’t demarcated in feet, but in meters. At 700 feet the hill was actually more than three times steeper than I had bargained for! And whose fault was that? It certainly wasn’t Michelin’s… And my legs have never let me forget that lesson.

It could be worse, tho. Back in 1999, a $125 million Mars Climate Orbiter crashed during its insertion burn because no one thought to convert numbers from Lockheed Martin’s imperial units into JPL’s metric ones. Awkward!

Compared to those experiences, adapting to metric units hasn’t taken much adjustment at all.

What did I need to change? Well, let’s look at things like a cyclist. What matters to a cyclist? Distances, speed, inclines, air temperature, tire pressures, and the weight of his equipment and body.

Distance isn’t that hard. A meter is just a slightly longer yard, and a kilometer is a somewhat shorter mile. And many rides are already demarcated in kilometers: a metric century (100 km = 62 miles), a 200k (124 miles), and so on. And like most men I stand a little shy of 2 meters in height.

Speed is simply distance divided by time (whose units haven’t changed), so you wind up with km/h as a rough analogue for mph. A familiar 15 mph average speed would equate to about 24 km/h; and a 10 mph headwind would be 16 km/h.

Similarly, inclines are just vertical distance divided by horizontal distance. So if you’re used to thinking in terms of feet per mile, you need to divide by 5¼ to recalibrate to meters per kilometer. And unlike feet per mile, you can simply divide m/km by 100 to get percent slope! That’s handy!

Air temperature really isn’t hard, either. I break it down into ten-degree chunks. Obviously, 0C equals 32F. From there, 10C = 50F, 20C = 68F, and 30C = 86F. There’s nothing complex about that.

Like the other metric units, weight is another one where routine use creates familiarity. My weight usually runs in the 76 to 78 kg range.

And air pressure, too. I run my bike tires at 550 kPa, and the car’s at 220 kPa. Those you would just have to remember, if you could find any device that actually reports in kPa instead of PSI (pounds per square inch).

For me, adapting my thinking has actually been the easiest part of the process. I spent more effort updating the hardware and software I use. That was like a more pervasive and annoying (but thankfully one-time) version of the annual daylight savings clock reset dance.

Computer changed? Check. Cell phone OS? Check. Home voice assistants? Yeah, okay. Smart bathroom scale? Yup. Bike computer? Yup. All the kitchen measuring cups and spoons? Well…

There were, of course, a couple outliers. There doesn’t seem to be any way to switch our (reasonably new) kitchen oven away from °F, nor our digital medical thermometer.

And websites, too. Biking sites like Garmin Connect, Strava, and Elevate? Yup. U.S. National Weather Service? Perhaps surprisingly, you can only change to international units on a couple of their pages, not all of them…

And then I had to make some updates to various software that I’ve written myself. My cycling database and spreadsheet and charts needed a few tweaks. I had to change the weather menubar widget I wrote to report out in metric. And the same for the program that appends weather and ascent data onto my Strava bike ride logs. And so forth.

Rather than me, the biggest inconvenience has been to Inna, who now has to explicitly ask our home voice assistant for temperatures in Fahrenheit (aka “little degrees”).

But for me, aside from a couple hours switching devices and program outputs, switching to metric was pretty effortless. So effortless that it makes the past sixty years of vociferous American hand-wringing seem stubbornly wrong-headed.

After all, 28.35 grams of prevention is worth 0.45 kilograms of cure…

Being a programmer and obsessive about data is not always an ideal combination.

Most people make a habit of knowing their age. After all, it’s a basic vital statistic, and a useful piece of information to have on hand.

Of course, no one actually pays attention how old they are. After all, when you tell us you’re so-many years old, that’s only a vague approximation, with a typical variance of hundreds of days.

That is, unless you’re data-obsessed, and have the engineering skills to write a program to calculate your age to a higher degree of precision.

That’s where this story comes back to me. Over the years, I’ve written programs in several languages that tell me exactly how old I am. But since dates are messy, I don’t go too crazy about precision; two decimal places—a hundredth of a year is a three-day window—is close enough for me.

Kedit logo

One of the oldest such programs runs as part of a Rexx macro when I open up Kedit, a favorite old text editor (and coincidentally the one I author my blogposts in). It calculates the difference between the current date and my date of birth, which is hardcoded in the program in Rexx’s standard “USA” format: MM/DD/YY.

All that worked great until a little while ago, when it started barfing up crap data. I didn’t pay much attention to the error until recently, when I was cleaning out a bunch of old code. And when I figured out what the problem was… it really pissed me off!

The relevant section of the manual spells it out rather bluntly:

When DATECONV() is used to convert a date that is specified using a 2-digit year, it assumes that the date falls within a 100 year sliding window starting at (current year - 50) and ending at (current year + 49).

For example, in 2007, DATECONV would convert 2-digit years to 4-digit years in the range 1957-2056. But in 2008, the sliding window would move by a year to cover 1958-2057.

Fast-forward to 2014, when Rexx decided that the “63” of my birth year no longer referred to 1963, but to 2063. In other words, shortly after I turned fifty, my birthday no longer fell within Rexx’s 50-year sliding window for converting two-digit years. It surprised me to realize that today we are actually closer to 2063 than we are to 1963!

So thanks Kedit/Rexx for breaking my age calculations. And thank you even more for letting me know that I’m too damned old for you to consider my birth year the most likely expansion of the two-digit abbreviation “63”.

Who is the best foosball player in the company? This question has followed me through three of my last four employers, ever since I spun my first rod back in 2005.

I’m happy to say that I’ve been able to provide my coworkers with an answer to that eternal question, through FRank, the foosball ranking site I first developed nearly ten years ago. If you’re interested in ancient history and FRank’s inception, you can read more about it in this blogpost from 2007.

A year after I wrote that post I left Optaros, and my foosball ranking site languished, nearly forgotten. After wasting a couple years at a sad little company that didn’t even have a foosball table, last December I found myself interviewing at Buildium, whose kitchen included not one but *two* tables! During the interview process, I made sure they knew that hiring me meant access to my foosball ranking site, too!

Naturally, after years of neglect, I wanted to clean things up a bit (and size up the foosball culture) before I opened the app up for public use. So over the past few weeks I put a few hours into a bit of a refresh. And I’m pretty happy with the result.

Here are some of my favorite new features:

Foosball table

First, I rewrote everything using Google’s Angular javascript framework. For non-techies that probably doesn’t mean much, but it’s cool new technology that I really need to learn anyways. And it allows me to easily do some cool things like providing predictions of the score of any given combination of players.

I also made it a single-page app, which means everything happens on one page, kinda like Google Docs, without any page refreshes because all that data comes from behind-the-scenes API calls. It feels more like a native application and less like a website.

Next, I redesigned it to have a mobile-friendly user interface, so that it would be simple and easy to use, whether you were on a desktop, laptop, tablet, or smartphone. It even has its own little icon so that its bookmark looks just like any other app on your phone.

I even added the Web Speech API, which allows anyone using Google Chrome to enter a set of players by saying aloud something like “Jordan and Matt versus Dave Owens and Ben”, rather than having to manually navigate four cumbersome drop-down lists.

In the first two weeks of public availability, the adoption rate among players here has been great. This week I added a user-suggested feature: when someone logs a game, a message is automatically broadcast in our company’s foosball chat room (from “FRank Foosbot”), summarizing the result for all to see.

Needless to say, I’m pretty happy with how I was able to bring it up to date with how the web has evolved. It’s been a fun coding exercise, while contributing something unique to the company culture.

The biggest irony, however, was when Buildium hired my old friend Dave. I worked with him at both Sapient as well as Business Innovation, where he wrote (and then lost the source code for) his original Microsoft .Net foosball application that inspired me to create FRank. And years later, we’re working together again, and I get to show him what his old foosball ranking system has evolved into.

With the perspective that comes from thirty years in tech, I’ve gained quite an appreciation for the basic absurdity of developing software.

A quick look in the rear-view tells a revealing story.

Of the volumes of software I’ve written, perhaps a quarter of it was never even used. And nearly all of the code that did make it into production was gone and deleted within five years of its creation. Heck, half of the companies I worked for disappeared within eight years! And nearly every programming environment I ever learned was obsolete within ten.

While everyone talks about how rapidly technology evolves, it’s rare that anyone thinks through the implications. The software that I was quite well paid to craft has been astonishingly ephemeral, and the development tools that I’ve used have had a useful lifetime somewhat shorter than my last pair of socks.

Needless to say, this isn’t just my problem; everyone in our industry faces the same underlying challenge. Nothing lasts forever, but in tech, everything we learn, use, or create should come with a “use-by” date of fewer than 60 months.

When you were young, you probably got the impression that your career would be a linear journey from Point A (your first job) to Point B (a comfortable retirement).

In the tech field, it’s more like trying to steer a sailboat at sea. You can point yourself toward a destination, but the water’s hidden currents and tides will pull you in different directions. The wind, waves, and other people’s passage will also push you off course. Never mind that every employer and project asks you to use their own boat with completely different rigging! And sometimes, either by choice or necessity, your destination changes mid-stream. About the time you reach the middle your career, you realize that your industry and career trajectory are far more fluid than you foresaw when you first set out.

While all this change and dynamism makes it hard to make progress in any one direction for long, if you develop the insight and skills to respond to these changes wisely, you can still get to a happy destination, even if it might look nothing like what you imagined when you got your first offer letter.

What follows are a list of observations I’ve made over the course of my shifting career: some often-overlooked implications of trying to navigate my way through such a turbulent industry. I hope they are of value to you on your own journey.

First, let’s look at the implications the ephemeral nature of software has on companies as a whole.

As soon as a development team delivers a software system, companies and product managers need to immediately start planning for its replacement. These days, you have two options: either factor a perpetual enhancement and revision process into your product strategy, or plan to simply throw away and reinvent your system at great cost a little further down the road. The traditional concept of implementing a system once and then scaling back for a lengthy “maintenance phase” died about the same time as pay phones and busy signals. It’s a nice old-fashioned idea that will lead you directly toward your Chapter 7 filing.

Whether you are a product manager or a development lead, you must accept and somehow communicate to your development team that time to market is infinitely more important than the elegance or academic correctness of their code. Bug-free code does not exist, and companies are much more rigorous about following the old 80/20 rule. If you’re truly following the Agile model (rather than pretending, as so many companies do), your top priority is to ship the beta: get an initial offering with a minimal feature set out into the market, and then react rapidly to customer feedback. These days, software that is “good enough” is almost always good enough.

When I first became an engineer, my older brother offered me one of the most valuable insights of my entire career: never hire technical staff for the knowledge they already have; instead, evaluate candidates primarily on their ability to learn new skills quickly and effectively. Five years down the road, the knowledge they walked in the door with will have no value; their usefulness as employees will be determined by how easily and quickly they can become productive with new languages and tools. Furthermore, the optimal way to retain the best technical talent is to support their desire to keep up with current and emerging technologies.

Now let’s talk about a few things that apply both to individuals as well as companies.

Whether you’re an individual managing your to-do list or a product manager specifying features and enhancements, you’re always going to have more tasks than time and resources to complete them. Therefore, always work on the highest value item. Constantly ask yourself whether you and your team are working on the most strategically valuable task. Always attach yourself to the tasks that truly have the most impact, and don’t waste your time on anything else.

Risk is uncomfortable. Risk is a threat to one’s company and one’s career. And yet risk is an inherent part of every single thing we do. While moving cautiously forward might seem like the most comfortable and risk-free approach, it really only defers that pain, because there is a huge hidden risk associated with not moving forward assertively enough. Both corporations and individuals must learn how to embrace risk, tolerate its associated discomfort, and recover from failures.

Software engineers and managers often have a grand dream of software reuse: the idea that if you’re building a program to handle Task A, you should invest some extra time into making it generic enough to handle anticipated future Tasks B and C. In the real world, B and C might never be needed, and their requirements are likely to change between now and then anyways. While it goes against our sensibilities, it is often quicker and easier to just duplicate and customize old code to handle new tasks. If the additional cost of maintaining multiple versions becomes sufficient, only then should you invest the resources to refactor it into a single generalized solution. That might sound like blasphemy, but in thirty years I’ve rarely seen a compelling example where software reuse saved money in the long run.

Finally, let’s talk about how we as individual employees should respond to the fact that our work has such a surprisingly short lifetime.

On a purely tactical level, as soon as you finish a project, save some screenshots and code samples for your portfolio. Six months later, those sites you built will have changed significantly, if they survive at all.

While everyone wants to be the best at what they do, building deep expertise in any tool or language no longer makes sense, because most languages are supplanted in a few short years. Rather than becoming an expert at one thing, a better strategy is to become the long-derided jack of all trades: someone who has a wide breadth of knowledge, an understanding of the general principles that apply to all environments, and the ability to adapt to changing business needs and a changing job market. Cultivate your passion for perpetually learning new tools, and your ability to be comfortable doing so under stress and time pressure.

In terms of getting your resume noticed, what you have done is not always as significant as who you worked for. Sites and projects are ephemeral, but major companies last longer and will catch the reader’s eye. Working with companies that are household names will—for the rest of your life—help you get that first phone screen.

My advice to all individuals is to focus on saving cash when you’re working, so that you can comfortably weather the inevitable downturns in the business cycle. Every time I’ve been laid off, I’ve been able to take a year or two off to decompress, have some fun, wait for the next upturn in hiring, and then be selective in my hunt for a new position. Layoffs and buy-outs weren’t personal emergencies because I had the cash on hand to weather any situation that arose. But if you take time off, devote some time to keeping your skills up to date and learning marketable new technologies.

Unlike the coding I’ve done, the one element of my career that has proven surprisingly durable over the long-term has been the relationships I’ve built with my coworkers. Despite everyone moving from project to project and job to job and often city to city, people remember you forever, and a robust contact list is immensely helpful in finding great places to work (and knowing which ones to avoid). It might sound crazy, but this has been one of the most important elements of my career success: put just as much effort into developing good relationships with your coworkers as you put into the software you write. Software doesn’t last, but people do.

Finally, one closing bit of advice about the long-term. If you want to be happy when you look back on your career, you must work for companies and projects that improve people’s lives, rather than just making a buck. Being a successful spammer or marketer might pay the bills, but money isn’t fulfillment. No matter how elegant, satisfaction will not come from the short-lived systems you build; real, lasting fulfillment comes from the impact your work had on real people’s lives. Life is too short to waste your time working on shit that doesn’t have any meaningful value, so make sure you’re contributing to a business you can really believe in.

And, of course, don’t be surprised or dismayed when the systems you worked so hard to build disappear overnight. It’s one of the facts of life as a software developer…

And now, just to be a complete contrarian, I present some frontend-tech-oriented “your mama” jokes. We assure you that no mamas were hurt while composing this entry.

HTML-oriented:

  • Your mama’s got a really big <body>.
  • Your mama’s got no <head>!
  • Your mama’s just an <object>.
  • Your mama’s a <sub>.
  • Your mama’s got no parent element.
  • Your mama’s value attribute is set to zero.

CSS-oriented:

  • Your mama’s got no style.
  • Your mama’s got no class!
  • Your mama’s width is 110%!
  • Your mama exceeds her max-width!
  • Your mama’s got too much bottom-padding...
  • Your mama’s got her overflow: visible.
  • Your mama’s so easy she’s got a negative z-index!

Other tech-oriented:

  • Your mama’s got such a regular expression.
  • Your mama’s got an out of date plugin.
  • Your mama’s a vector shape, and she looks like somebody’s been draggin’ her handles…

And yes, your mama floats right, too!

There really needs to be a corollary to Newton’s Second Law of Thermodynamics, stating that website maintenance is a constant (and un-winnable) battle against the Stupid introduced by other people.

Usually this involves a lot of quiet fuming while cleaning up the garbage left behind by the incompetent agents of entropy. But sometimes the Stupid is just so ludicrously headdeskingly perfect that there’s nothing you can do but laugh until you gag on your own puke. All the while, marveling at the “mysteries of the universe”.

For example, consider the following. While working on something, I once came across the following block of code on a production website:

$rss_feeds = "";
echo $rss_feeds;

Now, even if you’re code-illiterate, you can probably figure out what this does. It sets a variable to nothing and then prints… nothing.

Why? No reason. The only thing I can figure is that someone hired a contractor and paid them based on the sheer number of lines of code they produced.

Now, before I lose all the non-coders in the audience, here are a couple examples where people chose to demonstrate their mastery of their native language. For example, take this headline that appeared in a second-level heading on one page:

Private vs. Gevernment

Or this major announcement:

Without further adieu [...]

Or this favorite job listing of mine:

[...] is currently seeking a Senior FrontEnd Web Developer with 710 years of professional experience

Working our way into the code doesn’t have to be painful, though. How about this one: Need to name a file? Why not name it after your own awesome self?

$fileExt = 'markrules';

Another one that is easy for non-coders is this one:

<div id="left_content" class="right">

Yup. In the Stupid Universe, left is right and right is left.

Now how much would you pay? But wait: there’s more!

<?php //    include('ad_med_rectangle.inc.php'); ?>
<?php include('ad_med_rectangle.inc.php'); ?>

In PHP, two slashes are used to comment something out. So here we have a line of code carefully commented out. And then the exact same line, not commented out. Um… huh?

Speaking of comments, try figuring out what this one does:

$form->addElement('hidden', 'xzdf', 'A3104', array('id' => 'xzdf'));

Using names or key values with self-evident meanings is really overrated. The Law of Stupid instructs us to use completely nonsensical names, and make sure you don’t leave any comments in the code that might explain to the people maintaining your code what those random numbers and strings of characters actually mean!

And then there’s this mystery of the universe, a perennial favorite:

$term = ereg_replace("hero", "elongated sandwich", $term);

I can’t tell you why this site has such a strong aversion to heroes, but it’s clear that any time we find the word “hero”, we replace it with our preferred term “elongated sandwich”. No reason; we just do. No hero worship allowed here!

Here’s a fun one!

.blue_button {
    background: none repeat scroll 0 0 #ED8D1E;
}

Blue_button, huh? You might be forgiven if you thought that might actually show a button that was blue. But that background color of #ED8D1E? That’s dark orange. OF COURSE!

For some reason, “switch” statements seem beyond the grasp of many well-compensated “engineering professionals”. I’m not sure why it’s so difficult to do different things depending on whether a variable has a value of 1 or 2 or 3, etc. Is that so hard? Apparently it is. Here’s a nice example:

case 1:
     $url = 'http://www.awebsite.com/';
     break;
case 1:
     $url = 'http://www.awebsite.com/';
     break;
case 1:
     $url = 'http://www.awebsite.com/';
     break;
case 1:
     $url = 'http://www.awebsite.com/';
     break;
case 1:
     $url = 'http://www.awebsite.com/';
     break;

That’s a double dose of Stupid! Here, all the cases do exactly the same thing! But that’s okay, because they all test against the same value, too!

In plain English, it translates thus: if it’s a 1 you do this; but if it’s a 1 you still do this; or if it’s actually a 1 you would also do this; and if 1 you do the same thing too; and so on. That’s seventeen lines of code to do what requires only one. See what I mean about someone being paid per line of code?

Of course, that only works if you want to do something. Truly masterful Stupid code does nothing, like this switch statement:

switch($page[subnav]) {
}

Huh. Only outside of the Stupid Universe is it customary to write code to actually *do something*.

Of course, junior developers often aren’t wise enough yet to disguise the fact that they’re doing nothing. Consider this:

 

Yes, that’s nothing. That’s the whole contents of a file I found called small.css. Small, indeed! Perhaps they thought they weren’t leaving any evidence of their stupidity behind.

Here’s some additional CSS-flavored fun:

<div style="clear: left;"> </div>
<div style="clear: right;"> </div>

More from the Planet of the Confused: why not just do “clear:both”? Oh yeah, it’s because YOU HAVE NO IDEA WHAT YOU’RE DOING!!!

ttable tr td.odd {
     border-left: 0;
     border-right: 1px solid #fff;
}

Did the W3C create a new HTML tag (ttable) and I missed the news?

p.margin-left {margin-left: 15px; padding-right: 15px;}

So let me get this right: a paragraph called “margin-left” actually has equal margin on both sides? But on the left it’s a margin, and on the right it’s padding? That makes perfect sense, especially if you don’t understand basic HTML page layout!

Here’s an exemplary 12 lines of masterful coding:

if (isset($page_close)) {
$page_close .= <<<EOD
</body>
</html>
EOD;
} else {
$page_close = <<<EOD2
</body>
</html>
EOD2;
}
echo $page_close;

That’s just another example of how these guys clearly were getting paid per line of code. No matter what $page_close is set to, what those 12 lines of code really do is this:

</body>
</html>

No need for complex logic or any dynamic behavior. Good thing they inserted an extraneous IF/ELSE block, two “here quotes”, and echoing a variable, because how else would one know they were such masters of PHP syntax?

if (test_it_counter == 0) {
   computeForm(entry.form);
}
computeForm(entry.form);
test_it_counter++;

So the first time through this program, computeForm() get run twice in a row, just for kicks. I’m sure that works just great! I wonder why they didn’t run it twice every time?

<div id="nav" onmouseover="Tip('#nav { <br /> <var>float:</var> left; <br /> <var>width:</var> 788px; <br /> <var>height:</var> 36px; <br /> <var>margin:</var> 0; <br /> <var>padding:</var> 0; <br /> <var>background:</var> #fff url(images/navbg3.gif) no-repeat; <br /> <var>text-align:</var> center; <br /> } <br /><br /><cite>Note the hover action. </cite>')">

I have absolutely no idea what the coder was thinking here. If you hover over a nav, it displays a tooltip with a bunch of CSS code (which actually doesn’t get used and doesn’t appear anywhere in the page) and the message “note the hover action”. Glad that has been running out on the production web site for four or five years

My final example is a solve-it-yourself problem. Are you ready for a developer challenge? How long does it take you to spot the Stupid in this statement?

<?php if ($isForm = false) {

This one’s an all-time classic and a personal favorite. When comparing a variable to a literal, professional software engineers always put the literal first. Do you know why? Well, the above is a perfect illustration why. The reason why will be left as an exercise for the reader.

I’ve posted before about the random insult generator that I wrote back in college. If you don’t remember, you can read the backstory here, here, and here.

After starting with only a couple dozen possible sentence fragments, it now relies on a database of 43,000 data items from 28 different parts of speech.

Having recently gotten bored and installed a perl interpreter on my phone, I decided to see how easy it would be to port Insult to Android. To be honest, it was a piece of cake. I didn’t even have to alter the data files, just make a couple small tweaks to the main program.

The fun part is that the scripting engine provides ridiculously easy access to Android’s text-to-speech synthesizer. So not only can I generate random insults with a single touch, but the phone will also read them aloud!

Isn’t technology marvelous?

Just a quick note to observe the 25th anniversary of both the Space Shuttle Challenger disaster and my professional career.

The Challenger disaster is one of the few news events where I recall exactly where I was. At twenty minutes before noon on January 28 1986, I was at work.

Although I hadn’t finished my undergrad at UMaine, I had just begun working as a software engineer for the university’s parking, police, and fire departments, which were all housed in one old farmhouse on the edge of campus.

My Televideo 925 mainframe terminal was located just outside the police chief’s office, and when the news broke about the shuttle’s disintegration one minute into its flight, the chief called everyone into his office to watch the event on the television that he usually used for videotapes or presentations.

Three months earlier, in October of 1985, I had been fired from a job slinging sandwiches at 7-Eleven because I had actually read the manual on how to operate the cash registers. My buddy Mike Dow was doing database work for the parking department and brought me in to assist, since he and I had already done some volunteer work together on CSNEWS, one of the internet’s earliest information services. But the Public Safety gig was my very first paid programming job.

For that reason, the Challenger disaster is inextricably linked with the beginning of my professional programming career. A career which has now officially spanned twenty-five years.

It’s been quite a ride, but I won’t indulge in reminiscing about all the good and bad times along the way. I’ll simply say that I’ve learned a lot, developed valuable skills, had a lot of satisfying successes, made so many great friends, and had a ton of fun. It’s enough to make an unemployed guy want to go back to work!

But today isn’t about all those things. It’s really more about just taking a minute to say: Wow, twenty-five years!

It’s been nearly 25 years since I first got my hands on SLAM EXEC and started developing my own natural language insult generator. Since then I’ve expanded its vocabulary to 38,000 data items from 26 parts of speech.

Back in the early days, Xmastime wasn’t Xmastime unless it included a randomly-generated sick and twisted version of the Twelve Days of Xmas. You can see two examples from the early 1990s in this old blog post.

This year, to commemorate this very special time of year, I thought I’d create a 2010 vintage. So, without further ado, I present to you… Let’s all sing it together, now:

On the twelfth day of Xmas my true love sent to me:

Twelve laughers LOLing
Eleven cross-dressers strutting
Ten thugs a-sneering
Nine security chiefs conspiring
Eight brides a-kibitzing
Seven carps a-croaking
Six seals a-bleeding
FIVE ACRYLIC SURFBOARDS!
Four crooning mallards
Three Cylon panda bears
Two wicked absorbent donkeys
And a cockroach in a retirement resort.

Of course, my invisible army of insult elves aren’t idle for the other eleven months of the year! They’re always busily generating thousands of random sentences in hopes of producing something akin to Shakespeare’s “Hamlet”.

I used to save the “best” (or perhaps simply “most interesting”) examples for my heirs and posterity in a file called GRAND SLAMS. Back in 2004, I shared four dozen of my personal favorites in this blog post.

This is, of course, leading up to another instance of oversharing. Here, for your approval, is another batch of classic random insults, fresh out of the virtual oven. I hope you enjoy them.

  • You superfluous male son of a feminist!
  • If you don't hula, just harry He-Man.
  • You have the intelligence of burrito filling.
  • Tax Accountant Bear once bit my estate.
  • Screw you!
  • Excuse me while I go see some bum off the street perform live at Allston.
  • You look like a goddess when you act like a goddess.
  • I saw you be cooked by Abba with glamor and chivalrousness.
  • Your beloved smells like a very unusual gorilla.
  • I'm sick of your furry fur!
  • You're so problematic!
  • Go organize a Broadway show with Joe Namath.
  • Why don't you go to Hurricane Slimy and grapple yourself.
  • Don't decorate that reindeer, you art therapist!
  • I bet you'd love to be gobbled by a Playboy Bunny with a handful of breath mints.
  • If you don't move to Britain, you'll be infiltrated by Hilary Clinton.
  • Did the doctor get fixed when you were born?
  • You dress like a multiple amputee.
  • Be seduced by my spaghetti sauce spewing stegosaur.
  • You smell like the Barge Monster.
  • Why don't you just crawl off to Armageddon and loiter.
  • Ring an ambassador!
  • A bumblebee is your size, but a honeybee is more your speed.
  • Do something frugal with a bugle.
  • Go organize the manufacturing of a waffle with Egg Smeller Bear.
  • Go chew Annette Funicello's diseased femininity.
  • Why don't you just go horse around with your wildest sexual fantasies at psychoanalysis!
  • Go sit on my dog cart and pant.
  • Your betrothed with accidental poisoning by detergent or shampoo slept with Sapient Corporation at the sacrifice of the Incredible Frenching Llama from a NyQuil refinery.
  • I want to hoard your knickers.
  • Have you ever seen a panda bear act like a dominatrix?
  • You look like you incinerated Eddie Murphy's exuberant ass.
  • Someone told me that you and Princess Diana were slaughtered by a dust mite while the Stingy Hare Krishna Stud Baby Bird Dogs watched.
  • We all know that you get immunized against excessive eye-blinking regularly.
  • Your mother was a lovebird, and your father smelled of some Life cereal with Raisins!
  • You look savage.
  • I used to know a detestable fool just like you.
  • Did the doctor cringe when you were born?
  • May Carl Sagan tinker with your respirator.
  • Go organize Armageddon with Salman Rushdie.
  • If you wallow in suspense, you'll be restored by a cassette recording of a centerfold.
  • You'd put breakfast cereal in your handbag.
  • Excuse me, but your Congressman's prick is stuck in my tuba.

One part of my life that I haven’t mentioned here is foosball.

My first exposure to foosball was when I started working at BI in 2005. Initially, I viewed foosball (table soccer) as a pretty stupid game, but I did start playing a bit. It was interesting to see the differences in skill level between good players and neophytes, and I decided I’d start cultivating my skills. Despite the rather mundane nature of the game, there are a lot of subtle skills one can develop, and it’s really quite interesting, once one actually gets into it.

Foosball table

When I moved to Optaros, I found they, too had a foosball table, and I started putting real effort into on developing my game. I also took over most of the maintenance of the table.

At the same time, I missed one of the features we had at BI. Our lead architect had begun keeping track of scores and developed a ranking system based on the same system used to rank chess players. It grew into a full-fledged .NET application, and people really took to it. I decided I’d bring “the foosball app” to Optaros.

Unfortunately, when I asked the guys where the source code was, no one could answer me. So I wound up having to study the Elo ranking system and reverse engineer the thing all over again, this time using Perl and MySQL. I called it “Frank”: Foosball Rank. I took the opportunity to tweak the UI a bit, and you can see the result here. Neeto features include charts of each player’s rating over time, and the ability to predict the score of any given matchup, based on the players’ ratings.

The cool thing is that people at work have taken to it pretty well. At first, I was entering all the scores myself, but people have caught on, and now it seems pretty self-sustaining. It made for a fun little project, and the level of competition has definitely gone up since the system went into production back in June. I guess if I was smart I’d put some advertising on that page and generate some revenue from it, but that’s not gonna happen.

But the foos—and the foos app—are definitely interesting additions that I’m enjoying.

Up, date!

Jun. 30th, 2007 06:02 pm

Time for a quick general update. Things have been pretty good of late.

On the work front, I’m not at the client site anymore, which is really nice. Still working for that big lingerie retailer, which is mostly okay. The other day I learned what a tanga is. Sadly, not through a hands-on demonstration.

And I’ve changed roles on the project from business analyst to UI engineer, which is great; I like to balance my work experience between business, creative, and technical roles/tasks.

Got my first performance review last week. It was pretty glowing, which is gratifying, considering I was instrumental in pulling this project out of the hole it had dug itself. The few criticisms I received were mostly about how we as a team could have better handled a couple issues, rather than any individual shortcomings, which was also encouraging.

Being at the home office also means I can go down to the Haymarket to buy produce on Fridays, which has really surprised me. Last week was typical: I got 10 limes, 6 bananas, and a quart of strawbs for $4; the limes alone would have cost me $10 at the grocery store in my neighborhood! The savings at Haymarket is just ludicrulous, and I’ve been eating a whole lot more produce lately as a result.

The other thing I’ve done for work is recreate an improved version of the foosball ranking application that we used to run at my last job. It runs off the Elo ratings system that’s used in ranking chess players, so it has a bit of advanced maths to it, but it also lends a bit more credibility. I’m pretty happy with it, and so far it’s been pretty popular with the boys at work.

A week or two ago I got an email out of the blue from a nonprofit that wants to use one of my photos for a member mailing, and potentially have me do a multi-location photo shoot for their website. Paid! Granted, I’m not gonna charge much at all, both because they’re a nonprofit and I can use it to build up my portfolio. And it’s got me learning about how to price photos and effectively negotiate copyright rights. So that’s very cool, but it doesn’t deserve more press than that until it’s a done deal. It’d be sweet to be able to say I’m a paid photographer, in addition to being a paid writer and award-winning poet!

Bought new luggage, too. I liked my old red wheeled Kenneth Cole duffel, but the fabric had torn, so it needed to be replaced. It only survived the trip to Las Vegas thanks to copious last-minute application of Gorilla Tape. I couldn’t decide between the larger or the smaller Samsonite wheeled duffels, so dang, I bought ’em both, and still paid half of what one Tumi bag would have cost. And they’re a very pretty royal blue, which makes me happy.

Went to the dentist for… uh… the first time since I was laid off by Sapient. I have to go back in a couple weeks for xray results and a real exam, but the hygienist seemed to think things were actually very good. I’d been fearing much worse.

My assistant editor is preparing and sending out the next issue of DargonZine. It’s wonderful that I don’t have to, although he’s taking his time at it for someone who set a goal of getting nine issues out this year. Still, I don’t envy him; it’s not bad when you know the process, but it’d be quite involved for someone not familiar with how it’s done and the dozen or so technologies behind it.

There’s a mess of health and bike stuff to talk about, but it’s all going to go into [livejournal.com profile] ornoth_cycling, where it belongs.

Except for this one comment. By the end of this year’s PMC ride, I’ll have raised around $26-$29k for the Jimmy Fund. Thinking about that, it’s kind of staggering. That’s enough money to buy a pretty decent car, or pay $1200 per month in rent for two years. It just staggers me that my friends have been so incredibly generous. Then you think about the 5,000 other people who ride each year, who have similar fundraising stories, and you get an idea of how massive an impact the PMC has on the Dana-Farber’s ability to advance the state of cancer treatment and prevention.

That’s a great thing to be a part of, and a nice note to end on.

Frequent topics