Saturday 22 November 2014

Sugar's Job Ad - Not So Sweet

Sugar Technologies released a job advertisement in September 2014, looking for a Lead Software Engineer.

Much has been said about the ad, and of Sugar Technologies, mostly uncomplimentary. I had meant to add my two cents last month, but I didn't have a blog then. Ah, but I do have a blog now.

The ad has been reworded slightly since then, so I point you to the exhibit below:

Click to enlarge!

Sugar Technologies has since released a clarification and one of its interns, Asyraf Aliman, has also released a post in defense.

Unlike many of the comments posted, I do not consider the ad discriminatory, nor do I necessarily think that Sugar Technologies would be a bad place to work, under the right circumstances. Yes, Sugar Technologies should not be judged by its job ad. That's akin to saying that a prospective employee should not be judged by his resume, an assertion I don't wholly disagree with either. From the picture painted by Sugar Technologies and its intern, Sugar Technologies seems to be a fun place to pick up valuable professional experience, and is not the draconian hotbed of slavery depicted by the job ad. I'm inclined to give them the benefit of the doubt.

However, the subject under discussion is not Sugar Technologies, nor am I attempting to judge them based on one job ad. My issue is with the job ad itself.

The author was obviously trying to be different and original. Quirky? Perhaps. Edgy? Debatable. I think a more appropriate term would be immature and unprofessional.

And utterly, appallingly stupid.

How else would one describe an ad which uses such a condescending tone which effectively alienates its target audience - the developers? Consider the excerpt below:


Who We Want:
  • You are ambitious, intense and entrepreneurial, and you dream of doing truly epic shit with your life. You recoil at the thought of having 1.15 kids, balloting for a flat, saving up for a Toyota and waiting to withdraw your CPF savings at 65 (or 70, or 80, or 120).
Who We Don't Want:
  • You are a shallow social climber whose dream is to work for Goldman Sachs because it "looks good on your CV". You went to an Ivy League university because it would "look good on your CV". But you couldn't get into Goldman Sachs (or Citibank, or HSBC) because you actually have no passion for finance, just like how you want to buy that Louis Vuitton bag (because it will "look good on your social CV") despite having no passion for design and craftsmanship. Guess what? If you were rejected by Goldman Sachs, you will be rejected by us too. For exactly the same reasons. Advice: try applying for a government job.
  • You are a social misfit. You like technology only because you can't relate to real people. You spend your weekends playing DOTA and in your sleep you dream about your hero reaching Level 38. At school, you were always the last to get picked on any project or sports team. Having a conversation with you is about as interesting as watching paint dry. Advice: go seek help from a mental health professional.

Perhaps the author felt that those turned off by this segment would be "shallow social climbers" whom the company doesn't really need. Surprise - I am pretty much the kind of person who should identify with the ad.
  • I like kids only when they're not my own.
  • I consider cars overrated.
  • I've toiled almost exclusively for small unglamorous startups that worked me more than 12 hours a day. And moving up that corporate or social ladder isn't my priority - improving as a developer is. Because I went through a lot to become a web developer - and you will take it only from my cold, dead hands.
  • I've rarely been in the position to push the blame to anyone. The companies I worked for were so small that I was the beginning, middle and end of the assembly line. I was the whole fucking assembly line.
  • And I don't game. My weekends are spent doing housework, playing with code and hitting the swimming pool. I'm willing to bet that my mental health is excellent, thanks very much.

But no. While I'm not responding with as much vitriol as some comments posted online, I'm not so much angry as disgusted.

Yes, I've worked long extra hours to get things done. Without thought of recognition or reward. Because the act, in itself, was a reward. Because I love what I do.

But my employer is not entitled to benefit from that love. My employer is only entitled to what he pays me to do, and anything beyond that is mine to give.

Yes, I think marriage is one of the most horrifying institutions known to mankind. And I think having a job that does not stretch me in the slightest, where I can just coast to the day I collect my pension, is long slow career suicide. And I feel that it's no way to live.

But I do not judge people who want those things. I do not call them "shallow social climbers" or "social misfits". Not anymore, at least.

People want what they want. That's all there is to it. On my part, I just want to code and be paid for it, and if you have a problem with that, do us all a favor and go jump off Benjamin Sheares Bridge or something.

The smug and condescending tone of the job ad rankles, and for good reason. I have had people, with wife and kids in tow, smugly pointing to their "success" and asking me when I'm ready to settle down. As though not wanting what they achieved somehow means I'm deficient in some way. And I have been equally snarky in the past, wondering aloud, to their faces, why they're so proud of the fact that they have a spouse and kids just like almost every other schmuck on this island.

I encountered arrogance, and I responded with arrogance. If it's something a Teochew is good at, it's being cocky. But that was immature of me. And precisely because I've been immature before, I recognize immaturity when I see it. That job ad screamed immaturity. In spades.

