Nintendo as a Pioneer

Jun 2, 2009

Hate on the Nintendo Wii all you want, but it has clearly made Sony and Microsoft nervous (especially since the Wii has made money since day one, while the 360 and PS3 are still losing money on each sale). This week, Sony announced a PS3 motion controller, and Microsoft announced the Project Natal motion controller. For those not already in the know, the Nintendo Wii has had this capability for over 2 years now (though, granted, the Microsoft approach is a new twist).

I agree that the Nintendo Wii has, at some levels, been a relatively 'weak' platform compared to the others. It lacks HD support, has a fairly thin library of games, and has clunky online support. As a result, the Wii has been given the cold-shoulder by the "hard-core gaming community." The two recently announced, upcoming Mario titles (Super Mario Galaxy 2 and The New Super Mario Bros.) probably aren't enough to improve its reputation.

All that aside, it looks like the "big boys" are playing catch-up to Nintendo's "little engine that could." Maybe Nintendo knows the future more than we think they do...

New Logo

Jun 1, 2009

I've whipped up a quick logo to dress up this site a bit. The previous plain-text heading was a bit boring (as one reader rightly pointed out), so hopefully this is a step in a better direction. Other minor style changes have also been made (sidebar headings should now look a little better, for example).

Thoughts? Constructive criticism? Comment away!

TF2 Updates Drop Today

May 21, 2009

The new Spy and Sniper class updates are coming today, with the following goodies:

To top it all off, Valve is opening Team Fortress 2 to everyone for free this weekend. So download Steam, pre-load the files, and join in the fun!

Additional Bug Fixes

May 21, 2009

I have squashed some bugs from yesterday's theme unveiling:

  • The primary page container now renders properly in IE 6
  • Recent comments show up again in the sidebar
  • The PayPal donate button had somehow disappeared from the donation information page. It has now been restored.
  • DreamHost discount information has been updated (it was woefully out of date)

Brand New Look

May 20, 2009

Born Geek has been given a new set of clothes! The old design was, quite frankly, an eyesore. This new layout is simpler, cleaner, and much easier on the eyes. Gravatar support has been added. And visitors using Firefox 3+ get extra eye candy (so switch today)! Not everything is complete in this new theme, so expect to see minor tweaks and fixes over the next few days. It's been tested in Firefox and IE 7. Your mileage may vary in anything else. As always, let me know what you think and if you stumble upon any bugs.

Also note that you may have to force a refresh if you visited the site recently, so as to pick up the new style sheet!

Sniper and Spy Updates

May 15, 2009

Not only are we getting a Sniper class update (with a bow and arrow and the Razorback shield), but it looks like Valve is shipping the Spy class update as well (with two new watches)! Let it be known that I officially love Valve and Team Fortress 2.

Coming along with these updates is a new game play type, Payload Race, which looks super fun, and two new arena maps (which I'm not too wild about). This massive update doesn't drop until next Thursday, so there are still some goodies to be unveiled. New hats are also going to be available in this update, which should provide some fun.

I'm really looking forward to this update, even though Spy and Sniper are my two least-played classes. Perhaps this will motivate me to spend more time in those roles.

Office Season Finale

May 15, 2009

Tonight's season finale for The Office was pretty weak, in my opinion. To begin with, I was a little miffed that it wasn't an hour long, but after the show was over, I was glad it hadn't been. I'm not sure I could have stood another half hour of boredom. The only redeeming part of the episode was the tension between Michael and Holly. Here's hoping that things get back on track next season!

What did you guys think?

An article entitled A Brief, Incomplete, and Mostly Wrong History of Programming Languages offers a very humorous glimpse into the world of programming. My absolute favorite snippet from the article:

1987 - Larry Wall falls asleep and hits Larry Wall's forehead on the keyboard. Upon waking Larry Wall decides that the string of characters on Larry Wall's monitor isn't random but an example program in a programming language that God wants His prophet, Larry Wall, to design. Perl is born.

It's funny because it's true. (Hat tip to Dustin for the pointer to this article.)

You've no doubt seen the commercials for the "free" triple credit score reports, or the "learn to work at home" packages on TV. In most of these cases, a URL is provided in the ad for you to visit. For the observant among us, note that the URL changes. Most often, a number appears at the end. For example, workathome.yes.you.can might become workathome58.yes.you.can and then workathome132.yes.you.can. This observation leads us to our Internet Safety Tip of the Day:

If the URL in an advertisement changes on a regular basis, you should stay away!

Especially since those "free" reports will actually cost you $30 a month.

This tip brought to you by the Internet Safety Council, the letter D, and support from viewers like you. Thank you.

The rather humorously titled Slashdot article Duke Nukem For Never, reports that 3D Realms, once among the brightest computer game developers, has closed for good. This is pretty sad for me, as I was once a major fan of the company's games. So big a fan, in fact, that I maintained a little Map Editing FAQ for the Build game engine. In essence, that document and those games are what got me publishing on the web in the first place. It's hard to believe that was 13 years ago.

I can't say I'm surprised that the company has gone out of business, however. They've made a bunch of poor choices over the past few years, and have essentially released no new self-developed titles since 1997's Shadow Warrior (which was a great game). It will be interesting to see what happens to whatever actually exists of Duke Nukem Forever.

I have lots of music that I like to listen to, and I sometimes want to listen to it while lounging around my living room. The most convenient (and obvious) way to access my music is through my iPod, which houses my entire collection. At the moment, I don't have a way to play my music in the living room (besides busting out my headphones, which I don't always feel like doing).

