Wednesday, 27 April 2016

Programming Equivalence

Some of the most rudimentary logic in programming deals in comparison, or equivalence. For instance, every time we use an If statement, we use a conditional expression to test for equivalence. For the most part, this is pretty much a no-brainer. Consider the following in PHP.

    <?php
        $a = 5;
        $b = 3 + 2;
        echo ($a == $b ? "true" : "false");
    ?>


    true


This is true because the variable $b is set to (3+2), which is 5. The value of $a is also 5, therefore $a and $b are numerically equal.

Now consider this.
    <?php
        $a = 5;
        $b = 2.5 * 2;
        echo ($a == $b ? "true" : "false");
    ?>


    true


Again, $a and $b are numerically equal. $b is set to (2.5*2), which is 5.0, which is the numerical equivalent of $a.

Does this then follow that $a is equal to $b? Mathematically, yes. In programming parlance, no. Try the same code, with the following change.
    <?php
        $a = 5;
        $b = 2.5 * 2;
        echo ($a === $b ? "true" : "false");
    ?>


    false


The extra Equal sign

When you use the === operator rather than the == operator, you are testing for one more condition - that not only must $a and $b be numerically equivalent, they must be of the same data type. $a is 5, which is an integer. $b is 5.0, which is a floating point!

Now, how about this...
    <?php
        $a = true;
        $b = 1;
        echo ($a === $b ? "true" : "false");
    ?>


    false


$a is true, and numerically, that is 1. $b is set to the integer value of 1. Numerically they are equal, but $a is a Boolean and $b is an integer.

    <?php
        $a = intval(true);
        $b = 1;
        echo ($a === $b? "true" : "false");
    ?>


    true


The result is true. That is because $b is the integer 1. $a has been set to the integer value of true, which is 1. Therefore they are equivalent, both numerically, and in data type.

Why is this important?

If you want to compare only numerical equality, you use the == operator. And in cases where you wish to compare total equivalence, you use the === operator.

Say, for instance, you wanted to tally the items in a shopping cart. The total amount will then be processed to see if the shopper is entitled to a free gift. For arguments' sake, let's set that cut-off point at $50.00.
ItemQtyUnit PriceSubtotal
Cherries30

0.35
10.50
Oranges
10
1.00
10.00
Grapefruit
5
2.05
10.25
Peaches
15
1.55
23.25

The total is $54.00, so....
    <?php
        if ($cart_total >= 50)
        {
            echo "Congratulations! You are eligible for a mystery gift!";
        }
    ?>

See the comparison operator? It didn't rely on an extra Equal sign. That is because it doesn't matter if the total is an integer or a floating point; what we are interested in is the numerical value, and nothing else.

For a counter-example, let's take a look at PHP's search_array() function. For this, let's declare an array, $arr.
    <?php
        $arr = array("cherry", "orange", "pear", "banana");
    ?>


Now, if we were to search for "cherry" within this array, what would we get?
    <?php
        echo (array_search("cherry", $arr));
    ?>


0


We get 0 because that's the index position of "cherry" within the array $arr. But what if we wanted simply to check for the existence of "cherry"?
    <?php
        echo (array_search("cherry", $arr) == false ? "true" : "false");
    ?>


true


This is incorrect, because it is untrue that "cherry" is not found in the array $arr. The function returned an integer 0 because that is the index value of "cherry", as shown earlier. However, we used the == operator to compare it to false, which has the same numerical value as 0.

Thus, to eliminate ambiguity, we do this.
    <?php
        echo (array_search("cherry", $arr) === false ? "true" : "false");
    ?>


false


Here, we explicitly state that we're looking for a Boolean 0, not just any 0 value.

To conclude...

The extra Equal sign in PHP may cause some confusion. Hopefully, after explaining the concept of equivalence, things will be that much clearer.
Thanks very much. I cherry-sh your readership!
T___T

Saturday, 23 April 2016

Web Tutorial: Wheel of Fortune, Safari Edition

