Friday 26 May 2017

An Instructional Experience

Knowledge transfer is an oft-overlooked skill of developers. We're often so caught up in learning that we forget to engage in the process from the other perspective - that of the teacher. Doing so can yield dividends, for in the process of imparting concepts, one's own understanding often increases as well.

Also, teaching someone to write code is basically communication, and the importance of that in any developer cannot be overstated.

Before becoming a web developer; indeed, before even starting life as a tech professional, as a teen I was giving tuition to kids to offset the costs of schoolbooks. This was a purely one-on-one gig, and it would be many years before I actually conducted a class in an actual classroom.

The year was 2001, and I had just graduated with a Bachelor's Degree in Information Technology. The economy was facing a downturn and jobs were not forthcoming. I made ends meet by taking on freelance assignments and teaching weekend and evening classes.

Weekend classes were Computer Literacy, and my youthful patience was severely and repeatedly tested teaching senior citizens how to use the Internet. If it wasn't for the fact that I was starving, I would have quit after the fifth geriatric used his mouse upside down and wondered why it wasn't working.

For evening classes, I taught SQL, a subject in which I had done reasonably well in school. This didn't go well. I was too fresh-faced; too amateurish. I'd yet to actually accumulate any professional experience, and it showed. My late grandmother (bless her) encouraged me to keep at it and assured me that looking young wasn't a crime. Little did she know how much I detested the act of imparting skills I had yet to earn.

Grandma's little babyface

Fast forward ten years later, I was a full-fledged tech professional with six years of desktop support and four years of web development under my belt. My then-boss sent me to a client to deliver a course in MVC. That was the first time I had heard of MVC. I spent the entire weekend on a crash course learning the subject. You bet your ass I was nervous... but to my surprise, not only did the tech professionals in the classroom show me an unprecedented amount of respect, they actually thought I knew my shit. One of them even privately approached me with an eye for poaching an experienced professional with MVC skills!

What the actual fuck?!

More substantial teaching experience

Another year later, an ex-colleague introduced me a pro bono gig at the Muscular Dystrophy Association of Singapore, teaching PHP to members. For those not in the know, Muscular Dystrophy is a degenerative disease that causes the victim's limbs and organs to be underdeveloped. My students were wheelchair-bound and extremely slow typists. However, up there, they were perfectly healthy.

Before I continue, I want to stress that this wasn't an altruistic act of nobility on my part, nor do I have some bombastic virtue-signalling reason behind doing this gig. My motivations were completely selfish. You see, I am a web development enthusiast. That's how I've been able to stay in the game this long. And like most enthusiasts, I'm perfectly happy to share with people who are interested. And nothing spelled interest like a bunch of guys in wheelchairs painstakingly making their way down to MDAS every week, rain or shine, to learn the stuff. If someone could display that much commitment, I was more than willing to take half a day off every week to teach them. The fact that they were guys in wheelchairs did not matter. They could have been rich privileged kids for all I cared.

Also, as mentioned before, teaching hones the skills in the subject you are teaching. And as a tech professional, I was all for it.

The weeks went by as I brought them through the concepts of Client-server Architecture, variables, operators, conditionals and iterators. The going was slow. Real slow. Having underdeveloped limbs, they simply could not type as fast as the average programmer. Sometimes even using special characters like curly braces and quotation marks was a chore. It was from this, that I learned. I saw how they got around these limitations with various devices such as special keyboards, styluses and touch-screens. One of them even drove. I had the good fortune to help her move some stuff to her car, and witnessed the way she hauled herself into the driver's seat and tucked her wheelchair into the back all by herself. I saw the way the brake and accelerator were rigged just below the steering wheel to account for her abnormally short legs. Before this, in all my ignorance, I'd never even heard of a disability vehicle. My eyes were being truly opened.

The icing on the cake came around the last few weeks of the course, while I was taking them through the concept of arrays. Every time I made a mistake in the code, they would call me out on it. Not just syntax errors, but logic errors. After every lesson, I had been providing them links to follow for further reading and revision. And they had done their reading and revision. Instead of me pointing out their errors, these little devils were now pointing out mine. It's really hard to describe the overwhelming pride I felt that day.

Epilogue

My primary motive had been to share. I won't claim that I taught them extremely well, but somewhere along the way, I had helped fan the flame of my enthusiasm and it was starting to spread. And sometimes, transfer of enthusiasm is more valuable than the transfer of knowledge.

Soon, I changed jobs and my new employer no longer allowed me to spend my leave in regular half-days. At that point, I was no longer able to schedule classes. However, since then, I've started this blog and put up web tutorials. In some form or other, I want to continue sharing.

Now that was a really classy experience!
T___T

Saturday 20 May 2017

Frameworks in Perspective, redux

Back in 2015, I wrote a piece titled Frameworks in Perspective. My opinion of frameworks has not changed all that much since, though it's admittedly mellowed a fair bit after the rather juvenile rant I posted. Two years have passed, and I've had the benefit of a little more perspective.

You see, back then I was fresh off working under a Manager who was evangelistic about using frameworks. But it was hard for me to respect her style because she used them even for the smallest projects. The time she spent didn't seem appreciably less than the time it took for me to churn out code without using frameworks. And the aggressiveness with which she pushed her favorite framework, CodeIgniter, only served to turn me off it, and off frameworks in general.