Does anyone have recommendations for how I might go about doing this? I don't want the music to play through the TV (I'm willing to buy external speakers). A user friendly interface would be beneficial as well (maybe a way to change tracks, volume, etc from the couch?).

What does everyone else do?

One of my Perl scripts here at work used the Add_Delta_Days subroutine from the Date::Calc module to do some calendar date arithmetic. I'm in the process of building a new machine on which this script will run, and I don't have access to an external network. Unfortunately, the install process for Date::Calc is fairly difficult. The module relies on a C library which must be compiled with the same compiler as was used to build the local Perl install. To make matters worse, the modules that Date::Calc is dependent on have similar requirements. As a result, I decided to skip installing this non-standard module, and instead use a home-brew replacement. It turns out that Add_Delta_Days is fairly straightforward to replace:

use Time::Local; # Standard module

sub addDaysToDate
{
    my ($y, $m, $d, $offset) = @_;

    # Convert the incoming date to epoch seconds
    my $TIME = timelocal(0, 0, 0, $d, $m-1, $y-1900);

    # Convert the offset from days to seconds and add
    # to our epoch seconds value
    $TIME += 60 * 60 * 24 * $offset;

    # Convert the epoch seconds back to a legal 'calendar date'
    # and return the date pieces
    my @values = localtime($TIME);
    return ($values[5] + 1900, $values[4] + 1, $values[3]);
}

You call this subroutine like this:

my $year = 2009;
my $month = 4;
my $day = 22;

my ($nYear, $nMonth, $nDay) = addDaysToDate($year, $month, $day, 30);