It appears that my Wheel of Fortune web tutorial met some... misfortune.

Sometime after I had released the code, I happened to test it on Safari. And this is what I got.


Oh, the horror.

Despite the fact that I had conscientiously written WebKit equivalents of the CSS classes and specifications, Safari has this bug where the overflow property does not play nice with the border-radius property. And that sucks because there are some truly interesting effects to be enjoyed when these properties are combined.

That said, I can only blame myself for not checking that the code works on Safari and Opera. Most of the time, it's Firefox and Chrome. I don't test on Internet Explorer because, well, fuck IE.

What's the Safari fix, then?

Well, I'm sure given enough time and effort, one could find a way to break through this wall. But a good developer also entertains the notion of going around this wall. Which is precisely what we're going to do today.

First, add the CSS specification for safari_fix.
            #wheel_wrapper
            {
                width:500px;
                height:500px;
                position:relative;
                margin:0px auto 400px auto;
            }

            #safari_fix
            {
                width:500px;
                height:500px;
                position:absolute;
                z-index:100;
                margin-left:-120px;
                margin-top:-120px;
                border:120px solid #000000;
                border-radius:50%;
            }


Here are what the properties do...
- width:500px, height:500px, border-radius:50%; to create a circular div the same size as the wheel_wrapper div.
- position:absolute, z-index:100 because we want to overlap wheel_wrapper.
- border: 120px solid #00000 to create a very thick black border around the div. Why black? That's so you can see it better.
- margin-left and margin-top properties have been set to -120px in order to offset the positioning effects of having a 120 pixel-wide border.

Now create a div with the id safari_fix and put in inside wheel_wrapper.
        <div id="wheel_wrapper">
            <div id="safari_fix">
       
            </div>   
            <div class="semicircle_wrapper wheel2">
                <div class="segment_wrapper semicircle2">
                    <div class="segment7 segment">


Here's what you should have. A huge black God-awful ugly border around your wheel, hiding all the even uglier jagged corners. Try your code. Make sure everything works.



Now change the border color to match your background.
            #safari_fix
            {
                width:500px;
                height:500px;
                position:absolute;
                z-index:100;
                margin-left:-120px;
                margin-top:-120px;
                border:120px solid #FFFFFF;
                border-radius:50%;
            }


Voila! A cheap and dirty fix for Safari.



Not the best solution, but...

Yep, this is not the most elegant solution you could have. If you ever change the background color, you'll have to change the color of the border of your safari_fix div as well. But if it works, it works. Until I have a better solution, this stays.

Seeya around,
T___T

Sunday, 17 April 2016

The Importance of Placeholders (Part 2/2)

We've just covered placeholders in scripting code. Now it's time for...

Placeholders for the Front-end

When you're working on layout, you're going to find yourself refreshing your browser over and over again till you get it just right. That's, rather unfortunately, unavoidable. But you can save yourself approximately three-quarters of the hassle.

Not all of your content is going to be in one place. Sure, they'll be on the same page, but scattered throughout different sections. And of course, you'll want to ensure that they fit together nicely, or at least according to specifications. You'll be able to do this a lot more effectively, by applying placeholders.

Consider the HTML layout below. I'm going to simulate creating a Liverpool FC fan site. You have dummy text where the content is, just so you can figure out how everything should look like.

<!DOCTYPE html>
<html>
    <head>
        <title>Placeholder Test</title>
    </head>

    <body>
        <div id="container">
            <div id="header">
                <div id="header_logo" class="left">
                  
                </div>
                <div id="header_title" class="right">

                </div>
            </div>

            <div id="subtitle">
                You'll Never Walk Alone
            </div>

            <div id="navbar">
                <ul>
                    <li>About Us</li>
                    <li>Team of 2015/2016</li>
                    <li>Fixtures</li>
                    <li>News</li>
                    <li>Contact</li>
                </ul>
            </div>

            <div class="sidebar left">
                Mauris sollicitudin porttitor nibh ut tincidunt. Donec a elementum elit. Pellentesque