Old-school is old-school.

A year later, I was out of that company and working under an old-school Manager who didn't use frameworks. In fact, he was so old-school he remembered dealing in magnetic tapes and COBOL. His code was VBScript in classic ASP, his lovingly crafted system honed through many years of changes and extensions. He did not believe in frameworks. He considered them clunky and ungainly, wasteful of system resources and not worth the time to learn. If he needed to write a UI, he wrote HTML and CSS the old-fashioned way. If he needed scripts, he did pretty much the same thing. His attitude towards the cloud was similar.

I liked this guy, and I had to acknowledge his obvious years of experience. Still, as time went on, I found his aversion towards frameworks stifling. Here was a guy, I realized, who absolutely needed to stay in this company because most other companies out there would find his skillset obsolete. And I resolved not to turn into him. Not because I didn't respect him - I do, he's a stand-up guy who takes care of his subordinates - but because I value my professional autonomy and refuse to allow it to be compromised by attachment to any one company.

Extremes

What was the difference between the first Manager and the second? Both harbored extreme attitudes. One would use only frameworks (and I suspect she was incapable of working any other way) and the other would never use frameworks. In my humble (or not so humble) estimation, they are both wrong.

In my line of work, you do whatever it takes to get shit done, by any means necessary. With or without frameworks. There is no only or never.

What's changed?

I've learned to use Bootstrap. I've picked up jQuery Mobile and AngularJS. For the past six months, I've been using Semantic UI and MeteorJS. Recently, I've even begun exploring CodeIgniter again. Basically, my aversion towards using frameworks has softened considerably in the past two years. I have gained an increased appreciation of how frameworks make life easier, especially for large-scale projects, and small-scale projects with plans for expansion.

It's also a matter of pragmatism. If I'm coding for work, whatever will get me the fastest results in the least amount of time, gets the nod. If that involves using frameworks and libraries, so be it.

I used to be really hung up on wastage. To me, every line of code in an application needed to serve a purpose. Frameworks and libraries ran counter to that purpose because they provide tons of functionality that any given application is unlikely to use 100% of. But now... meh. Given that roughly 90% of the web is like that now anyway, obsessing over wastage seems a tad pointless.

What hasn't changed?

I still don't think taking short-cuts without understanding the nature of those short-cuts, is the way. At least, not for a tech professional.

Technology has evolved, yes. A layman, for instance, may now create websites via Online Website Builders such as WiX, SquareSpace or Weebly without knowing a lick of HTML, CSS or JavaScript. I am a web developer. I can use those same tools to build websites, but not knowing HTML, CSS and Javascript is a luxury I don't have.

And any developer who uses frameworks without understanding what that framework does for them, isn't that much different from a layman in that regard. The typical web framework automates tasks like routing, sanitizing input and guarding against security threats such as CSRF and SQL Injection. I would find it alarming if a developer used frameworks without understanding how to implement those things without frameworks, or, in some cases, not even knowing what those things are!

