gatlingGun shoots holes in your array

Here’s a snippet I created to generate invalid data from a valid key-value array. It’s really handy for testing. Feel free to use it.

  /**
   * Gatling gun takes an array of valid params and returns every
   * combination of invalid data caused by blanking out individual params.
   *
   * Example:
   *
   * $validData = array('firstName' => 'Gatling',
   *                    'lastName' => 'Gun',
   *                    'age' => 12);
   *
   * $ggData = gatlingGun($validData);
   *
   * $ggData = array(
   *     array('firstName' => '',        'lastName' => '',    'age' => ''),
   *     array('firstName' => '',        'lastName' => '',    'age' => 12),
   *     array('firstName' => '',        'lastName' => 'Gun', 'age' => ''),
   *     array('firstName' => '',        'lastName' => 'Gun', 'age' => 12),
   *     array('firstName' => 'Gatling', 'lastName' => '',    'age' => ''),
   *     array('firstName' => 'Gatling', 'lastName' => '',    'age' => 12),
   *     array('firstName' => 'Gatling', 'lastName' => 'Gun', 'age' => '')
   * );
   *
   *
   * @param array $validData
   * @return array
   *
   */
  function gatlingGun($validData)
  {
      $original = $validData;
      $invalidCombinations = array();

      $max = count($original);
      $keys = array_keys($original);
      $combinations = pow(2, $max) - 1;

      for ($i = 0; $i < $combinations; $i++) {
           $tmp = array();
           $j = count($keys) - 1;
           foreach ($keys as $k => $key) {
              $tmp[$key] = (($i & pow(2,$j)) == 0) ? '' : $original[$key];
              $j--;
          }

          $invalidCombinations[] = $tmp;
      }
      return $invalidCombinations;
  }

Just be careful, the number of combinations it comes up with is 2^n - 1. So the number of invalid combinations from an array with 10 key-value pairs will quickly balloon to 1023.

Do drop me a line to let me know if this has been helpful for you.

Machine Jobs: career advice from a software developer

This Yesterday morning, I got out a little earlier than usual – combination of an early night before, and me wanting to beat the weather to work. It was so gloomy, the skies threatened to burst and pour down at any moment.

Coming up to a quiet traffic-lit intersection, it suddenly dawned upon me that once upon a time, a human being had to perform the very manual task of directing traffic at an intersection. Given that I was commuting to work, I couldn’t help but think of Mr. Expert Traffic Conductor waking up one fateful morning in 1868 to find that he wouldn’t be going to work that day because some machine with light bulbs had just replaced him.

That made me think of other such jobs were replaced such a long time ago, we forget that a human once had to devote his or her life to perform the task, day in, day out. One example is the elevator operator. A another one, the telephone operator.

More currently, I’m inclined to believe the reason a good portion of the human workforce still have their jobs isn’t because machines can’t yet perform them, but because the economics still swing in favour of hiring a human being over building and employing a machine equivalent. ‘Still’ being the operative word.

This is why it puzzles me when someone aspires to be more machine-like with their work.

Granted, I’m not unfamiliar with the fact that the more work one is able to perform per unit time generally translates into higher productivity which, in most cases, increases one’s income. Also granted, I’m acutely aware that every higher-up dreams of commanding a cohort of machine-like human beings; so for an underling, the contortion one’s humanity often presents itself as a wise career move, until you realize you’re just a stop-gap while the real machines creep within range of the corporate budget.

Still, the days of such “machineable” careers are severely numbered. You can trust me on that because bringing such a reality to past is implied in my job description as a software developer.

On the surface, it says “make better software to empower human beings”. What it really means is “make software so that we don’t need to pay that guy to sit there all day and click his mouse”. True story.

So if one is to derive any stone cold career advice out of this, it is to steer clear of the competition.

Instead of aspiring to be more machine-like, seek to be less. Spend time cultivating the things that are uniquely human – traits like creativity, beauty, vision, intelligence, compassion, inspiration. While this almost precludes you from scoring a mindless, well-paying, short-term job, at very least you won’t be out of one when a machine does better.

Cross-training the mind

Back in my high school years, I was an avid mountain biker. Sure, two cycling buddies and I would go riding after school, during weekends, etc, but “avid” more in the sense that we’d thoroughly consume every cycling magazine that would grace the shelves of the school library.

One of the articles I remember very clearly till this day had to do with the way professional cyclist train. One of the vital muscle groups that they aim to strengthen is the abdominal muscles. Apparently (and sensibly), it’s one of those muscle groups that greatly affects the performance of a cyclist, but isn’t actively strengthened in the act cycling. Therefore they would put themselves through a range of off-bike regimes in order to develop those muscles. Cross training, basically.

I can’t help but extrapolate that to the way I engage my programming craft. Given the abundance of introductory tutorials to various programming languages on the Internet, I’d spent many a weekend picking a new language or framework, working through a tutorial, and expose myself to the thinking behind it.

These days, while I code primarily in PHP against an enterprise-y object-oriented MVC framework, I find myself slipping in the occasional functional declaration, or borrowing an enumerator idiom from a different language. Things that I would’ve never done if I simply remained in PHP land.

So onward with my quest for more diverse cross-training, I had a go at Gödel, Escher, Bach: an Eternal Golden Braid. Today, after failing miserably at explaining it to a fellow nerdhead (she’s an econometricist), I figured I’d give it a rest and pick something a little easier – A Beginners Guide to Graph Theory 2e.

Armed with my new Kindle DX (be-earlied birthday present from the wifey), and a stack of PDF’s I’ve acquired over the years, I’m now 10 pages into an introduction about sets and digraphs.

Wish me luck.

Freelance or Permanent

This question popped up at least 3 times in the past 6 weeks. Conjuring up an answer for it forced me to think it through very carefully.

My last permanent position was with a non-profit company. When I left for freelancing and running my own business, it was somewhat around the same time the GFC hit most of the developing/developed world. Everyday there was news of jobs being cut, organisations “restructured”, etc.

Because of the calamity all around me, it made being a business owner (or more bluntly put, unemployed) less unpalatable. The argument was, “being permanent isn’t all the secure either”. The months that followed saw me build up a convincing case for being a freelancer over being an employee.

Over the years, things changed, the work that I busied myself with evolved from juggling multiple clients and projects, to more recently, devoting most of my week to one project, for one client – not unlike what a full-time employee might be accustomed to.

When I was most recently asked why I’d remain as a contractor as opposed to committing as a permanent, the best I could come up with was:

“It’s more a frame of mind”

I has been my way of keeping on my toes, affirming and preserving my identity as an independent professional, and not overexposing myself to the whims and fancies of a composite construct.

Work matters have been rolling along very swimmingly, I hope I don’t get swept up and disoriented, because it looks like it’s going to be one hell of a ride.

Symfony2 ContainerAware Callback Validation

Today I had a big win at work.

We’re building an SOA platform for the business, so different bits of data end up sitting on different services, contactable only via a RESTful API.

One of the roadblocks we hit was validating some Service B data entered into Service A. Symfony2’s built in validators do a great job when everything is available on the same box, in the same database, but falls completely flat when it needs to validate outside a service boundary.

So I figured out how to inject a DI container into a Callback validator on Service A, and proceeded to summon some other validator services that would query the existence of a particular resource entity residing on Service B via HTTP.

It’s late now, but I’ll share the code when I get a little more time. Leave a comment if you’re really desperate to find out how it was done.