enim lacus, sollicitudin vitae luctus quis, interdum sit amet massa. Nunc commodo urna quis ex ornare posuere. Sed a

pellentesque nisl. Sed ut nibh dignissim augue pellentesque laoreet vitae et metus. Nam vulputate finibus accumsan.

Phasellus dui quam, molestie at elementum a, rutrum at mi. Sed leo metus, gravida vitae sagittis pretium, lacinia eget

massa. Nulla mattis nibh ut viverra placerat. Suspendisse fermentum ornare sem eu auctor. Donec finibus vestibulum

tortor, non tincidunt dolor vulputate iaculis. Praesent volutpat urna sit amet augue gravida mattis.
            </div>

            <div class="content left">
                <div id="content_article">
                    <h1>Article title</h1>
                    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed nec ex vel enim

volutpat euismod. Duis bibendum pretium nunc, ac porta arcu posuere at. </p>
                    <p>Aliquam erat volutpat. Cras porta metus sed venenatis consequat. Aenean

tristique, leo vel pulvinar elementum, nisi est porta eros, vel interdum dolor lorem quis lacus. Nam quis bibendum erat.

Nunc quis felis gravida, sodales eros sit amet, blandit mauris. </p>
                    <p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac

turpis egestas. Nunc sit amet lobortis odio, nec venenatis justo. Morbi id quam massa.</p>
                </div>
                <div class="content_gallery left" style="background:url(http://2.bp.blogspot.com/-

1oo7CPOixIU/VTIZZFvCPBI/AAAAAAAAAhM/qjLBTa2W1Ps/s1600/covercontain01.jpg) center center no-repeat;background-

size:cover;">

                </div>
                <div class="content_gallery left" style="background:url(http://3.bp.blogspot.com/-

7nLyedwne-E/VTIZZIGUtSI/AAAAAAAAAhI/0exuMK92Sz0/s1600/covercontain02.jpg) center center no-repeat;background-

size:cover;">

                </div>
                <div class="content_gallery left" style="background:url(http://3.bp.blogspot.com/--

No09xO9fvA/VTIZZ4qoL_I/AAAAAAAAAiA/jC5yQujsB9w/s1600/covercontain03.jpg) center center no-repeat;background-size:cover;">

                </div>
                <div class="content_gallery left" style="background:url(http://4.bp.blogspot.com/-

8k81q55TDio/VTIZaMa-SLI/AAAAAAAAAhY/XKwJTweBaBA/s1600/covercontain04.jpg) center center no-repeat;background-

size:cover;">

                </div>
            </div>

            <div class="sidebar right">
                Vestibulum nisi enim, tempus lobortis elit in, aliquet consectetur dui. Cras cursus arcu

et ante ullamcorper, eu posuere diam dapibus. Praesent tristique consequat tincidunt. Etiam nec ex sed augue euismod

consectetur quis eget nisi. Quisque eu diam id est tempor consectetur. Pellentesque at tortor ultricies eros dignissim

fringilla. Nulla posuere nisl dui, id iaculis ante dignissim et. Nam malesuada diam augue, id elementum nibh laoreet ac.

Nulla ut odio a dui dapibus egestas id a leo.               
            </div>


            <div id="footer">
                footer text
            </div>
        </div>
    </body>
</html>


Perhaps your CSS code looks roughly like this. This is not a web tutorial, so I've not going to bother making things readable. The CSS is not the point here.
        <style type="text/css">
            body{background-color:#AA2222;}
            #container{width:900px;height:auto;margin:0px auto 0px auto;background-color:#FFFFFF;padding:5px}
            #header{width:100%;height:auto;}          
            #header_logo{width:150px;height:150px;background:url(http://3.bp.blogspot.com/-

a3hUPxlx2lw/VTIeXF-_JhI/AAAAAAAAAic/bjXKaOWHVQY/s1600/logo_liverpool.jpg) center center no-repeat;background-

size:contain;}
            #header_title{width:740px;height:150px;background:url(http://4.bp.blogspot.com/-rpU-