On their statement, Sugar Technologies had this to say:

Firstly, we fully understand and acknowledge that working at a tech start-up is not for everyone. The majority of job-seekers desire stability, security, structure and consistency, and like many tech start-ups, we are not able to provide this. Given the nature of what we do, we require our employees to be comfortable with a certain degree of chaos and uncertainty.

Then why, oh why, didn't they say this from the start instead of trying to be cute in their job ad? Sugar Technologies is a tech start-up. One of several hundreds (probably thousands) on this island. With one cool (and hopefully original or at least superior) Mobile App idea they're riding on. Don't put on airs. It's just silly.

To conclude, and to reiterate, Sugar Technologies is not being discriminatory with the job ad. Sugar Technologies is perfectly within their legal rights. Ethically, they are blameless. Someone just got a little carried with the fancy wording on their job ad, that's all.

Guess it's true what they say -  advert-sity breeds character!
T___T

Friday 14 November 2014

Web Tutorial: The Wayang Progress Bar (Part 4/4)

We've reached the last part of this web tutorial, and in this one, we're going to make your Wayang Progress Bar load more realistically.

Realistic how?

Well, take a look at your bar. It moves very predictably. One pixel at a time, one percentage at a time, just as it's programmed to in the JavaScript. But in real situations, the page doesn't load like that. Sometimes it loads some things faster, sometimes it takes more time with other components. To simulate that, we're going to add a random element to your animation.

Change the following line in the process_loader() function of your JavaScript:
                function process_loader(varloadercontent)
                {
                    var inc=Math.floor((Math.random() * 50) + 1);
                    var marginleft = document.getElementById(varloadercontent).style.marginLeft;
                    marginleft=marginleft.replace("px","");
                    marginleft=parseInt(marginleft)+inc;

                    if (marginleft>=0)
                    {
                        document.getElementById(varloadercontent).style.marginLeft="-5px";
                        document.getElementById(varloadercontent+"_text").innerHTML="Loading 95%"+dots;
                    }
                    else
                    {

                        var percent=(((500+marginleft)/500)*100).toFixed(0);
                        document.getElementById(varloadercontent+"_text").innerHTML="Loading "+percent+"%"+dots;
                        document.getElementById(varloadercontent).style.marginLeft=marginleft+"px";
                    }
                }

Now reload. What do you see? Your progress bar now loads unpredictably. Sometimes it goes faster, and sometimes it goes slower. That's because the inc variable was originally set to 1. So your bar moved one pixel at a time. With this change, you've basically told your JavaScript to move the bar one to fifty pixels each time!

For more about JavaScript random number functions, click here. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random

Final touch!

Now for the next bit of fun. Do you feel that your bar is moving a little jerkily? It probably wasn't obvious when it was moving one pixel at a time, but now that it surges forward up to fifty pixels any time, you can see it.