This subroutine isn't a one-to-one replacement, obviously. Unlike Date::Calc, my home-brew subroutine suffers from the Year 2038 problem (at least on 32-bit operating systems). It likewise can't go back in time by incredible amounts (I'm bound to the deltas around the epoch). However, this workaround saves me a bunch of setup time, and works just as well.

It's been quite a while since my last programming tips grab bag article, and it's high time for another. As promised, I'm discussing PHP this time around. Although simple, each of these tips is geared towards writing cleaner code, which is always a good thing.

1. Use Helper Functions to Get Incoming Data

Data is typically passed to a given web page through either GET or POST requests. To make things easy, PHP give us two superglobal arrays for each of these request types: $_GET and $_POST, respectively. I prefer to use helper functions to poke around in these superglobal arrays; it results in cleaner looking code. Here are the helper functions I typically use:

// Helper function for getting $_GET data
function getGet($key)
{
    if(isset($_GET[$key]))
    {
        if(is_array($_GET[$key]))
            return $_GET[$key];
        else
            return (trim($_GET[$key]));
    }
    else
        return null;
}

// Helper function for getting $_POST data
function getPost($key)
{
    if(isset($_POST[$key]))
    {
        if(is_array($_POST[$key]))
            return $_POST[$key];
        else
            return (trim($_POST[$key]));
    }
    else
        return null;
}

Calling these functions is super simple:

$someValue = getGet('some_value');

If the some_value parameter is set, the variable will get the appropriate value. If it's not set, the variable gets assigned null. So, all that's needed after calling getGet or getPost, is a test to make sure the variable is non-null:

if(! is_null($someValue))
{
    // ... do something
}

Note that these functions also handle the case where the incoming data may be an array (useful when processing lots of similar data fields at once). If the data is simply a scalar value, I run it through the trim function to make sure there's no stray whitespace on either side of the incoming value.

2. Write Your Own SQL Sanitizer

The first and most important rule when accepting data from a user is: never trust the user, even if that user is you! When incoming data is going to be put into a database, you need to sanitize the input to avoid SQL injection attacks. Like the superglobal arrays above, I like using a helper function for this task:

function dbSafe($string)
{
    global $db; // MySQLi extension instance
    return "'" . $db->escape_string($string) . "'";
}

In this example, I'm making use of the MySQLi extension. The $db variable is an instance of this extension, which gets created in another file. Here's an example of creating that instance, minus all the error checking (which you should do); the constants used as parameters should be self explanatory, and are defined elsewhere in my code:

$db = new mysqli(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME);

Back to our dbSafe function, all I do is create a string value: a single quote, followed by the escaped version of the incoming data, followed by another single quote. Let's assume that my test data is the following:

$string = dbSafe("Isn't this the greatest?");

The resulting value of $string becomes 'Isn\'t this the greatest?'. Nice and clean for insertion into a database! Again, this helper makes writing code faster and cleaner.

3. Make a Simple Output Sanitizer

If you work with an application that displays user-generated content (and after all, isn't that what PHP is for?), you have to deal with cross-site scripting (XSS) attacks as well. All such data that is to be rendered to the screen must be sanitized. The htmlentities and htmlspecialchars functions provide us with the capability to encode HTML entities, thus making our output safe. I prefer using the latter, since it's a little safer when working with UTF-8 encoded data (see my article Unicode and the Web: Part 1 for more on that topic). As before, I wrap the call to this function in a helper to save me some typing:

function safeString($text)
{
    return htmlspecialchars($text, ENT_QUOTES, 'UTF-8', FALSE);
}

Everything here should be self explanatory (see the htmlspecialchars manual entry for explanations on the parameters to that function). I make sure to use this any time I display user-generated content; even content that I myself generate! Not only is it important from an XSS point of view, but it helps keep your HTML validation compliant.

4. Use Alternate Conditional Syntax for Cleaner Code

Displaying HTML based on a certain condition is incredibly handy when working with any web application. I used to write this kind of code like this:

<?php
if($someCondition)
{
    echo "\t<div class=\"myclass\">Some element to insert</div>\n";
}
else
{
    echo "\t<div class=\"myclass\"></div>\n"; // Empty element
}
?>

Not only do the backslashed double quotes look bad, the whole thing is generally messy. Instead, I now make use of PHP's alternative syntax for control structures. Using this alternative syntax, the above code is modified to become:

<?php if($someCondition): ?>
    <div class="myclass">Some element to insert</div>
<?php else: ?>
    <div></div>
<?php endif; ?>

Isn't that better? The second form is much easier to read, arguably making things much easier to maintain down the road. And no more backslashes!

Giant Grocery Portions

Apr 20, 2009

It's no surprise to anyone that obesity in America is getting worse every year. This animated map shows the progression in the US between 1985 and 2007, and it's quite a depressing sight. Lots of factors are contributing to everyone's weight gain: poor eating habits, no exercise, etc., but part of the blame certainly lies with food manufacturers. In recent times, food portions have increased by an incredible amount, and they only seem to be getting worse. Not only are the larger portions contributing to our weight gain, they are also making it much harder for people like me to shop in the grocery store.

Before I go much farther, I must confess that I'm not a big eater. Growing up, I knew guys who could eat two or three times as much as I do at each meal. And there are plenty of my peers today who can do the same thing. So I realize that I'm already starting out on the low side of the curve. However, this doesn't change the fact that food manufacturers have gotten out of control with portion management.

Shopping for one is difficult enough to begin with, but I've noticed that it's gotten more so in recent times. While at the grocery store recently, I picked up some potato chips for lunch through the week. The bag I bought had "20% more chips free," making it even larger than the normal bag (which is a little too big to begin with). A sign below the bags of chips offered the following deal: buy 2 get 2 free. So, you have to buy four bags of chips to get a deal! Who in their right mind eats four, full-sized bags of potato chips? Even in reasonably sized families, that's an insane number of chips to buy at once.

Similarly, doughnut manufacturer Krispy Kreme apparently no longer sells their half-dozen doughnut boxes. Instead, they offer a new box of 9. Every once in a while (maybe once every two months), I used to pick up a half-dozen doughnuts and eat them through the week with my breakfast. By the end of that week, the last doughnuts had nearly grown stale, but were still good enough to reheat. A box of 9 would certainly not last the way I eat them.

There are plenty of other examples, but these two stick out in my mind since I encountered them recently. If food manufacturers would provide smaller portions, at somewhat lower prices, I would be able to enjoy their products more often and I wouldn't be wasting perfectly good food. As an added bonus, I wouldn't eat as much, and would feel better as a result. Does anyone else feel the way I do?

In a surprising move, Time Warner Cable is scrapping the bandwidth cap tests for Rochester, NY. Not only that, but it looks like TWC will be shelving the tiered pricing tests across the board, while "the customer education process continues." Maybe the internet works after all.

Digg Gets Shady

Apr 16, 2009

Jeffrey Zeldman has pointed his readers to an interesting article entitled Digg, Facebook Stealing Content, Traffic, Money From Publishers? The article focuses on the recently launched DiggBar, and the negative effects it's having on the web. I gave up on Digg long ago, and this just furthers my intent to stay away from the site. With shady practices like this, it doesn't deserve my attention.

It was great news to hear that captain Richard Phillips was rescued yesterday. I'm amazed that snipers could hit someone on a boat, from another boat, at a distance of nearly 100 feet.

As a result of this hostage situation, there has been a lot of news about pirate attacks around Somalia. It's clearly a big business for these people, seeing as their country is essentially a nonexistent entity. The problem is that these pirates have yet to be punished for their actions. 100% of their ransom attempts (up until now) have been carried through. In other words, they always win.

The other day, it occurred to me how we can solve this problem. All we need is a throwback to the days of World War 2. It's fairly apparent that these pirates have little naval power. They aren't heavily armed, they attack in small boats, and they haven't (yet) appeared in large numbers. As a direct result, this is a perfect opportunity to employ the use of the convoy system.

All we need to do is establish a perimeter around the problem area. If you want to go inside this perimeter, even if you're just passing through, you have to be a part of a convoy. Multiple convoys would leave daily, protected by the various naval ships that are already patrolling the area. This would make attacks much harder, much less infrequent, and would (I claim) put a large stop on the activity going on.

It looks like Time Warner is expanding their broadband bandwidth caps to new markets. One of those new markets is in Greensboro, NC, about 1 hour from where I live. To add insult to injury, it looks like prices are going up as well. The 40GB tier will cost $55, which is $5 more than what I pay today. As they say, this stuff is getting real.

The Office has really seen a resurgence in quality over the past several weeks. I lamented once before about a perceived downward spiral for the show, but tonight's episode was a real throwback to the good old days of seasons 2 and 3. Other recent episodes have been equally as strong, making the show a joy to watch again. Michael's tension with his new boss Charles is truly palpable, allowing the viewer to share those awkward moments that made the early seasons so fun.

It looks as if the writers are setting things up for a huge season finale. We get to see Ryan for the first time in a while in the next episode (which is two weeks from tonight), and hilarity should ensue as Michael and Pam set out to start a new paper company. Will Michael hire Ryan as an employee in his new company? Could Holly make another appearance at the end of the season? Will the folks at Dunder-Mifflin realize that, despite his antics, Michael Scott is the right man for their company?

I can't wait to find out.

Back in the spring of 2005, after having graduating from college, I went looking for a job. I got the chance to interview for Microsoft, though I'm not sure what I would have ended up doing had I gotten the job (they never really told me). My interview was conducted entirely over the phone, and consisted of the typical "brain teaser" type questions that Microsoft is famous for. Needless to say, I performed very poorly and was instantly rejected. The guy on the phone said he'd let me know and, 10 minutes later via email, I knew.

One of the questions they asked me stumped me beyond belief, and I butchered my answer terribly. Not only was I embarrassed for myself, I was embarrassed for the interviewer, having to patiently listen to me. :oops: Anyway, here's a retelling of the question I was asked:

Given a large NxN tic-tac-toe board (instead of the regular 3x3 board), design a function to determine whether any player is winning in the current round, given the current board state.

I realize now that I misinterpreted the question horribly. The interviewer stated the question quite differently than I have it written above; I believe he used something along the lines of "given a tic-tac-toe board of N dimensions ..." I assumed that the bit about dimensionality meant delving into the realm of 3 or more physical dimensions; essentially something like 3-D tic-tac-toe. Obviously, solving such a problem is much more difficult than solving on an NxN 2-D board.

Tonight, for whatever reason, I recalled this question and the fact that I never found an answer for myself. Happily, I subsequently stumbled upon someone else's answer (see question 4), which is quite clever. It's good to finally resolve this problem.

I know interviewing candidates for a job can be tricky, but asking these kinds of questions is silly. Does someone's ability to answer this kind of question really prove they are a better programmer than someone who can't? In the end, I'm eternally glad I didn't get hired for Microsoft; I now realize they are one of the companies I would least like to work for. My current employer seemed much more concerned with real-world problems, my previous employment experience, and the (increasingly rare) ability to program in C++. For that, I am oh-so-grateful.