gahiQ0M/VTIZZJQVjZI/AAAAAAAAAhQ/bbaWuD2-9ZM/s1600/covercontain00.jpg) center center no-repeat;background-size:cover;}
            #subtitle{width:100%;height:50px;text-align:center;}
            #navbar{width:100%;height:50px;}
            #navbar ul li {width:150px;height:40px display:block;float:left;background-

color:#440000;color:#FFFFFF;text-align:center;margin:2px;}
            .sidebar{width:200px;height:auto;}
            .content{width:460px;height:auto;margin-left:5px;padding:5px;}

            .left{float:left;}
            .right {float:right;}
            .content_gallery{width:100px;height:100px;margin-right:5px}
            #footer{width:100%;height:150px;margin-top:50px;}
        </style>


And now your layout looks like this.



But how do you know you have it right? It looks like a mess right now. Remember, you're going to have to test it out on different browsers and screen sizes. This is hard enough as it is. Time to make it easier!

Add this to your CSS code.
        <style type="text/css">
            div{border:1px solid #FF0000;}
            body{background-color:#AA2222;}
            #container{width:900px;height:auto;margin:0px auto 0px auto;background-color:#FFFFFF;padding:5px}
            #header{width:100%;height:auto;}          
            #header_logo{width:150px;height:150px;background:url(http://3.bp.blogspot.com/-

a3hUPxlx2lw/VTIeXF-_JhI/AAAAAAAAAic/bjXKaOWHVQY/s1600/logo_liverpool.jpg) center center no-repeat;background-

size:contain;}
            #header_title{width:740px;height:150px;background:url(http://4.bp.blogspot.com/-rpU-

gahiQ0M/VTIZZJQVjZI/AAAAAAAAAhQ/bbaWuD2-9ZM/s1600/covercontain00.jpg) center center no-repeat;background-size:cover;}
            #subtitle{width:100%;height:50px;text-align:center;}
            #navbar{width:100%;height:50px;}
            #navbar ul li {width:150px;height:40px display:block;float:left;background-

color:#440000;color:#FFFFFF;text-align:center;margin:2px;}
            .sidebar{width:200px;height:auto;}
            .content{width:460px;height:auto;margin-left:5px;padding:5px;}

            .left{float:left;}
            .right {float:right;}
            .content_gallery{width:100px;height:100px;margin-right:5px}
            #footer{width:100%;height:150px;margin-top:50px;}
        </style>


See what we did there? We just specified that every div is going to have a red border. Now refresh your browser.



Look at this and tell me it doesn't make your life a whole lot easier. Now you have a visual aid, like a wireframe, to help you as you make the necessary adjustments. You can tell where the code needs to be adjusted.

The "You'll Never Walk Alone" text is mixed into the navbar because the header's width isn't well-defined. The footer text runs all the way to the top because there's no break after the middle content.

In fact, let's make these adjustments right now.
<html>
    <head>
        <title>Wheel</title>

        <style type="text/css">
            div{border:1px solid #FF0000}
            body{background-color:#AA2222;}
            #container{width:900px;height:auto;margin:0px auto 0px auto;background-color:#FFFFFF;padding:5px}
            #header{width:100%;height:160px;}          
            #header_logo{width:150px;height:150px;background:url(http://3.bp.blogspot.com/-

a3hUPxlx2lw/VTIeXF-_JhI/AAAAAAAAAic/bjXKaOWHVQY/s1600/logo_liverpool.jpg) center center no-repeat;background-

size:contain;}
            #header_title{width:740px;height:150px;background:url(http://4.bp.blogspot.com/-rpU-

gahiQ0M/VTIZZJQVjZI/AAAAAAAAAhQ/bbaWuD2-9ZM/s1600/covercontain00.jpg) center center no-repeat;background-size:cover;}
            #subtitle{width:100%;height:50px;text-align:center;}
            #navbar{width:100%;height:50px;}
            #navbar ul li {width:150px;height:40px display:block;float:left;background-