So let's smoothen the animation a bit. Add these lines to your CSS.
            .loader_content
            {
                width: 500px;
                height: 20px;
                background: #ff4444; /* Old browsers */
                background: -moz-linear-gradient(top, #ff4444 0%, #ff9e9e 52%, #ff4444 100%); /* FF3.6+ */
                background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#ff4444), color-stop(52%,#ff9e9e), color-stop(100%,#ff4444)); /* Chrome,Safari4+ */
                background: -webkit-linear-gradient(top, #ff4444 0%,#ff9e9e 52%,#ff4444 100%); /* Chrome10+,Safari5.1+ */
                background: -o-linear-gradient(top, #ff4444 0%,#ff9e9e 52%,#ff4444 100%); /* Opera 11.10+ */
                background: -ms-linear-gradient(top, #ff4444 0%,#ff9e9e 52%,#ff4444 100%); /* IE10+ */
                background: linear-gradient(to bottom, #ff4444 0%,#ff9e9e 52%,#ff4444 100%); /* W3C */
                filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ff4444', endColorstr='#ff4444',GradientType=0 ); /* IE6-9 */
                transition: margin-left 1s;
  
            }

What we've done here is to tell your browser to render the changes incrementally over the space of one second, instead of moving your bar immediately. See what a difference this makes?

Here's an excellent tutorial on CSS3 Transitions. http://www.w3schools.com/css/css3_transitions.asp

And we're done!

The Wayang Progress Loader is meant for those situations where your HTML page is loading slowly (due to an image-intensive gallery or a very long-winded article) and you need the user to be patient.

Couldn't I just have done this in jQuery?

Dear Lord, please tell me you're joking. Of course you could have done it in jQuery or Mootools. But to load the jQuery library just to produce a simple piece of code like this? That's excessive. And nowhere as fun. Sure, you could have pulled this out of jQuery's long list of functions and utilities. But it would have saved you a couple minutes at best, and it isn't the same as knowing how to do it yourself.


Keep it real,
T___T

Wednesday 12 November 2014

Web Tutorial: The Wayang Progress Bar (Part 3/4)

So now you have a working Wayang Progress Bar. (Hey it works, OK? Just not the way the typical user thinks it works.) What's next?

Numerical representation!

But why? I hear you wail. Well, some people just wanna watch the world burn need to see figures. Trust me, it adds value to your wayang.

So make the following changes to your code - CSS, JavaScript, HTML.
<!DOCTYPE html>
<html>
    <head>
        <title>Progress Loader test</title>
        <style type="text/css">
            .loader_box
            {
                width: 500px;
                height: 20px;
                border: 1px solid #777777;
                border-radius: 9px;
                overflow: hidden;
                margin-left: auto;
                margin-right: auto;
            }

            .loader_content
            {
                width: 500px;
                height: 20px;
                background: #ff4444; /* Old browsers */
                background: -moz-linear-gradient(top, #ff4444 0%, #ff9e9e 52%, #ff4444 100%); /* FF3.6+ */
                background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#ff4444), color-stop(52%,#ff9e9e), color-stop(100%,#ff4444)); /* Chrome,Safari4+ */
                background: -webkit-linear-gradient(top, #ff4444 0%,#ff9e9e 52%,#ff4444 100%); /* Chrome10+,Safari5.1+ */
                background: -o-linear-gradient(top, #ff4444 0%,#ff9e9e 52%,#ff4444 100%); /* Opera 11.10+ */
                background: -ms-linear-gradient(top, #ff4444 0%,#ff9e9e 52%,#ff4444 100%); /* IE10+ */
                background: linear-gradient(to bottom, #ff4444 0%,#ff9e9e 52%,#ff4444 100%); /* W3C */
                filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ff4444', endColorstr='#ff4444',GradientType=0 ); /* IE6-9 */           
            }

            .loader_wrapper
            {
                width: 100%;
                height: 100%;
                background: rgba(0,0,0,0.8);
                position: fixed;
                z-index: 600;
                top: 0px;
                left: 0px;
                padding-top: 50px;
                display: none;     
            }

            .loader_text
            {
                width: 500px;
                height: 20px;
                text-align: center;
                font-size: 14px;
                font-family: arial;
                color: #FFFFFF;

                margin-left: auto;
                margin-right: auto;
            }
        </style>

        <script>
            var loader;
            dots=".&nbsp;&nbsp;";

            function start_loader(varloader)
            {
                document.getElementById(varloader+"_wrapper").style.dislay="block";
                loader=setInterval(function () {process_loader(varloader+"_content")}, 500);

                if (dots==".&nbsp;&nbsp;")
                {
                    dots="..&nbsp;";
                }
                else if (dots=="..&nbsp;")
                {
                    dots="...";
                }
                else if (dots=="...")
                {
                    dots=".&nbsp;&nbsp;";
                }


                function process_loader(varloadercontent)
                {
                    var inc=1;
                    var marginleft = document.getElementById(varloadercontent).style.marginLeft;
                    marginleft=marginleft.replace("px","");
                    marginleft=parseInt(marginleft)+inc;

                    if (marginleft>=0)
                    {
                        document.getElementById(varloadercontent).style.marginLeft="-5px";
                        document.getElementById(varloadercontent+"_text").innerHTML="Loading 95%"+dots;
                    }
                    else
                    {

                        var percent=(((500+marginleft)/500)*100).toFixed(0);
                        document.getElementById(varloadercontent+"_text").innerHTML="Loading "+percent+"%"+dots;

                        document.getElementById(varloadercontent).style.marginLeft=marginleft+"px";
                    }
                }
            }

            function stop_loader(varloader)
            {
                 clearInterval(loader);
                 document.getElementById(varloader+"_wrapper").style.dislay="none";
            }
        </script>
    </head>

    <body>
        <div id="loader_wrapper" class="loader_wrapper">
            <div id="loader" class="loader_box">
                <div id="loader_content" class="loader_content" style="margin-left:-500px;">

                </div>
            </div>
            <br />
            <div id="loader_content_text" class="loader_text">

            </div>

        </div>

        <script>
            start_loader("loader");
        </script>

       <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>

       <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>

       <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>

       <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>

        <script>
            //stop_loader("loader"); COMMENT THIS CODE OUT SO YOU CAN SEE WHAT'S HAPPENING.
        </script>
    </body>
</html>

Now run the code. This is what you should be seeing...

What did I just do?

You added a placeholder with id loader_text just under the loader_box. But still within the loader_wrapper div. And then you styled it as follows...

width: 500px - to match the width of loader_box.
height: 20px - well you may not really need this, but I'm a bit of a control freak.
text-align: center - because it would look weird otherwise.
font-size: 14px - what nice big font you have, grandma.
font-family: arial - because I fucking love arial. Shut up.
color: #FFFFFF - nice contrast to that black background.
margin-left: auto,margin-right: auto - centers it nicely within loader_wrapper.


And then you added a global variable dots to your JavaScript, and set an initial value of <dot><space><space>. Then a long-ass chained If-Else statement that masically changes the value of dots to the next applicable value. So as your text animation progresses and even when it stops moving because it's reached the end, the dots will keep animating. Clever, eh?

Next, you modified the If-Else statement in the process_loader() function to display a "Loading <percentage>%..." string which will change according to how far the loader_content div has moved from its original margin-left property of -500px!

I bet that was a lot to take in. Note that all of this is absolutely optional. So if you made it this far, give yourself a pat on the back... and roll those sleeves up because we've got more to do.

Next...

Making your Wayang Progress Bar move more realistically. (Yes it's fake, but the users don't have to know that)

Web Tutorial: The Wayang Progress Bar (Part 2/4)

Now that we have your Wayang Progress Bar, here's the next step: how to present it, and how to turn it off.

Firstly, we're going to add some filler content to the existing page, so that you can get a nice visual of what the final result looks like.

Add this markup code to your page.
    <body>
        <div id="loader" class="loader_box">
            <div id="loader_content" class="loader_content" style="margin-left:-500px;">

            </div>
        </div>

        <script>
            start_loader("loader");
        </script>

       <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>

       <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>

       <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>

       <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>

    </body>


The result:


Next, what we're going to do may be a little tricky for a CSS beginner. We're going to place a layer over the entire screen, and plonk your Wayang Progress Bar right in the middle.

Make these amendments to your CSS and HTML.
<!DOCTYPE html>
<html>
    <head>
        <title>Progress Loader test</title>
        <style type="text/css">
            .loader_box
            {
                width: 500px;
                height: 20px;
                border: 1px solid #777777;
                border-radius: 9px;
                overflow: hidden;
                margin-left: auto;
                margin-right: auto;
            }

            .loader_content
            {
                width: 500px;
                height: 20px;
                background: #ff4444; /* Old browsers */
                background: -moz-linear-gradient(top, #ff4444 0%, #ff9e9e 52%, #ff4444 100%); /* FF3.6+ */
                background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#ff4444), color-stop(52%,#ff9e9e), color-stop(100%,#ff4444)); /* Chrome,Safari4+ */
                background: -webkit-linear-gradient(top, #ff4444 0%,#ff9e9e 52%,#ff4444 100%); /* Chrome10+,Safari5.1+ */
                background: -o-linear-gradient(top, #ff4444 0%,#ff9e9e 52%,#ff4444 100%); /* Opera 11.10+ */
                background: -ms-linear-gradient(top, #ff4444 0%,#ff9e9e 52%,#ff4444 100%); /* IE10+ */
                background: linear-gradient(to bottom, #ff4444 0%,#ff9e9e 52%,#ff4444 100%); /* W3C */
                filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ff4444', endColorstr='#ff4444',GradientType=0 ); /* IE6-9 */  
       
            }

            .loader_wrapper
            {
                width: 100%;
                height: 100%;
                background: rgba(0,0,0,0.8);
                position: fixed;
                z-index: 600;
                top: 0px;
                left: 0px;
                padding-top: 50px;      
            }

        </style>

        <script>
            var loader;

            function start_loader(varloader)
            {
                loader=setInterval(function () {process_loader(varloader+"_content")}, 500);

                function process_loader(varloadercontent)
                {
                    var inc=1;
                    var marginleft = document.getElementById(varloadercontent).style.marginLeft;
                    marginleft=marginleft.replace("px","");
                    marginleft=parseInt(marginleft)+inc;

                    if (marginleft>=0)
                    {
                        document.getElementById(varloadercontent).style.marginLeft="-5px";
                    }
                    else
                    {
                        document.getElementById(varloadercontent).style.marginLeft=marginleft+"px";
                    }
                }
            }
        </script>
    </head>

    <body>
        <div id="loader_wrapper" class="loader_wrapper">
            <div id="loader" class="loader_box">
                <div id="loader_content" class="loader_content" style="margin-left:-500px;">

                </div>
            </div>
        </div>

        <script>
            start_loader("loader");
        </script>

       <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>

       <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>

       <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>

       <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>

    </body>
</html>

The result:

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
What we've done is to determine where your Wayang Progress Bar sits when visible. And now we're going to turn it invisible, which will be the default state.

Add the following code to your CSS.

            .loader_wrapper
            {
                width: 100%;
                height: 100%;
                background: rgba(0,0,0,0.8);
                position: fixed;
                z-index: 600;
                top: 0px;
                left: 0px;
                padding-top: 50px;
                display: none;     
            }

And viola! All that's left is your Lorem Ipsum filler content. Now we're going to include code to turn your Wayang Progress Bar visible when the page loads, and then turn it invisible again when the page is done loading.

Modify your JavaScript and HTML as shown below:
<!DOCTYPE html>
<html>
    <head>
        <title>Progress Loader test</title>
        <style type="text/css">
            .loader_box
            {
                width: 500px;
                height: 20px;
                border: 1px solid #777777;
                border-radius: 9px;
                overflow: hidden;
                margin-left: auto;
                margin-right: auto;
            }

            .loader_content
            {
                width: 500px;
                height: 20px;
                background: #ff4444; /* Old browsers */
                background: -moz-linear-gradient(top, #ff4444 0%, #ff9e9e 52%, #ff4444 100%); /* FF3.6+ */
                background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#ff4444), color-stop(52%,#ff9e9e), color-stop(100%,#ff4444)); /* Chrome,Safari4+ */
                background: -webkit-linear-gradient(top, #ff4444 0%,#ff9e9e 52%,#ff4444 100%); /* Chrome10+,Safari5.1+ */
                background: -o-linear-gradient(top, #ff4444 0%,#ff9e9e 52%,#ff4444 100%); /* Opera 11.10+ */
                background: -ms-linear-gradient(top, #ff4444 0%,#ff9e9e 52%,#ff4444 100%); /* IE10+ */
                background: linear-gradient(to bottom, #ff4444 0%,#ff9e9e 52%,#ff4444 100%); /* W3C */
                filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ff4444', endColorstr='#ff4444',GradientType=0 ); /* IE6-9 */           
            }

            .loader_wrapper
            {
                width: 100%;
                height: 100%;
                background: rgba(0,0,0,0.8);
                position: fixed;
                z-index: 600;
                top: 0px;
                left: 0px;
                padding-top: 50px;
                display: none;     
            }
        </style>

        <script>
            var loader;

            function start_loader(varloader)
            {
                document.getElementById(varloader+"_wrapper").style.dislay="block";
                loader=setInterval(function () {process_loader(varloader+"_content")}, 500);

                function process_loader(varloadercontent)
                {
                    var inc=1;
                    var marginleft = document.getElementById(varloadercontent).style.marginLeft;
                    marginleft=marginleft.replace("px","");
                    marginleft=parseInt(marginleft)+inc;

                    if (marginleft>=0)
                    {
                        document.getElementById(varloadercontent).style.marginLeft="-5px";
                    }
                    else
                    {
                        document.getElementById(varloadercontent).style.marginLeft=marginleft+"px";
                    }
                }
            }

            function stop_loader(varloader)
            {

                 clearInterval(loader);
                 document.getElementById(varloader+"_wrapper").style.dislay="none";
            }
        </script>
    </head>

    <body>
        <div id="loader_wrapper" class="loader_wrapper">
            <div id="loader" class="loader_box">
                <div id="loader_content" class="loader_content" style="margin-left:-500px;">

                </div>
            </div>
        </div>

        <script>
            start_loader("loader");
        </script>

       <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>

       <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>

       <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>

       <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.</p>

        <script>
            stop_loader("loader");
        </script>
    </body>
</html>

And you're done! Sit back and watch the show.

Not displaying?

I thought that might happen. The start_loader() function takes effect after 500 milliseconds. But if your page is done loading within 500 milliseconds, the stop_loader() function kills it! So all you're going to see (if you're lucky) is a flash of black. In order to actually see your code working, you need to replace the filler content with something more substantial, like an entire gallery of images.

In any case, this is more like what you should be seeing.

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

Next...

Adding more visual input to your Wayang Progress Bar. The code can be used and is fully functional. But we're not done yet, sunshine! If you're gonna wayang, be professional about it! We're going to value-add!

Tuesday 11 November 2014

Web Tutorial: The Wayang Progress Bar (Part 1/4)

In my University days, we studied HCI (Human-Computer Interaction). And somewhat unavoidably, we learned from a charming gentleman by the name of Peter Bickford, an expert in the field. I quote him below:

Switching to a watch cursor during the wait delayed the subject's departure for about 20 seconds. An animated watch cursor was good for over a minute, and a progress bar would keep them waiting until the Second Coming - or Windows 98, whichever came first.

More at http://web.archive.org/web/20040913083444/http://developer.netscape.com/viewsource/bickford_wait.htm#bio

Granted, this was maybe two decades ago, but his words still hold true. However, to keep this up-to-date, we'll need to roughly halve the waiting times mentioned. This is the iPad generation. Bandwidth and data transfer speeds have quadrupled. Instant gratification is the in-thing. People are getting used to obtaining information with a swipe of the finger. These days, it takes roughly 2 to 5 seconds of waiting time before the user will turn to you and holler "Ah hia! Your website broken lah, dey!"

With that in mind, we're going to create a Progress Bar. Ostensibly, this displays how much of the current page has been loaded, and should keep the user content to wait. Except that this isn't a real loader. It's just an animated bar designed to harness the user's attention span. Hence, what I like to refer to as the Wayang Progress Bar. If you're neither Singaporean nor Indonesian and don't know what wayang is, wayang kulit is a form of shadow puppetry which originated in Java, Indonesia, and essentially means, in local parlance, "purely for show".

Shadow Puppet

And that's exactly what the Wayang Progress Bar is; purely for show. It won't speed up your website, nor will it actually display how much of the site has loaded. Its purpose is merely to stall the user till your page is done loading!

This Wayang Progress Bar will have no graphics, because graphics take time to load and the whole point of the Wayang Progress Bar would be lost if it significantly increased waiting time. Instead, we'll be leveraging heavily on HTML, CSS and JavaScript.

This is your layout:
<!DOCTYPE html>
<html>
    <head>
        <title>Progress Loader test</title>
    </head>

    <body>
        <div id="loader" class="loader_box">
            <div id="loader_content" class="loader_content" style="margin-left:-500px;">

            </div>
        </div>
    </body>
</html>

Now add the CSS declaration to the head tag.
<!DOCTYPE html>
<html>
    <head>
        <title>Progress Loader test</title>
        <style type="text/css">
            .loader_box
            {
                width: 500px;
                height: 20px;
                border: 1px solid #777777;
                overflow: hidden;
            }

            .loader_content
            {
                width: 500px;
                height: 20px;
                background: #440000;        
            }
        </style>

    </head>

    <body>
        <div id="loader" class="loader_box">
            <div id="loader_content" class="loader_content" style="margin-left:-500px;">

            </div>
        </div>
    </body>
</html>

This is how it's going to look like at the moment:



Nothing fantastic, huh? Just a long rectangle. Not to worry, we're just getting started! 500 pixels is a rough guide. You may want to make the progress bar longer or shorter, but you'll need to adjust the margin-left property of the loader_content div tag accordingly.

Now, add this JavaScript snippet to your header tag. Also, add the JavaScript event handler to your HTML.
<!DOCTYPE html>
<html>
    <head>
        <title>Progress Loader test</title>
        <style type="text/css">
            .loader_box
            {
                width:500px;
                height:20px;
                border:1px solid #777777;

                overflow:hidden;
            }

            .loader_content
            {
                width:500px;
                height:20px;
                background: #440000;        
            }
        </style>

        <script>
            var loader;

            function start_loader(varloader)
            {
                loader=setInterval(function () {process_loader(varloader+"_content")}, 500);

                function process_loader(varloadercontent)
                {
                    var inc=1;
                    var marginleft = document.getElementById(varloadercontent).style.marginLeft;
                    marginleft=marginleft.replace("px","");
                    marginleft=parseInt(marginleft)+inc;

                    if (marginleft>=0)
                    {
                        document.getElementById(varloadercontent).style.marginLeft="-5px";
                    }
                    else
                    {
                        document.getElementById(varloadercontent).style.marginLeft=marginleft+"px";
                    }
                }
            }
        </script>

    </head>

    <body>
        <div id="loader" class="loader_box">
            <div id="loader_content" class="loader_content" style="margin-left:-500px;">

            </div>
        </div>

        <script>
            start_loader("loader");
        </script>

    </body>
</html>

For more about JavaScript timer functions, click here: http://www.w3schools.com/js/js_timing.asp

Now refresh your browser, sit back, and enjoy the magic!

How do I use this?

You can slip the loader div anywhere you please. Though I'd recommend having it just after your body tag.

What the code does

There's an outer div with the id loader_box. And an inner div loader_content, colored brown (#440000), within it. The loader_content div is offset 500px to the left initially. The overflow:hidden CSS value ensures that any part of loader_content that goes out of loader_box is invisible.

As soon as the timer function process_loader() is triggered, it progressively alters the margin-left property of loader_content so that it appears as though the loader_box is filling up! You can adjust the speed of the animation by changing the value highlighted below. This line basically tells your browser to trigger the process_loader() function every 500 milliseconds, so decrease the value if you need to speed it up!

loader=setInterval(function () {process_loader(varloader+"_content")}, 500);

This Wayang Progress Bar should be good for an average page lag of 20 seconds. If you need a longer time, adjust the animation speed or the length of the Wayang Progress Bar.

Cool, eh? But that's not all. Look at the JavaScript in the If-Else statement. If the margin-left value exceeds 0px, which means the box is full, the display automatically keeps it at roughly 99%. So if it reaches 100% and your page is still not loaded, the user won't be asking why?

Let's make it pretty!

 Give your progress bar rounded corners! Add the following code to your CSS.

        <style type="text/css">
            .loader_box
            {
                width: 500px;
                height: 20px;
                border: 1px solid #777777;
                border-radius: 9px;
                overflow: hidden;
            }

            .loader_content
            {
                width: 500px;
                height: 20px;
                background: #440000;        
            }
        </style>



Now change the colour of your bar. For some cool color combos, visit http://www.colorzilla.com/gradient-editor/

I'm just going to go with a nice flamingo pink. This is CSS3, but you don't need to learn it all right now, we're just having a little fun.

        <style type="text/css">
            .loader_box
            {
                width: 500px;
                height: 20px;
                border:1px solid #777777;
                border-radius: 9px;
                overflow: hidden;
            }

            .loader_content
            {
                width: 500px;
                height: 20px;
                background: #ff4444; /* Old browsers */
                background: -moz-linear-gradient(top, #ff4444 0%, #ff9e9e 52%, #ff4444 100%); /* FF3.6+ */
                background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#ff4444), color-stop(52%,#ff9e9e), color-stop(100%,#ff4444)); /* Chrome,Safari4+ */
                background: -webkit-linear-gradient(top, #ff4444 0%,#ff9e9e 52%,#ff4444 100%); /* Chrome10+,Safari5.1+ */
                background: -o-linear-gradient(top, #ff4444 0%,#ff9e9e 52%,#ff4444 100%); /* Opera 11.10+ */
                background: -ms-linear-gradient(top, #ff4444 0%,#ff9e9e 52%,#ff4444 100%); /* IE10+ */
                background: linear-gradient(to bottom, #ff4444 0%,#ff9e9e 52%,#ff4444 100%); /* W3C */
                filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ff4444', endColorstr='#ff4444',GradientType=0 ); /* IE6-9 */   
  
            }
        </style>

A This is just a simulation of how the final result will be. Get creative!


There are more enhancements you may like to consider for your Wayang Progress Bar. They'll be discussed in the following parts of this web tutorial.

Next...

How to turn your Wayang Progress Bar off! You didn't think I left that out, did you?

Thursday 6 November 2014

To the Strong and the Bold

With the introduction of HTML5, there has been a fair bit of confusion regarding the tags <strong> and <em>. Many developers have regarded these tags as replacements for <b> and <i> respectively. Even HTML Editors such as CKEditor and Adobe Dreamweaver have introduced these as defaults. Click on the  button in either of these applications and you're likely to get a <strong> instead of a <b>. Likewise, click on the button and you'll get <em> instead of <i>.

What people don't realize is that, unlike certain tags like <font> and <center>, <b> and <i> have not been deprecated. That's right, they are part of the HTML5 specification.

HTML5 Specs for the STRONG tag: http://www.w3.org/TR/html5/text-level-semantics.html#the-strong-element
HTML5 Specs for the EM tag http://www.w3.org/TR/html5/text-level-semantics.html#the-em-element

What exactly are these tags for?

We'll start with the difference between <strong> and <b>. Once you understand this, <em> and <li> should follow quite easily.

On the surface, to the human eye, there is no difference. <strong> and <b> both turn text bold, as shown below.

This text is <b>bold</b>
<br />
This text is <strong>strong</strong>.

This text is bold.
This text is strong.


The difference is that <b> is purely cosmetic, while <strong> has semantic significance. You use <strong> when you want to put some extra weight on a word, to increase its importance. You use <b> when you only want to make text bold.

With semantic significance, you can change the entire meaning of a sentence.

He didn't say he stole her jewels.
He didn't say he stole her jewels.
He didn't say he stole her jewels.
He didn't say he stole her jewels.
He didn't say he stole her jewels.
He didn't say he stole her jewels.
He didn't say he stole her jewels.

Contrast this to the code below. The headers are rendered with the <b> tag, not because they have any special significance, but because it would look nicer to have them in bold.

<table>
   <tr>
                <td><b>Header A</b></td>
                <td><b>Header B</b></td>
                <td><b>Header C</b></td>
                <td><b>Header D</b></td>
   </tr>
   <tr>
                <td>Data</td>
                <td>Data</td>
                <td>Data</td>
                <td>Data</td>
   </tr>
   <tr>
                <td>Data</td>
                <td>Data</td>
                <td>Data</td>
                <td>Data</td>
   </tr>
</table>


Result:
Header A Header B Header C Header D
Data Data Data Data
Data Data Data Data


Of course, one could argue that we could just solve this thing with CSS (and you'd be quite right), but CSS is not the subject matter here. Just to be pedantic, the CSS descriptor font-weight:bold is also purely cosmetic.

Yes, to the human eye, this still makes no difference. <strong> and <b> will still appear as bolded text. It will, however, make a great deal of difference to a machine. The builders of the HTML5 specification probably intended for semantic markup to play a part in SEO (Search Engine Optimization). Thus, the separate tags even though they both look the same to you. Because if everything in bold was important, that would lead to a lot of cranky search results!

New fun stuff!

Apparently, you can also nest <strong> tags.

<strong>He never said he stole <strong>her</strong> jewels.</strong>

To the human eye, this does nothing more than bold the entire block of text. When a machine reads this, however, it's supposed to place importance on the sentence, and even greater importance on the word "her" within that sentence.

What about <em> and <i>?

So now, apply everything I just said about <strong> and <b>, and apply it to <em> and <i>.

What does this mean for future development?

Well, at this point in time, until everyone gets used to the idea and starts applying this standard, you could probably get away with using the tags interchangeably. But looking to the future, you're advised to adapt. Heaven knows when HTML5 syntax will finally stop fluctuating though, so take your time.

Until then, fortune favours the <b>, so go get <em>!
T___T

Wednesday 5 November 2014

Five Things Not to Say to a Web Developer

In the course of searching for a web developer, a company is definitely going to go through a few resumes and it's almost a certainty that interviews will be conducted. However, depending on the size of the company, there will be different kinds of interviews being conducted. Those dealing with the technical aspect, and those dealing with the human resource aspect. And assuming both interviewers stick to their scope, all's well and good.

The problem tends to begin when a non-technical person (usually HR personnel) is sent to conduct the only interview for a web developer. Miscommunication can arise, not because HR is unprofessional per se, but because HR is rarely equipped to understand the technical aspects of a web developer's repertoire.

Consider this conversation.

HR: May I know more about your work experience in your last company?

WD: Well, my first project was a CRM. It was on a PHP MVC platform and I was working under the Team Lead, and put in charge of testing the Reporting functions. After a year, I was put solely in charge of a medum-sized e-commerce portal with a ERDBMS back-end...

HR: Wait, what's a CRM?

The one nice thing about putting oneself through the hassle of an interview, getting dressed up and all, is that you get to brag about stuff you've done. But bragging to someone who can't tell a XML tag from an dog tag makes the entire exercise pointless.

Still, this seems to be inevitable and bearing that in mind, here are some things to avoid saying to a web developer interviewee. These things are almost guaranteed to produce an uncomfortable moment as the interviewee struggles with a mental eye-roll, or actually produces a look which plainly says Why am I talking to you, exactly?

Looking to the future.

1. Where do you see yourself in 5 years' time? Do NOT ask this question.

This has got to be the most overused interview question on the island. Unless you're hiring a web developer with intent to promote him AND you actually have some kind of company hierarchy that allows for this (three levels of reporting doesn't count), don't. Just... don't.


HTML is a programming
language? Really?

2. Get your terminology right.

It's fun to throw technical terms around like you mean it. But unless you have a pretty good idea what they
actually are, try to avoid doing so. Don't, for example, refer to HTML as a "programming language". Or MVC. Or AJAX, for that matter. If such distinctions are lost on you, you may want to consider letting someone else handle this part of the interview.

For more on this subject, see http://inventwithpython.com/blog/2013/12/15/why-is-html-not-a-programming-language/


Yes, I can fucking bold text.

3. Don't ask if he can bold text, or anything stupid like that.

I actually had an interviewer ask me this once before. Can you bold text? Italics? How about changing the colour? He must have caught the dude-are-you-fucking-with-me look on my face because he swiftly moved on.

Web development isn't the most glamourous job in the world. The pay can be shitty, the hours worse. And sometimes we're forced to produce work we're not proud of, work we would never acknowledge unless a loaded gun was pointed to our heads, just to pay the bills.

That said, web developers do have a certain amount of pride. Web development is a craft, and should be treated with a modicum of respect. Don't ask a web developer if he knows how to do these very simple, very banal tasks. That's insulting. Unless you just want a glorified HTML coder to write your EDMs. Schoolkids nowadays know HTML. Schoolkids can bold text, dammit.


THIS is web dev.

4. How many hours a workday would you say you spend programming? Do NOT ask this either.

I remember the first time I was asked this question. My first reaction was, is this some kind of abstractly worded test question I had to answer with tact and wisdom? I swiftly came to the conclusion that the truth was horrifyingly simple - I was being interviewed by an old-fashioned factory-style pencil-pusher.

Web development is more than just programming. There's UI, database, requirements gathering, the works. Hell, programming is more than just programming. I would hope the average programmer spends far more time testing than actually coding!

In other words, anyone who can ask this question with a straight face obviously has nary a clue regarding the process. You do not want to come off as that person.


Developers come in all shapes,
sizes and skin colours.

5. Don't ever suggest that he stands a better chance due to his nationality.

If you need someone who can speak a English fluently, sure, you would be justified in wanting a local. And even that is no guarantee that his communication skills are effective enough. Or perhaps you require this prospective hire to travel. Fair enough. But if you just want a local in order to boost your headcount quota, be smart enough not to mention it to his face.

You're hiring him and his skill-set, not his passport. You're hiring him because he represents the best value for your money. Anything less than that is a put-down.

And if you still manage to hire this person despite that horrific gaffe, do bear in mind that few things are more detrimental to your operation than a professional with zero pride. Unless he's entry-level. In which case, go to town on him because he's got to earn his dignity.


Before I sign off, any questions? Yes, I can bold text, smartass.
T___T