Lines of Code? We Don’t Need No Stinking Lines of Code

Let’s look at an old application my department started in 2001 and developed sporadically until finally launching it in 2007:

[me@desktop old]$ find . | grep -E '(php|js)$' | xargs wc -l | tail -n 1
53063 total
[me@desktop old]$ find . | grep -E '(html|css)$' | xargs wc -l | tail -n 1
9726 total

Now let’s switch over to the replacement application I started in January, 2009 and launched in May, 2009:

[me@desktop new]$ find . | grep -E '(php|js)$' | xargs wc -l | tail -n 1
5955 total
[me@desktop new]$ find . | grep -E '(html|css)$' | xargs wc -l | tail -n 1
2302 total

For those unfamiliar with find, grep, regular expressions, xargs, or tail, that means the old application took 53,063 lines of PHP and JavaScript to do what I did in 5,955.  The old used 9,726 lines of HTML and CSS; I used only 2,302.

So, basically I had fewer total lines of content in the entire rewritten application than its predecessor had merely of markup and styles.  That’s fantastic!

Of course, some of you are thinking that’s just because I write much longer lines of code, right?  And you naturally want me to compute the average number of characters per line used in each application to compare, right?  And you demand — demand — that it be done with a single command chain in UNIX?  As you wish!

[me@desktop old]$ (find . | grep -E '(html|css|php|js)$' | tee temp | xargs wc -l | tail -n 1 | awk '{print $1}' ; cat temp | xargs wc -c | tail -n 1 | awk '{print $1}') | sed 'N;s/\n/ /' | awk '{print $2 " / " $1 " = " $2 / $1}'
1523405 / 51063 = 29.8338

[me@desktop new]$ (find . | grep -E '(html|css|php|js)$' | tee temp | xargs wc -l | tail -n 1 | awk '{print $1}' ; cat temp | xargs wc -c | tail -n 1 | awk '{print $1}') | sed 'N;s/\n/ /' | awk '{print $2 " / " $1 " = " $2 / $1}'
252837 / 8257 = 30.6209

See?  I used only one extra character per line!  On the other hand, I spent a good 30 minutes writing that command: 1 minute composing what I put there and the other 29 trying to figure out a way to do it without either running the find twice or writing anything to a temp file.  (You’ll notice I gave up and threw in a tee halfway through.)

UPDATE: I was too focused on the chaining problem to recognize that I could just have wc calculate the number of characters and lines at the same time.  This would have worked just as well, with no temp file, and with far less complexity:

find . | grep -E '(php|js|html|css)$' | xargs wc -l -c | tail -n 1 | awk '{print $2 " / " $1 " = " $2/$1}'

Vote Vote Voter Vote Voter

I enjoyed this query listing permits for a new application called, generically, “vote.”

[bobbojones@production aeacus] > SELECT * FROM permit WHERE application='vote';
+-------------+------------+-----------+----------------------+----------------+
| application | privilege  | principal | principal_type       | subapplication |
+-------------+------------+-----------+----------------------+----------------+
| vote        | vote       | voter     | vote:voter           |                |
+-------------+------------+-----------+----------------------+----------------+

I’m reminded first of when xkcd’s blag depicted “Wikipedia’s entry on blogs, with everything that is not the word ‘blog’ (or a derivative thereof) removed.”

I’m then reminded of a line of my own code from about five years ago that went something like:

$param = $this->_params[$params['param']];

(In my defense, I saw the absurdity immediately and renamed some variables, so the verbatim line is now lost to us, but its spirit remains.)

Transulcent 3D Pie Charts: The Future of Design

Since I’m currently working on a new application for our help desk, we’ve been evaluating features in other, existing applications.  We considered, among others, a hosted solution called “Service Now.”

Immediately after logging into the demo site, we saw this traumatizing departure from any known laws of graphic design:

Pie Chart à la Awful

Pie Chart à la Awful

Someone has evidently decided that since 3D pie charts are known to distort human perception of data, what will really make them useful is a layer of translucency.

Four, Oh Subversioned Four!

I’ve never really used Subversion’s web interface before, since I’m normally checking out or committing revisions from the command line.  However, this morning I wanted to browse quickly through the entire repository tree, so I opened what I thought was the right page.  The title read:

repository – Revision 404: /

Oh, 404.  The standard “page not found” error.

I went straight to our Knowledgebase to figure out the correct address.  I had it right; I just happened to commit revision #404 immediately before I opened the site for the first time, and Subversion was helpfully pointing that out.

That’s just awful timing.

The Poetry of Errors

In an application I just launched, customers can enter a list of people (by username) whom they want added to their website.  This is a large box, so we included instructions for its use directly inside: “To add users to your site, select a role above…” The instructions appear in gray and disappear when you click the box to begin typing, just like the word “Google” in Firefox’s standard search box.

Unfortunately, I inadvertently let the user click “Add” with my instructions still in the box.  The application naturally treated all the words in the sentence as usernames.  After weeding out those that couldn’t possibly be valid, it listed the remainder alphabetically in a table.  The result was this, which I find has a surprising poetry to it:

above add and are as both click
every fine finished for here like many
names please role select separate site space
then to type user users want with
you your

I like best the end: “to type user users want with you your.”

Since we caught the bug internally before any customer did (and I say “we” meaning “not me”), the only consequence is that we have this lovely poem to help us remember.

SELECT * FROM insanity LIMIT ∞

This was just unearthed in an application someone else (who shall remain nameless) built just about two years ago.  It’s reformatted to fit here, but otherwise unchanged.

$result = mysql_query("SELECT * FROM table_name"
    . " WHERE  id >= '" . mysql_real_escape_string($_POST['id'])
    . "' ORDER BY  `id` ASC LIMIT 0 , 1");

if ( !($row = mysql_fetch_array($result, MYSQL_ASSOC)) ) {
    $result = mysql_query("SELECT * FROM table_name"
        . " WHERE  id >= '1'"
        . " ORDER BY  `id` ASC LIMIT 0 , 1");
    $row = mysql_fetch_array($result, MYSQL_ASSOC);
}

So… we start by selecting all rows with id >= 27, then limit the results to only the first one… which should be id = 27.

Of course, if I ask for an id that’s not really in the database, I’ll now get some arbitrary other row that happens to be numbered next.  Plus, if we didn’t get any rows from the first query, we try again starting from ‘1’, thus returning whatever row we happen to find.

This is just awesome.

Unreachable

From my own code:

if ($ok) {
    // ... snip ...
    return;
} else {
    // ... snip ...
    exit;
}
// ... snip ... 50 lines of unreachable (and buggy) code

That can’t be good…

2,147,483,647 + 1 = 2,147,483,648

I love PHP.  For starters, it doesn’t have any of those pesky “compiler errors” other languages have.  Just think how much time I would have wasted over the last six years if I had to fix my errors before running my programs!

Plus, PHP doesn’t buy into the idiotic notions that integers have “maximum” values.  Other languages throw around fancy claims like “signed 32-bit integers can’t be larger than 2,147,483,647.”  Ha!  Real programmers know that’s only because the language designers were lazy! PHP respects our intelligence.  It’ll tell you the “maximum” integer value, but if you need a bigger number, just ask for it!

echo PHP_INT_MAX . ' ' . (PHP_INT_MAX + 1); 
// Produces: 2147483647 2147483648

(But seriously folks — I know other languages will coerce up to a 64-bit integer when the need arises.  MySQL does, for one.  I still laugh at the idea that I can write “max + 1” and have it actually work.)