color:#440000;color:#FFFFFF;text-align:center;margin:2px;}
            .sidebar{width:200px;height:auto;}
            .content{width:460px;height:auto;margin-left:5px;padding:5px;}

            .left{float:left;}
            .right {float:right;}
            .content_gallery{width:100px;height:100px;margin-right:5px}
            #footer{width:100%;height:150px;margin-top:50px;}
        </style>


    </head>

    <body>
        <div id="container">
            <div id="header">
                <div id="header_logo" class="left">
                  
                </div>
                <div id="header_title" class="right">

                </div>
            </div>

            <div id="subtitle">
                You'll Never Walk Alone
            </div>

            <div id="navbar">
                <ul>
                    <li>About Us</li>
                    <li>Team of 2015/2016</li>
                    <li>Fixtures</li>
                    <li>News</li>
                    <li>Contact</li>
                </ul>
            </div>

            <div class="sidebar left">
                Mauris sollicitudin porttitor nibh ut tincidunt. Donec a elementum elit. Pellentesque

enim lacus, sollicitudin vitae luctus quis, interdum sit amet massa. Nunc commodo urna quis ex ornare posuere. Sed a

pellentesque nisl. Sed ut nibh dignissim augue pellentesque laoreet vitae et metus. Nam vulputate finibus accumsan.

Phasellus dui quam, molestie at elementum a, rutrum at mi. Sed leo metus, gravida vitae sagittis pretium, lacinia eget

massa. Nulla mattis nibh ut viverra placerat. Suspendisse fermentum ornare sem eu auctor. Donec finibus vestibulum

tortor, non tincidunt dolor vulputate iaculis. Praesent volutpat urna sit amet augue gravida mattis.
            </div>

            <div class="content left">
                <div id="content_article">
                    <h1>Article title</h1>
                    <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed nec ex vel enim

volutpat euismod. Duis bibendum pretium nunc, ac porta arcu posuere at. </p>
                    <p>Aliquam erat volutpat. Cras porta metus sed venenatis consequat. Aenean

tristique, leo vel pulvinar elementum, nisi est porta eros, vel interdum dolor lorem quis lacus. Nam quis bibendum erat.

Nunc quis felis gravida, sodales eros sit amet, blandit mauris. </p>
                    <p>Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac

turpis egestas. Nunc sit amet lobortis odio, nec venenatis justo. Morbi id quam massa.</p>
                </div>
                <div class="content_gallery left" style="background:url(http://2.bp.blogspot.com/-

1oo7CPOixIU/VTIZZFvCPBI/AAAAAAAAAhM/qjLBTa2W1Ps/s1600/covercontain01.jpg) center center no-repeat;background-

size:cover;">

                </div>
                <div class="content_gallery left" style="background:url(http://3.bp.blogspot.com/-

7nLyedwne-E/VTIZZIGUtSI/AAAAAAAAAhI/0exuMK92Sz0/s1600/covercontain02.jpg) center center no-repeat;background-

size:cover;">

                </div>
                <div class="content_gallery left" style="background:url(http://3.bp.blogspot.com/--

No09xO9fvA/VTIZZ4qoL_I/AAAAAAAAAiA/jC5yQujsB9w/s1600/covercontain03.jpg) center center no-repeat;background-size:cover;">

                </div>
                <div class="content_gallery left" style="background:url(http://4.bp.blogspot.com/-

8k81q55TDio/VTIZaMa-SLI/AAAAAAAAAhY/XKwJTweBaBA/s1600/covercontain04.jpg) center center no-repeat;background-

size:cover;">

                </div>
            </div>

            <div class="sidebar right">
                Vestibulum nisi enim, tempus lobortis elit in, aliquet consectetur dui. Cras cursus arcu

et ante ullamcorper, eu posuere diam dapibus. Praesent tristique consequat tincidunt. Etiam nec ex sed augue euismod

consectetur quis eget nisi. Quisque eu diam id est tempor consectetur. Pellentesque at tortor ultricies eros dignissim