I think of using a framework as akin to driving a car. The objective is to get from Point A to Point B, in the shortest time possible. Knowing how to drive a car is good. Knowing how to drive a car but not knowing how to walk (not really possible, but it's just an analogy)... not so good.

Point A to Point B.

Of course, at work, nobody has time to wait for you to walk from Point A to Point B. Of course they'd prefer you to drive. I'm not saying that frameworks are bad for business. On the contrary, they're excellent for business. They're only bad for developers, unless said developer has a rock-solid foundation to fall back on.

Just to be clear, I'm not expecting praise just because I can get routing up without relying on a framework. That's the bare minimum. Expecting applause would be like a database administrator wanting accolades for knowing how to write Stored Procedures!

Tool-user vs Tool-maker, a question of expertise

I found this blogpost particularly poignant. This is not to say that developers should have the skills of tool-makers, but rather that they should have a better appreciation for what those tools accomplish on their behalf. If a developer is going to use tools without learning at least a little about what goes under the hood, there is little point in calling them developers. The same way it is really hard to consider a guy a web dev simply because he can make a website using Weebly.

I've tried to bring this point across. I was met with disproportionate outrage from places like Facebook (nothing new there) and Quora (trust me, despite the BNBR regulations, many people still manage to be snarky and condescending... not that I have a leg to stand on). I had fellow geeks up in arms, nerd-raging and throwing clichés like "Standing On The Shoulders Of Giants" and "Reinventing The Wheel" at me, like it was going out of style.

What's next? "Don't Repeat Yourself"?

Dudes, dudes. I've heard this all before. Why is this even a point of contention? I agree. Frameworks are there so we don't have to re-do all the work someone has already done, and focus on doing new stuff instead. Yes, I get it!

But how can we consider someone expert on any given technology when all he does is use tools that leverage on that technology? We can't, and I include myself in that assessment. But here's the thing, and this may seem a bit outlandish to some...

...it is entirely OK not to be an expert. Not an expert, but just a tool-user? That's perfectly fine. Just because you're not an expert doesn't make you a bad person, a terrorist or a televangelist. Besides, expertise exists on different tiers.

Businesses often say they're looking for experts when hiring, but what they really want are people who can get shit done. They don't know, and probably don't care, about what goes on under the hood. They're laymen, for Christ's sake!

Results vs Process

Sometimes the whole thing about using frameworks just boils down to this - results vs process.

If your organization tells you they need a responsive website, they don't care if you use Bootstrap or Semantic UI, code it the hard way, or ask your dog to do it for you. They just want a result, and they want it yesterday.

OMG Fifi, you're a genius!

On the other hand, if I'm doing stuff for myself, I should feel free to take as long as I want. The result does not matter. The process does. If, for example, I go for 20 laps in the pool, I'm not going to do the butterfly stroke just so I can complete the 20 laps faster. No, I'm going to take my own sweet time and slowly breaststroke all 20 laps. Enjoy the process. This is not work for me. I'm a web developer enjoying a leisurely swim, not an Olympic athlete!

In other words, your employer pays for your time, so make that time worth something.

In conclusion...

I still have nothing against frameworks. Properly applied and in the right context, they can be a huge boon. The only point of contention appears to be - what constitutes the right context?

But that's for another day, and another time.

Non-expertly yours,
T___T

Tuesday 16 May 2017

Web Tutorial: AngularJS BMI Calculator

A couple years back, while beefing up on my front-end repertoire, I came across this nifty little front-end framework known as AngularJS. And had a fair bit of fun with it.

Angular 2 has come out since then, but for old times' sake, let's revisit one of the little projects I tinkered with in AngularJS. It's a BMI calculator I made for shits and giggles.

What's BMI?

It's an acronym for Body-Mass Index. Basically, you take your height and weight, then apply a formula that gives you the BMI. The BMI chart tells you whether you're dangerously underweight, overweight, or just right, or any range in between.

Let's get started!

For this, you'll need a HTML file, index.html, and a js file, main.js

The main.js file should be stored in the js folder. This is not absolutely necessary, but it's a good habit which we should follow.



Your HTML begins like this...
index.html
<!DOCTYPE html>
<html>
    <head>
        <title>BMI</title>
        <script src="js/main.js"></script>
    </head>

    <body>

    </body>
</html>


Now we're going to add a little something that makes this an Angular app - the reference to the external AngularJS library.
index.html
<!DOCTYPE html>
<html>
    <head>
        <title>BMI</title>
        <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
        <script src="js/main.js"></script>
    </head>

    <body>

    </body>
</html>


Next, we add two range inputs with ids of rngHeight and rngWeight respectively, as well as labels for those inputs.
index.html
<!DOCTYPE html>
<html>
    <head>
        <title>BMI</title>
        <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
        <script src="js/main.js"></script>
    </head>

    <body>
        <div>
            <label for="rngHeight">Height </label>
            <input type="range" id="rngHeight"> 
            <br />
            <label for="rngWeight">Weight </label>
            <input type="range" id="rngWeight">
        </div>
    </body>
</html>


Let's set rngHeight's input range between 1 to 300 cm, and rngWeight's range between 1 to 300000 g. Which is probably a reasonable estimate.
index.html
<!DOCTYPE html>
<html>
    <head>
        <title>BMI</title>
        <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
        <script src="js/main.js"></script>
    </head>

    <body>
        <div>
            <label for="rngHeight">Height </label>
            <input type="range" id="rngHeight" min="1" max="300"
            <br />
            <label for="rngWeight">Weight </label>
            <input type="range" id="rngWeight" min="1" max="30000">
        </div>
    </body>
</html>


So this is what your current output looks like...


The front-end will do us, for now. Let's focus on adding functionality. To do this the Angular way, we need to modify the HTML this way.
index.html
<body ng-app="bmiApp">


And then we need to add this code into main.js. This declares a variable, app, and sets it to a module created by AngularJS's module() method, using the the element we just tagged with ng-app="bmiApp" above. That means anything within the body tag is now considered part of the app module.
main.js
var app = angular.module("bmiApp", []);


Now make these changes to your HTML. The div element that houses the range inputs rngHeight and rngWeight now has a new attribute ng-controller with the value "bmiCtrl". This tags it as the controller bmiCtrl. The rngHeight input has ng-model added as an attribute with the value "height_cm". Something similar has been done for rngWeight. Why will become clear momentarily.
index.html
        <div ng-controller="bmiCtrl">
            <label for="rngHeight">Height </label>
            <input type="range" id="rngHeight" min="1" max="300" ng-model="height_cm">
            <br />
            <label for="rngWeight">Weight </label>
            <input type="range" id="rngWeight" min="1" max="300000" ng-model="weight_g">
        </div>


Now, let's add this code in. This creates a controller in the app module, and passes in the string "bmiCtrl" as the first argument, and a function (with $scope as the argument) as the second argument.
main.js
var app = angular.module("bmiApp", []);

app.controller("bmiCtrl",
function($scope)
{

}
);


Now add this code into the function. This ensures that the default values for the local scope variables height_cm and weight_g are 100 and 10000 respectively.
main.js
var app = angular.module("bmiApp", []);

app.controller("bmiCtrl",
function($scope)
{
    $scope.height_cm=100;
    $scope.weight_g=10000;
}
);


Refresh. Since we've bound rngHeight to height_cm and rngWeight to weight_g, it should look like this now.


OK, great! Now that data looks correct, let's add a little visual indicator to the range inputs. Having the values in centimeters and grams is necessary for functionality, but a little too granular for human consumption. So we're going to display values in meters and kilograms.
index.html
        <div ng-controller="bmiCtrl">
            <label for="rngHeight">Height </label>
            <input type="range" id="rngHeight" min="1" max="300" ng-model="height_cm">{{height_m}} m
            <br />
            <label for="rngWeight">Weight </label>
            <input type="range" id="rngWeight" min="1" max="300000" ng-model="weight_g">{{weight_kg}} kg
        </div>


Your display now has "m" and "kg" next to the range inputs. You'll notice that the double curly bracers and stuff don't show up - that's because the curlies are AngularJS's placeholders for values. And since the values height_m and weight_kg are currently undefined, they simply don't show up.


One more thing we need to add to your HTML. ng-init ensures that the calc_bmi() function is run when the page is initialized.
index.html
        <div ng-controller="bmiCtrl" ng-init="calc_bmi()">
            <label for="rngHeight">Height </label>
            <input type="range" id="rngHeight" min="1" max="300" ng-model="height_cm">{{height_m}} m
            <br />
            <label for="rngWeight">Weight </label>
            <input type="range" id="rngWeight" min="1" max="300000" ng-model="weight_g">{{weight_kg}} kg
        </div>


Now let's do this. Here, within the scope defined by the controller bmiCtrl, we have the calc_cmi() function. First, it takes the values for height_cm and weight_g, and converts them using the functions convert_height() and convert_weight() respectively.
main.js
app.controller("bmiCtrl", function($scope)
{   
    $scope.calc_bmi=
    function()
    {
        $scope.height_m=convert_height($scope.height_cm);
        $scope.weight_kg=convert_weight($scope.weight_g);
    };

    $scope.height_cm=100;
    $scope.weight_g=10000;
});


And here we define the functions convert_height() and convert_weight(). These functions are not accessible by the app, and run only within the scope of calc_bmi. convert_height() converts the value of its argument to meters and returns the new value to two decimal places. convert weight() does something similar, except this time it converts grams to kilograms.
main.js
app.controller("bmiCtrl", function($scope)
{   
    $scope.calc_bmi=
    function()
    {
        function convert_height(ht)
        {
            return (ht/100).toFixed(2);
        }

        function convert_weight(wt)
        {
            return (wt/1000).toFixed(2);
        }

        $scope.height_m=convert_height($scope.height_cm);
        $scope.weight_kg=convert_weight($scope.weight_g);
    };

    $scope.height_cm=100;
    $scope.weight_g=10000;
});


Now the values for height_m and weight_kg should show up!


OK, now we're going to make this little app react to your input. This ensures that calc_bmi() is run not just on page initialization, but also whenever the values in the range inputs change!
index.html
        <div ng-controller="bmiCtrl" ng-init="calc_bmi()">
            <label for="rngHeight">Height </label>
            <input type="range" id="rngHeight" min="1" max="300" ng-change="calc_bmi()" ng-model="height_cm">{{height_m}} m
            <br />
            <label for="rngWeight">Weight </label>
            <input type="range" id="rngWeight" min="1" max="300000" ng-change="calc_bmi()" ng-model="weight_g">{{weight_kg}} kg
        </div>


Refresh. Do the values change when you move the sliders?


Right. From here on, it's just a matter of further applying what we've already done! Modify your HTML.
index.html
        <div ng-controller="bmiCtrl" ng-init="calc_bmi()">
            <label for="rngHeight">Height </label>
            <input type="range" id="rngHeight" min="1" max="300" ng-change="calc_bmi()" ng-model="height_cm">{{height_m}} m
            <br />
            <label for="rngWeight">Weight </label>
            <input type="range" id="rngWeight" min="1" max="300000" ng-change="calc_bmi()" ng-model="weight_g">{{weight_kg}} kg
            <h1>Your BMI is {{bmi}}</h1>
        </div>


Again, you should not be seeing anything within the curly bracers, because those values are undefined.


Modify the JavaScript. This new line ensures that height_m and weight_kg are converted to BMI after being defined by converting height_cm and weight_g.
main.js
app.controller("bmiCtrl", function($scope)
{   
    $scope.calc_bmi=
    function()
    {
        function convert_height(ht)
        {
            return (ht/100).toFixed(2);
        }

        function convert_weight(wt)
        {
            return (wt/1000).toFixed(2);
        }

        $scope.height_m=convert_height($scope.height_cm);
        $scope.weight_kg=convert_weight($scope.weight_g);

        $scope.bmi=convert_bmi($scope.height_m,$scope.weight_kg);
    };

    $scope.height_cm=100;
    $scope.weight_g=10000;
});


And of course, here we define the convert_bmi() function. It basically takes the height and weight in meters and kilograms respectively, and applies the formula, then returns the result to two decimal places.
main.js
app.controller("bmiCtrl", function($scope)
{   
    $scope.calc_bmi=
    function()
    {
        function convert_height(ht)
        {
            return (ht/100).toFixed(2);
        }

        function convert_weight(wt)
        {
            return (wt/1000).toFixed(2);
        }

        function convert_bmi(ht,wt)
        {
            return (wt/(ht*ht)).toFixed(2);
        }

        $scope.height_m=convert_height($scope.height_cm);
        $scope.weight_kg=convert_weight($scope.weight_g);

        $scope.bmi=convert_bmi($scope.height_m,$scope.weight_kg);
    };

    $scope.height_cm=100;
    $scope.weight_g=10000;
});


Now try your code again! The BMI calculation should appear, and should adjust with your sliders!


But hold on, we're not done yet. The BMI's just a number. The typical user, of course, wants to know what it means! So add this to your HTML.
index.html
        <div ng-controller="bmiCtrl" ng-init="calc_bmi()">
            <label for="rngHeight">Height </label>
            <input type="range" id="rngHeight" min="1" max="300" ng-change="calc_bmi()" ng-model="height_cm">{{height_m}} m
            <br />
            <label for="rngWeight">Weight </label>
            <input type="range" id="rngWeight" min="1" max="300000" ng-change="calc_bmi()" ng-model="weight_g">{{weight_kg}} kg
            <h1>Your BMI is {{bmi}}</h1>
            <p>{{remarks}}</p>
        </div>


This creates a new scope variable, remarks, which is derived from running the function convert_remarks() with bmi as an argument.
main.js
app.controller("bmiCtrl", function($scope)
{
    function convert_height(ht)
    {
        return (ht/100).toFixed(2);
    }

    function convert_weight(wt)
    {
        return (wt/1000).toFixed(2);
    }

    function convert_bmi(ht,wt)
    {
        return (wt/(ht*ht)).toFixed(2);
    }   

    $scope.calc_bmi=
    function()
    {
        $scope.height_m=convert_height($scope.height_cm);
        $scope.weight_kg=convert_weight($scope.weight_g);

        $scope.bmi=convert_bmi($scope.height_m,$scope.weight_kg);

        $scope.remarks=convert_remarks($scope.bmi);
    };

    $scope.height_cm=100;
    $scope.weight_g=10000;
});


And of course, convert_remarks() takes bmi and returns a text message based on its range!
main.js
app.controller("bmiCtrl", function($scope)
{
    function convert_height(ht)
    {
        return (ht/100).toFixed(2);
    }

    function convert_weight(wt)
    {
        return (wt/1000).toFixed(2);
    }

    function convert_bmi(ht,wt)
    {
        return (wt/(ht*ht)).toFixed(2);
    }

    function convert_remarks(bmi)
    {
        if (bmi<=20) return "You're malnourished.";
        if (bmi>20&&bmi<=22) return "Looking a tad lightweight here.";
        if (bmi>22&&bmi<=24) return "Looking good.";
        if (bmi>24&&bmi<=27) return "Time to shed a few pounds.";
        if (bmi>27) return "Dude, you have a problem. A HEAVY problem.";
    }   

    $scope.calc_bmi=
    function()
    {
        $scope.height_m=convert_height($scope.height_cm);
        $scope.weight_kg=convert_weight($scope.weight_g);

        $scope.bmi=convert_bmi($scope.height_m,$scope.weight_kg);

        $scope.remarks=convert_remarks($scope.bmi);
    };

    $scope.height_cm=100;
    $scope.weight_g=10000;
});


Re-run your code. The comments should appear now!


That's it for our little AngularJS project...

There's a whole lot more we can accomplish with this framework, of course. This wasn't anything I couldn't have done in plain old vanilla JavaScript, but it did feature two-way data binding and scoped functions and variables. Which makes this little app far more maintainable if I ever wanted to expand it. This little appetizer might actually motivate me to get off my arse and learn Angular2.

Is there more? Weight and see!
T___T

Friday 12 May 2017

Why you should love your job

A couple weeks back, Minister Chan Chun Sing delivered a speech during my alma mater Temasek Polytechnic's graduation ceremony. This was met with a certain amount of controversy, as he addressed the career aspiratons of the graduates with these words...
"In today's world, where we have many choices, it is very easy for us to get lost among the many choices and get very distracted. We are constantly searching for that something that would give us perfection, searching for that something that would give us meaning. But we would often fail, and then we will be disappointed. But instead, if we change our perspective, and ask ourselves, can we do justice to the job we are doing, can we do justice to the relationship that we are building, can we give meaning to what we are doing, then we are in control. And if we can give, rather than just expect to take, then regardless of our station in life then I think we will find meaning because we give meaning. But to only find meaning, it will be tough to be happy."


I don't disagree (much), though much ado has been made over his follow up remarks...
"Is it more important to marry the woman you love? Or to love the woman you marry?"


Yeowtch. Just tone it down a notch there, fella.

Love what you do, or do what you love?

But however you take those words, one thing remains clear - loving your work has become more important than ever. A couple years back, I ruminated a little over Steve Jobs's infamous quote about loving one's work.

And now, I would like to add a little nuance to it.

Why should one love his job?

One of the most common answers would be - if you love your job, you naturally do it better. That's true enough, but that's merely the icing on the cake, not the cake itself. Also, does it naturally follow that someone who does not love his job will not be good at it?

I've heard it said that passion is part of professionalism.

Rubbish. Utter self-aggrandizing claptrap.

Professionalism is about delivering services to certain accepted standards regardless of whether one loves what he is doing or not... especially if he does not love what he is doing. Professionalism is about divorcing one's feelings from the quality of his work. Nobody is going to cut you any slack, for example, if you start writing rubbish code because your girlfriend just dumped you.

The only exception to the above rule would be artists - designers, photographers, actors - whose work requires them to pour a certain amount of their soul into it (yes, I'm being melodramatic here, deliberately so). And even then, if said professionals in those fields allow negative feelings to adversely affect their work, they're certainly not going to be earning any sympathy points.

When I say someone does not love his work, I don't necessarily mean he hates it. He could simply see it as a means to put food on the table, nothing more. If he could help it, he wouldn't do it at all. There's stuff he would much rather be doing. That does not mean someone who does not love what he does, is less professional. In fact, quite the opposite - someone who does not love what he does and yet manages to perform at consistently high levels, displays an astonishing amount of discipline and focus.

Enthusiasm isn't everything. I mean, look at me. I have enthusiasm in spades, but I suck.

That said...

There is a compelling reason to love what you do.

Automation is becoming the next big thing. Machines won't demand benefits. Machines will produce consistently with few errors. Machines don't need to be motivated. McDonald's has started replacing their human staff with self-service kiosks. Phone Support Hotlines are being replaced by pre-recorded messages. Web development work is being automated via scripts. And I'm not even going to go into factory production lines.

If you don't love your job, the danger isn't that you won't perform as well in it. Even if you are the consummate professional, the fact is that you are tolerating your job to perform as required.

Guess what will always do better than you, at tolerating your job?

Desire is irrelevant.

Remember this quote from the God-awful Terminator 3: Rise of the Machines?
John Connor: You don't want to do this!
Terminator: Desire is irrelevant. I am a machine.

Machines don't have to tolerate their job at all because machines are incapable of disliking their job. But there is a saving grace to this. Machines, by the same token, are incapable of loving their job. If you can love your job and perform better due to that love, you've just afforded yourself some immunity to the effects of automation.

Because love cannot be automated. Emotions cannot be automated. That is also why artistic industries are largely proofed against the dreaded A-word. Not because actors, musicians and sculptors are more professional. But because their output cannot be easily replicated via automation. Yet.

This blogpost was not automated.
T___T

Monday 8 May 2017

How I Learned Bootstrap (Part 2/2)


After doing the required reading on Twitter Bootstrap and getting a feel of how it was used, it didn't seem so damn hard. That was because Bootstrap is what a wheelchair is to a double amputee. You can't walk, but it will still get you from Point A to Point B by leveraging on a different set of tools, i.e, your hands. In the case of Bootstrap, the user does not have to understand Responsive Design - he just needs to leverage on HTML. The CSS files provided will do the rest.

More action

And then it was time to wade in further. Playtime was over.

Time to go deeper.

I accepted a commission from a friend to build a site. I charged him a shamefully low price for my services, but on one condition - I was to be allowed to use Twitter Bootstrap even though I had no professional experience in it. For months, I slaved over the look and feel. Money wasn't the issue here. I wanted to produce something using Bootstrap, something that would actually be put on public domain. With each UAT, each iteration, I grew stronger. Sure, I wasn't exactly becoming a guru in Responsive Design. But learning to use Twitter Bootstrap was a good first step.

And then I discovered something strange.

When I viewed the source of my HTML, it now looked suspiciously familiar. In fact, it was pretty much identical to what my colleague was doing. She had been using Bootstrap, and the clueless noob that was my CEO had bought into the narrative that this made her the expert in Responsive Design. Although at his level, I'm pretty sure it made no difference whatsoever. The end result was there.

Now, this is not meant to be a criticism of my ex-CEO. There's plenty to criticize, but that's neither here nor there. No, this is basically how the average layman thinks. They see the end result, but they're not privy to the process and they have no clue what differentiates a tool-user from a real expert. Resenting it would not make an iota of difference. Instead, I resolved to take full advantage of it.

How?

Performing "magic".

I quit my job. And then I left that company for another company full of the same clueless noobs, and presented my newfound skills in Bootstrap as mastery in Responsive Design. It worked like a charm. They had wanted Responsive Design, and what I gave them was a whole lot of shameless Bootstrapping. They never understood the difference.

Why did I quit the company?

That's the burning question. Some of my ex-colleagues, due to the timing of my departure coinciding with the promotion of my new colleague over me, thought I left out of bitterness. That's their opinion, but I think they were projecting a fair bit. I didn't care about the promotion. Being a "Senior" or a "Manager" has never mattered to me, especially when said title is being bestowed by some clueless jackass.

So why did I want to leave? After all, I'd already overcome my front-end handicap. There was no longer a need to leave, right?

Wrong.

You see, biases run deep. I had been hired by a Manager who had been on his way out. In fact, his last day was the day I joined. My new colleague had been hired by the CEO himself. When push came to shove, I knew whose side he would be on. It's just human nature.

Also, the sensation of coming in every morning to a workday filled with endless grunt work was... unpleasant. It wasn't the volume of work that I minded. It was the complexity, or lack thereof. Seriously, I was a web developer. Why would I want to spend another year coping with EDMs, writing registration forms and performing maintenance work that an intern could do? The money was good, but this was ultimately career suicide. I was a diesel truck doing the work of a horse cart.

On top of all that, was knowing that I was working for a guy who did not rate me, and was simply looking for an excuse to get rid of me. If not the front-end excuse, eventually some other thing. I could have tried harder to prove myself, but I simply did not see the need to prove myself to a dude who didn't know jackshit. What was the point?

Learning Bootstrap did not eliminate the need to leave. Rather, it facilitated my desire to leave.

The Takeaway

You may think this sounds utterly cynical, and on a certain level, it sure as hell is. But there's a lesson (or a few) to be learned in all this. Sometimes it makes no sense to beat them, when you can simply join them. The result of this was that I picked up a few new skills to add to my ever-growing toolbox.

The first, obviously, was Twitter Bootstrap.

The second, not so obviously, was that sometimes being an expert is too much work when you can just fool people into thinking you're an expert.

The third, if I do say so myself, is that I'm pretty good at turning lemons into lemonade.




I guess we could call this a... re-boot?
T___T

Saturday 6 May 2017

How I Learned Bootstrap (Part 1/2)

In recent years, I've been busy stepping up to the demands of front-end web development. With the explosion of mobile technology and all the other nifty portable tech devices, front-end has never been so hot.

But I certainly didn't just wake up one morning and decide, I am going to pick up my front-end game. No, it sparked from a certain conversation I had a couple years back, augmented with tons of soul-searching.

Here's how it began

It was 2013. I was slaving away in a media house maintaining all their websites and microsites, for a CEO who obviously felt (and had expressed his disappointment) that my skill in coding did not translate to "beautiful" interfaces. At that time, even with a working knowledge of HTML, CSS and JavaScript, I was pretty much a server-side and database guy. Most people understood that web design and web development were two different disciplines. Not this fella. For his money, he expected someone who could make stuff work, maintain his servers and make stuff look pretty.

And then he hired this girl, who actually did make stuff look pretty. The animations, colors and responsive layouts she incorporated into her work made my spartan (white background, black text) style look positively horrendous. I viewed the source of her code, and the stuff I found in there bamboozled me.

I understood then, that no matter how many deadlines I met, no matter how hard I worked, no matter how many weekends I burned, my job was in jeopardy.

Then my Manager took me aside and confirmed my suspicions. Our CEO favored his new hire, not just because she was his new hire (though that didn't hurt, I'm sure) but because she made stuff look nice and shiny. This was the media and publications industry, my Manager explained. That was just the way it was. However brilliant I thought my code was on the server, it would go unappreciated. In this business, what mattered first and foremost was appearance. Also, to a lesser extent, this reflected the worldwide trend. Server-side and back-end stuff wasn't dying, but it was certainly not growing as fast as front-end, which was really taking off at that point.

In short, I ignored the front-end portion of my web dev game at my own peril. I had neglected it for years while learning new databases and scripting languages. And now my Manager's little nudge sent me in the right direction. The writing was clear on the wall.

Time to think...

Over the course of a five-minute smoke break, I made up my mind. I would pick up my front-end game. But my time in the company was over. The CEO was merely tolerating my presence because I got shit done. Once his new hire got into the swing of things (and stopped pissing our colleagues off, but that's another story for another day), my days in the company were numbered. I would be gone faster than you could say "Hypertext Transfer Protocol".

For all my faults, and believe me there are plenty, I've never been one to outstay my welcome.

Taking that first step

There were ex-colleagues on my network. I reached out and made a few calls, asking basically the same question.

How do I improve the front-end aspect of my skillset?

Lifelines
I'm glad I was nice to my ex-colleagues back then. Because, oh boy, they really came through for me now.

Some of them gave me advice. Better, some gave me links. The common thread was bootstrapping. Using a grid system to lock the front-end into a responsive layout. And finally, my search brought me to Twitter Bootstrap. One of my ex-colleagues swore by it.

Action 

Now that I had made up my mind to learn Bootstrap in order to beef up my front-end game, the rest was easy. Well, not easy, per se, but simple enough. The direction had been settled, the immediate steps defined. Now all that was required was action.

For a couple weeks, I dedicated myself to this task. Over weekends, I read the documentation. I perused the examples, explored the links, and marveled at the results as I tried out line after line of Bootstrapped HTML. Researching something as general as Responsive Design had been intimidating. Learning Twitter Bootstrap, which was merely a tool, was a lot more manageable. There were library books. Online tutorials. For a guy who had picked up VBScript and PHP from reading a book, this was familiar ground.

Next

Details about how I cut my teeth in Bootstrap.

Tuesday 2 May 2017

The Case For Stored Procedures

I used to be a big fan of Stored Procedures. They kept me from worrying too much about SQL Injection and kept my code from getting too repetitive.

That's not to say I'm no longer a fan of Stored Procedures. I still love them, and still use them when the need arises. The thing is, I no longer overuse them. Yes, it's possible to rely too much on Stored Procedures. As I'm very fond of saying - there are no blanket solutions in this business. There's a time and place for everything. And Stored Procedures do have their place.

All the example code below is in PHP and SQLServer.

What's so special about Stored Procedures? 

Security? After all, Stored Procedures protect against SQL Injection, don't they? Yes, they do - to a point. However, parameterized queries do the same thing. In fact, the principle is exactly the same. Whether or not you use Stored Procedures, you should always use parameterized queries.

How about speed? Stored Procedures get compiled ahead of time and all that, so there's less time spent on re-parsing the query with repeated use. Well, you get pretty much the same thing with Prepared Statements.

Ease of maintenance? There's something to be said for that. Separating your logic into different tiers could accomplish that. But this is contentious. Sometimes you want all your logic to be in the same layer, ie your code.

With all of the above in mind, I'm going to outline exactly what Stored Procedures can do, that can't be done any other way.

Security 

Forget SQL Injection for a moment. What Stored Procedures do is execute queries on the tables in your database. With this, you can disable SELECT, UPDATE, DELETE access to all your tables, and grant only access to Stored Procedures. You can even specify which users get access to which Stored Procedures. This greatly limits what users can do to the database. And from a security point of view, that is unambiguously a good thing. A hacker can't simply insert an UPDATE or DELETE or even a SELECT statement into your database if all of these permissions are disabled. Only Stored Procedures are allowed, and since these Stored Procedures carry out very specific functions, they can't be used to attack your database.

Of course, if you're suicidal enough to write a Stored Procedure that drops all your tables, all bets are off.

Again, security

Look at this example...
<?php
$serverName = "serverName\sqlexpress";
$details = array( "Database"=>"dbName", "UID"=>"username", "PWD"=>"password");
$dbConn = sqlsrv_connect($serverName, $details);

$x="1";
$y="y";
$z="abc";

$strsql="UPDATE table1 SET field3 =? WHERE field1 =? AND field2=?";
$statement = sqlsrv_prepare($dbConn,$strsql,array(&$z,&$x,&$y));
sqlsrv_execute($statement);
?>

And look at this one calling a Stored Procedure. Unlike the first example, the tables and fields are not exposed to the application programmer. If you're not the database administrator, you don't know that the table you're updating is table1, or that the fields are field1, field2 and field3. You only know you're executing a Stored Procedure named sp_update!

This is excellent if you have different people working on the database and different people working on the server-side code, and want to limit knowledge of the database to a need-to-know basis.
<?php
$serverName = "serverName\sqlexpress";
$details = array( "Database"=>"dbName", "UID"=>"username", "PWD"=>"password");
$dbConn = sqlsrv_connect($serverName, $details);

$x="1";
$y="y";
$z="abc";

$strsql="CALL sp_update(?,?,?)";
$statement = sqlsrv_prepare($dbConn,$strsql,array(&$z,&$x,&$y));
sqlsrv_execute($statement);
?>

Well, if you use Stored Procedures, there's no longer a need to know.

Neatness 

Logical branching statements are possible in Stored Procedures. And this could be vital if you're a big fan of keeping your code lean. Take, for example, adding and updating a record in a table. Let's say your table named tb_students, and contains student information. Normally, one would have an UPDATE statement for updating the table and a INSERT statement for creating a record, like so. This assumes the variable id was obtained from a POST.
<?php
$serverName = "serverName\sqlexpress";
$details = array( "Database"=>"dbName", "UID"=>"username", "PWD"=>"password");
$dbConn = sqlsrv_connect($serverName, $details);

$name="John Smith";
$address="23 King George's Avenue";
$id=intval($_POST["id"]);

if (id==0)
{
    $strsql="INSERT INTO tb_students (name,address) VALUES (?,?)";
    $statement = sqlsrv_prepare($dbConn,$strsql,array(&$name,&$address));
}
else
{
    $strsql="UPDATE tb_students SET student_name =?, student_address=? WHERE student_id =?";
    $statement = sqlsrv_prepare($dbConn,$strsql,array(&$name,&$address,&$id));
}

sqlsrv_execute($statement);
?>

But wouldn't this be neater?
<?php
$serverName = "serverName\sqlexpress";
$details = array( "Database"=>"dbName", "UID"=>"username", "PWD"=>"password");
$dbConn = sqlsrv_connect($serverName, $details);

$name="John Smith";
$address="23 King George's Avenue";
$id=intval($_POST["id"]);

$strsql="CALL sp_updatestudents(?,?,?)";
$statement = sqlsrv_prepare($dbConn,$strsql,array(&$name,&$address,&$id));

sqlsrv_execute($statement);
?>

You could just call the Stored Procedure sp_updatestudents. If creating a record, just pass a "0" into the student_id field, and if updating an existing record, pass the student's id into the student_id field.
CREATE PROC [sp_updatestudents]
    @name VARCHAR(50),
    @address VARCHAR(150),
    @id INT
AS
    IF @id=0
        INSERT INTO tb_students (name,address) VALUES (@name,@address)
    ELSE
        UPDATE tb_students SET student_name =@name, student_address=@address WHERE student_id =@id;
GO

 

Portability between server-side languages 

Imagine if your code was in PHP and you wanted to make a switch to, say, C#. Hey, if your database calls were all in Stored Procedures, no problemo. Whether you're using PHP or C#, you still call the same Stored Procedure. The Stored Procedure still performs the exact same function on your database! But if your database calls were actually in the code itself, now you'd have to change all of them from PHP to C#.

Ouch.

Are Stored Procedures invincible? 

Not by a long shot. There are situations where use of Stored Procedures makes things sketchy (though we won't go into that here). But the reasons above are the strongest ones I have for using them. Your mileage may vary!

Thanks for reading. Stay tuned for the next UPDATE!
T___T