fringilla. Nulla posuere nisl dui, id iaculis ante dignissim et. Nam malesuada diam augue, id elementum nibh laoreet ac.

Nulla ut odio a dui dapibus egestas id a leo.               
            </div>

            <br style="clear:both">

            <div id="footer">
                footer text
            </div>
        </div>
    </body>
</html>

See that? Wunderbar!


Now remove the red borders... and there you go. Not perfect by a long shot, but a hell of a lot easier on the eyes now! From here, you can make further adjustments till yor layout is exactly what you want. If need be, bring the red borders back.


Another hack

Alternatively, do this.
div{background-color:rgba(255,0,0,0.2);}

This changes the background of all your divs to a transucent red. Useful for when you have a lot of nested divs.

 

Know your place(holders)!

That's the principle behind what we're doing. Placeholders for code, so you know what that segment is supposed to do. Placeholders for layout, so you know where your stuff overlaps and where it stops. None of it is rocket science, just applied common sense. They probably don't teach you this in school. In fact, you probably would have figured it out all by yourself after a while.

Have a nice day. Don't get too bordered by the specifics.
T___T

Thursday, 14 April 2016

The Importance of Placeholders (Part 1/2)

How's the week been so far? Hectic, I bet. Here's a handy hack to keep your sanity - placeholders.

Placeholders are visual aids, with a wide variety of implementations. As it's more of a concept than an actual official feature, you don't really need to know about placeholders in order to be in web development. But boy, do they help. In every aspect of the job.

Implementing placeholders in the back-end

Sometimes the project gets too big. You lose track of all the little things you have to do in order for it to work. So, in order not to end up being bogged down by minutia, especially if the piece of code you're planning to write is really long, you'll need to step back and look at the big picture.

Big picture moment, yo.

Let's say, for example, you are writing a login procedure. You have the front-end, which is essentially a login text field, a password text field, and a submit button. Your work at the back-end is pending - you of course need to check for an existing login/password match, and then if there's a match, you need to check the user's access rights. Superadmins have access to everything and have no expiration date. Admins have access to certain areas outside of normal access and have no expiration date. Normal users have access only to a limited set of features and have an expiration date - if that expiration date has arrived, they are not automatically logged out.

Sound like a lot? Hell no, it's a pittance! I've deliberately scaled this down for ease of explanation.

Now, how should we approach this? Just wade in and start coding? Dear me, no. You'd be making things hell of a lot easier on yourself if you divided and conquered. I'm not even talking about Object-oriented Programming here. Just use comments judiciously to provide placeholders for each segment, like so.

//BEGIN get login variables
//---
//END get login variables

//BEGIN check existing login/password
//---
//END check existing login/password

//BEGIN check user type

   //BEGIN superadmin
   //---(display superadmin links)
   //END superadmin


   //BEGIN admin

      //BEGIN check access rights
      //---(display links according to access rights)
      //END check access rights
  
   //END admin

   //BEGIN user
      //BEGIN check expiration
      //---(log user out if account expired)
      //END check expiration
   //END user

//END check user type

//BEGIN display normal user links
//---
//END display normal user links


So, where it says //---, you just substitute that with whatever code you need to write.

This will add a whole lot more lines to your code, but you'll be able to leave anytime, return and see what you've missed out! Also, segmenting it this way allows you to divide your procedural code into logical blocks.

No, this is not some super-genius hack for enterprise level programming. In fact, if you were a super-genius, you probably would have enough intellectual capacity and brainpower to not bother at all. For the rest of us mere mortals, this is a nice lifehack.

Next

Placeholders for the front-end! Same concept, vastly different implementation.

Friday, 8 April 2016

The Development Process - Are you Engine Grease or a Spanner?

Taking ownership of a project - at times it seems to mean different things to different people. When your manager tells you he wants you to "take ownership", in all likelihood, he doesn't mean it literally. The work you do is on your company's equipment. And therefore, by the terms of your employment contract, whatever work you do on it belongs to the company. There is zero ambiguity there. What your manager means is that he wants you, as the developer, to take responsibility for the project, do your due diligence, and for all intents and purposes, treat it like your baby.

That sounds straightforward enough. Take your job seriously. As professionals, we can do no less. We have to do what we feel is in the best interests of the project. Which means exercising best practices, writing the best code you know, and making the best decisions possible under the circumstances.

The "best" here is a sticking point because best practices are situation-dependent. There are situations where what's considered a "best practice" elsewhere is a nuisance and waste of time here (Like SEO for a data management system. Or anti-XSS safeguards for a static site...). And of course, we have to consider the fact that clients and higher management have a very different view of web development. It's not necessarily a wrong view, but the business perspective markedly differs from the technical one. Even discounting that, sometimes technical professionals have different preferences where implementation is concerned. And it's usually a good thing to discuss, debate and come to a consensus. But where does one draw the line? When do you reach a point where you say - enough is enough, let's put it to a vote and get on with it? Where the development process is concerned, are you engine grease or a spanner?

A couple years back, I was an in-house web developer in a small department within the company. I reported to a manager and worked alongside a few other colleagues. There was one that stood out, in particular. Not because she was ugly, because from an objective point of view she really looked all right. Not because she was bitchy, because, credit where it's due, she did make an effort to be nice. But because she was a massive pain in the ass to work with.

Ouch.

An early example

Picture our manager holding a small team meeting. There were a few projects on hand that the team needed to produce, and we were discussing specifications. Our manager was saying how she planned for the project to be coded the traditional "procedural" way when my colleague raised an objection. No, she declared, there was no way she would agree that the project not be coded in her framework of choice. And of course, there was the obligatory back-and-forth about the pros and cons of a framework-coded project vs a traditional approach. I had zero problem with that. My manager had her say, my colleague had her say. Everything was cool, right?

Not so.

My colleague argued her case vehemently and it was quite apparent that there would be no compromise. It must be coded in an MVC framework. She was adamant about it. I almost expected her to start stamping her feet for emphasis. My manager, tactfully, moved on, but I could tell she was perturbed. After all, she was the manager, for goodness sake. She was the one who would be held accountable if the project tanked. Granted, it was our duty as her colleagues and subordinates to point out any potential pitfalls, but shouldn't she have the final say? On my part, I was appalled, but I kept my peace. This wasn't my fight.

A mystifying question

Months later, our manager got transferred. This troublesome colleague got promoted.

After her promotion, my new manager wasted little time getting me alone for a 1-on-1. And she laid a real beauty of a question on me.

"Do you have any problem with the fact that I got promoted despite the fact that you're older and more experienced?"

I was honestly baffled by this. Seriously? This was taking insecurity to ridiculous levels. I was not going to dig my heels in and refuse to budge just because I think she had her head up her ass. That would be unprofessional, prima donna behavior.

This is how I see it - the company pays me for my cooperation, and thus my cooperation is assured. Same for clients. If I think the client's requirements are not in the best interests of the project, it is my professional duty - no, obligation - to advise accordingly. But that is as far as it goes. Because however much I take "ownership" of the project, ultimately it's not my project, and it's not about my satisfaction. Every professional needs to take a certain amount of pride in their work, but they should never let their ego get in the way of delivery. At the end of the day, delivery - to client specifications, of course - is what counts. You can have the most technically solid product in the world, but if it expressedly goes against client requirements and you're unable to get the client to sign off on it as a result, you have a big fat zero.

Be reasonable - do it my way.

This is not to say that I will automatically agree with everything. If I have reservations about what's required of me, I will voice them. But I will voice them only once. And after my objections have been filed for the record, it is time to STFU, roll up my sleeves and get cracking.

Many people think that professionalism is about excellence. They're not wrong. But it is also about compliance. Compliance to standards, compliance to procedures, sure. But most importantly, compliance to product specifications. Because if this is not met, the other two no longer matter. Therefore, if the client wants a piece of shit, he is going to get a piece of shit. In fact, he is going to get a magnificent steaming pile of excrement. And I will gladly take a long piss over that pile of excrement, just to give him his money's worth.  This is not about how much better I can do, or how superior my knowledge is to the customer's. In fact, this is not about me, period. It is about delivering what I'm paid to deliver.

Where's your professional dignity, man?

That is my brand of professionalism - pragmatic, un-fancy, and utterly workman-like. It's all well and good to have principles. But the one principle that should receive top billing is - Get. The. Fucking. Job. Done.

Be engine grease, don't be a spanner - be a lubricant, don't be a tool.
T___T

Friday, 1 April 2016

YOLO

Happy April Fool's!

It was with a certain amount of wry amusement when I read this article recently from Fortune.

In it, the author takes us through his year at tech startup HubSpot, run by New Age-y Millennials. My amusement faded somewhat when I considered the implications. True, this was a somewhat ramped-up depiction of events (I hope), but undeniably this is how Millennials tend to be perceived - seeking change for the sake of change, being different for the sake of being different and trying too damn hard to be special.

I cop to a fair bit of sympathy on that score. While I am currently pushing 40 and therefore out of the defined range of the term "Millennial", I've often fallen foul of the abovementioned perception by association. While my younger friends, the true Millennials, consider me an old-fashioned stick-in-the-mud with old-school ideals; my older pals from the Generation X tend to see me as a feckless and impulsive punk. I've been on the receiving end of the "I'm older (by a few years, go figure) therefore I know better" horsecrap, and put up with many a diatribe about "these youngsters nowadays", or "in our day...".

Still, all was well until I read this piece from the New York Times. And man, did I cringe at the depiction of Millennials in it - self-centered, irresponsible and shallow. The earlier article didn't seem quite so funny any more.

Any traces of amusement that remained were thoroughly wiped out when UOB launched its newest card late last month, a couple days ago.

YOLO, yo.


The YOLO card. Shiver me timbers. Which idiot came up with that, and what was he or she smoking at the time?

YOLO, if you've been living under a rock for the past decade, is an acronym for the term "You Only Live Once", a philosophy that encourages one to throw caution to the wind and embark on outrageous adventures. UOB was using this buzzword to target Millennials.

Not that I fault them for targeting Millennials - it's a sound business decision and I like the direction they've taken the design. But boy, did the term "YOLO" smack of condescension. Well done, UOB. In one sweeping gesture, you've lumped all individuals of that age group under the negative stereotype of reckless thrillseeking hedonists. What's arguably more insulting is that UOB seems to believe throwing some hip-sounding, douchebaggy marketing catchphrase at the card is going to draw these Millennials like flies to honey. Just how stupid do they think Millennials are, anyway?

Let me be clear here that I think Millennials have been given a bad rap, rather unfairly so. I've worked with, and for, Millennials who struck me as sensible people with good ideas. True, I've had my problems with some of them, but those problems were a product of personality, rather than age. I've had similar problems with older employers and colleagues. And true, their thinking isn't always in line with old-school tradition, but why the hell should it be? This is an evolving world, and when you live in an evolving world, you evolve or perish. Tradition, like most things, has its place. More importantly, tradition must know its place.

I'm also getting a wee bit tired of the smug, self-congratulatory assumption that young people today have it too easy and aren't built with the same resilience as the older generation. Sure, many of the twenty-somethings out there are aimless and prone to instant gratification. And I suppose those in the Generation X had life figured out by the time they turned 25? Cut me a fucking break. If you can claim that you have life figured out, the only thing certain is that you haven't got jackshit figured out. Most of us, regardless of generation, figured life out step by step, mistake by mistake, all the while chafing under our know-it-all elders.

The entire exercise of putting Millennials down, reeks of desperation - desperation of my fellow Gen X alumni to feel good about themselves at the expense of an entire younger generation. Come on, Gen X. You're better than this. This stereotype needs to die. Pronto.

Give the Millennials some credit, won't you?
T___T