Monday 30 May 2016

Data Transport Methods Across Webpages (Part 2/2)

It's time to look at the other method of sending data.

The POST method

The POST method is a more effective way of sending data. The data is embedded in the headers and sent to the next page.

<form method="POST">
    <input name="x" value="test">
    <input name="y" value="12345">
    <input type="submit" name="btSubmit" value="submit">
</form>


Pros

Way more secure than GET - All data is hidden. Note that I said more, not totally secure. POST has its vulnerabilities which we'll explore at a later date.

Versatility in data formats and lengths - You can send long paragraphs of text, in addition to everything you can already send via GET. Also, and this is no trivial matter, you can send binary files.

Cons

Breaks page flow - clicking on the Back button or reloading the page will cause a popup to appear, asking if you wish to re-send your data. Depending on the nature of your data, re-sending the data may cause something to break. Below is a sample of this popup. The message varies from browser to browser.


Use POST for...

... almost everything. Long and complex data, especially files.

... data that needs to be kept private, e.g. transactions or passwords.

Do not use POST for...

... pages you may want to be cached.

... pages where backwards-forwards navigation is an issue.

The methods in a nutshell

The GET method has a well-deserved reputation for being widely used - sometimes overused. I once spoke to a software developer who looked upon GET with disdain and was of the opinion that GET is an unsafe and "cheap" way of sending data. She was only half right. GET is all that, and so much more. There is a place for everything, and GET is no exception. GET has its uses - some of which are not immediately apparent to people who aren't web developers.

On the other hand, I've been guilty of using POST when it would have been more beneficial to use a GET instead. Oh, well. Live and learn.

The lesson for the day is - the correct tool for the correct job. Whatever you end up choosing, exercise appropriate caution.

That's all for the time being. I'll POST again soon. (snicker)
T___T

Saturday 28 May 2016

Data Transport Methods Across Webpages (Part 1/2)

Web developers all know that there the Internet is a stateless medium and to mitigate that unfortunate fact, there are two basic ways of transporting data across pages - GET and POST. While this is bread-and-butter stuff for all who deal with the web, ultimately not every developer understands GET and POST as well as they should, mostly operating on a vague understanding of which to use, and when.

And that is why, today I'll be dealing with both cases.

The GET method

The GET method is the default way of transporting data. In a HTML form, if the method attribute is not specified in the form tag, the browser automatically assumes a GET. Here's an example. Pay attention to the form tag.
<form>
    <input name="x" value="test">
    <input name="y" value="12345">
    <input type="submit" name="btSubmit" value="submit">
</form>


is the same as
<form method="GET">
    <input name="x" value="test">
    <input name="y" value="12345">
    <input type="submit" name="btSubmit" value="submit">
</form>


The GET method of transporting data basically embeds the data in the URL in data-value pairs separated by ampersands. Assuming that this form is in a page named tt_test.asp, submitting the form would give you a URL of:
tt_test.asp?x=test&y=12345&btSubmit=submit


This also means that you can use the GET method to transport data without using a form.

Pros

Quick and dirty - As mentioned, you don't need a form to send data via the GET method. You merely need to formulate the URL properly.

Caching - Since GET is essentially a URL, it follows that pages generated from the GET method may also be cached, and this shaves valuable time off page loads. URL caching in turn facilitates pages generated using the GET method being crawled by search engines, which leads to better Search Engine Optimization. And this is the one thing that cements GET its place as a viable method of data transport despite its obvious inferiority to POST in many areas.

Cons

Size limitations - The URL can hold only that much data. Therefore using GET to send long strings of data (over 1000 characters including the URL, depending on browser) is not advisable.

Format - GET can send only text data. Even then, special characters have to be encoded. If, for example, you wanted to send an ampersand as part of your data, you would have to be very careful that the it is not mistaken as a separator.

Security - The data appears in the URL. Duh.

Use GET for...

... simple data that can be easily sanitized and whitelisted.

... data that does not need to be private.

Do not use GET for...

... data that should be hidden, such as passwords.

... complex data

... long strings

Absolutely do not use GET for...

... entire SQL queries (Jesus Christ, do you have a death wish or something?!)

tt_test.asp?query=SELECT x from table_y WHERE id=3

Next

We take a look at the POST method.


Sunday 22 May 2016

Web Tutorial: The Javascript Clockface

Tick-tock!

Today's web tutorial will revolve around creating a clockface in JavaScript. It will move like a clock, with the hands of the clock pointing at the appropriate positions.

How is this useful?

Er, well actually it's not very useful. But it's good for exercising what you know about JavaScript Timer functions, transformations and the like.

Without further ado, here's the starting HTML.
<html>
    <head>
        <title>Clock</title>

        <style>
            #clockface
            {
                width:300px;
                height:300px;
                border-radius:50%;
                border:5px solid #FFDD00;
                margin-left:auto;
                margin-right:auto;
                margin-top:10%;
            }           
        </style>

        <script>

        </script>
    </head>
    <body>
        <div id="clockface">

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


So we have a div with an id of clockface, and this is what its CSS styling does.
- width:300px, height:300px sets the height and width.
- border-radius:50% makes it circular.
- border:5px solid #FFDD00 gives it a nice thick orange border.
- margin-left:auto, margin-right:auto places the clockface in the middle of the screen.
- margin-top:10% just gives the clockface a little spacing from the top.

It should look like this now.


Now for the numbers!

What's a clockface without numbers, right? Let's add those little suckers. We'll need some JavaScript for this. But first, the HTML and styling.
<html>
    <head>
        <title>Clock</title>

        <style>
            #clockface
            {
                width:300px;
                height:300px;
                border-radius:50%;
                border:5px solid #FFDD00;
                margin-left:auto;
                margin-right:auto;
                margin-top:10%;
            }

            .clocksegment
            {
                position:absolute;
                z-index:5;
                width:20px;
                height:150px;
                margin-left:140px;
                margin-top:0px;
                -webkit-transform-origin:50% 100%;
                transform-origin:50% 100%;
                border:1px solid #FF0000;
            }

            .clocksegmentno
            {
                width:100%;
                height:21px;
                -webkit-transform-origin:50% 50%;
                transform-origin:50% 50%;
                color:#444444;
                font-size:15px;
                text-align:center;
                border:1px solid #00FF00;
            }

            .clocksegmentno_offset
            {
                background-color:#444444;
                width:1px;
                height:5px;
                margin-left:auto;
                margin-right:auto;
                margin-top:-10px;
            }           
        </style>

        <script>

        </script>
    </head>
    <body>
        <div id="clockface">
            <div id="segment1" class="clocksegment">
                <div id="segmentno1" class="clocksegmentno"></div>
                <br />
                <div class="clocksegmentno_offset"></div>
            </div>
        </div>
    </body>
</html>


Here we've added one div with the id of segment1 and a CSS class of clocksegment within the clockface div, then nested two other divs inside the segment1 div. The first div contains the number and has an id of segmentno1 and a CSS class clocksegmentno. The second div has no id and is styled using the CSS class clocksegmentno_offset.

Here's what the clocksegment CSS class does.
- position:absolute, z-index:5 ensures that the segments can overlap within the clockface div.
- width:20px, height:150px because each segment is half the height of the clockface div, and should occupy only that much width.
- margin-left:140px,margin-top:0px since the width of the segment is 20 pixels, half of that would be 10. And since half the width of the clockface div is 150 pixels, offsetting the left side of the segment by 150-10=140 pixels places the segment dead center top of the clockface.
- transform-origin:50% 100% because you'll want to rotate the segment by its bottom center. This is gonna be important later.
- border:1px solid #FF0000 for now, so you can see what's taking place.

Here's what the clocksegmentno CSS class does.
- width:100% sets the width to be equal to that of its parent, which would be 20 pixels.
- height:20px to allocate that amount of space for the number.
- transform-origin:50% 50% because the numbers need to be rotated later, by the center point.
- color:#444444, font-size:15px are cosmetic values, change as you will. But the font size shouldn't be too large or too small. There's a certain amount of wriggle room.
- text-align:center to ensure that no matter what width the number takes up, its placement is consistent.
- border:1px solid #00FF00 for now, so you can see what's taking place.

Here's what the clocksegmentno_offset CSS class does. This is pretty much just a thin grey line pointing to the number.
- background-color:#444444, width:1px, height:5px turns this into a very thin div with a grey background color.
- margin-left:auto, margin-right:auto keeps this in the center of its parent div.
- margin-top:-10px reduces the spacing between the number and the pointer.

This is what you should have...


Now add eleven more of these segments, and number them accordingly. Remember to change the numbering of the nested divs as well!
        <div id="clockface">
            <div id="segment1" class="clocksegment">
                <div id="segmentno1" class="clocksegmentno"></div>
                <br />
                <div class="clocksegmentno_offset"></div>
            </div>
            <div id="segment2" class="clocksegment">
                <div id="segmentno2" class="clocksegmentno"></div>
                <br />
                <div class="clocksegmentno_offset"></div>
            </div>
            <div id="segment3" class="clocksegment">
                <div id="segmentno3" class="clocksegmentno"></div>
                <br />
                <div class="clocksegmentno_offset"></div>
            </div>
            <div id="segment4" class="clocksegment">
                <div id="segmentno4" class="clocksegmentno"></div>
                <br />
                <div class="clocksegmentno_offset"></div>
            </div>
            <div id="segment5" class="clocksegment">
                <div id="segmentno5" class="clocksegmentno"></div>
                <br />
                <div class="clocksegmentno_offset"></div>
            </div>
            <div id="segment6" class="clocksegment">
                <div id="segmentno6" class="clocksegmentno"></div>
                <br />
                <div class="clocksegmentno_offset"></div>
            </div>
            <div id="segment7" class="clocksegment">
                <div id="segmentno7" class="clocksegmentno"></div>
                <br />
                <div class="clocksegmentno_offset"></div>
            </div>
            <div id="segment8" class="clocksegment">
                <div id="segmentno8" class="clocksegmentno"></div>
                <br />
                <div class="clocksegmentno_offset"></div>
            </div>
            <div id="segment9" class="clocksegment">
                <div id="segmentno9" class="clocksegmentno"></div>
                <br />
                <div class="clocksegmentno_offset"></div>
            </div>
            <div id="segment10" class="clocksegment">
                <div id="segmentno10" class="clocksegmentno"></div>
                <br />
                <div class="clocksegmentno_offset"></div>
            </div>
            <div id="segment11" class="clocksegment">
                <div id="segmentno11" class="clocksegmentno"></div>
                <br />
                <div class="clocksegmentno_offset"></div>
            </div>
            <div id="segment12" class="clocksegment">
                <div id="segmentno12" class="clocksegmentno"></div>
                <br />
                <div class="clocksegmentno_offset"></div>
            </div>
        </div>


Now see what you did. They're all overlapped, aren't they? So you will see no apparent difference in the output. We're going to rectify that with some JavaScript! Add the startclock() function to your script tag. Here, we run a For loop which iterates through all twelve segments.
        <script>
            function startclock()
            {
                for (i=1;i<=12;i++)
                {

                }
            }
        </script>


And modify your HTML. This ensures that startclock() is fired off right at the start.
    <body onload="startclock();">


Now let's get back to the startclock() function. First of all, rotate each segment by an increasing 360/12=30 degrees. segment1 will be rotated by 30 degrees, segment2 by 60 degrees, etc. Unless it's segment12 - segment12 stays put.
function startclock()
{
    for (i=1;i<=12;i++)
    {
        if (i<12)
        {
            document.getElementById("segment"+i).style.transform="rotate("+(i*30)+"deg)";
            document.getElementById("segment"+i).style.webkitTransform="rotate("+(i*30)+"deg)";

        }
    }
}


Presto!


Now to fill in the numbers. This line of code is outside of the If-else block because segment12 also needs to have its number displayed.
    for (i=1;i<=12;i++)
    {
        if (i<12)
        {
            document.getElementById("segment"+i).style.transform="rotate("+(i*30)+"deg)";
            document.getElementById("segment"+i).style.webkitTransform="rotate("+(i*30)+"deg)";          
        }

        document.getElementById("segmentno"+i).innerHTML=i;
    }


Here we are, the numbers are in! But do you see a problem? That's right, the numbers have been rotated along with their parent divs. This is bad because "6" now looks like "9".


We're going to rotate all the number divs independently of their parent divs. This line of code rotates the ppropriate div in the opposite direction of which their parent div was rotated.
    for (i=1;i<=12;i++)
    {
        if (i<12)
        {
            document.getElementById("segment"+i).style.transform="rotate("+(i*30)+"deg)";
            document.getElementById("segmentno"+i).style.transform="rotate(-"+(i*30)+"deg)";
            document.getElementById("segment"+i).style.webkitTransform="rotate("+(i*30)+"deg)";
            document.getElementById("segmentno"+i).style.webkitTransform="rotate(-"+(i*30)+"deg)";              
        }

        document.getElementById("segmentno"+i).innerHTML=i;
    }


Like magic!


Now set all the border properties of the clocksegment and clocksegmentno CSS classes to 0px.
            .clocksegment
            {
                position:absolute;
                z-index:5;
                width:20px;
                height:150px;
                margin-left:140px;
                margin-top:0px;
                -webkit-transform-origin:50% 100%;
                transform-origin:50% 100%;
                border:0px solid #FF0000;
            }

            .clocksegmentno
            {
                width:100%;
                height:21px;
                -webkit-transform-origin:50% 50%; 
                transform-origin:50% 50%;
                color:#444444;
                font-size:15px;
                text-align:center;
                border:0px solid #00FF00;
            }
           

There you go.


Time to add the hands!

Specifically, the hour hand, minute hand and second hand.
        <div id="clockface">
            <div id="segment1" class="clocksegment">
                <div id="segmentno1" class="clocksegmentno"></div>
                <br />
                <div class="clocksegmentno_offset"></div>
            </div>
            <div id="segment2" class="clocksegment">
                <div id="segmentno2" class="clocksegmentno"></div>
                <br />
                <div class="clocksegmentno_offset"></div>
            </div>
            <div id="segment3" class="clocksegment">
                <div id="segmentno3" class="clocksegmentno"></div>
                <br />
                <div class="clocksegmentno_offset"></div>
            </div>
            <div id="segment4" class="clocksegment">
                <div id="segmentno4" class="clocksegmentno"></div>
                <br />
                <div class="clocksegmentno_offset"></div>
            </div>
            <div id="segment5" class="clocksegment">
                <div id="segmentno5" class="clocksegmentno"></div>
                <br />
                <div class="clocksegmentno_offset"></div>
            </div>
            <div id="segment6" class="clocksegment">
                <div id="segmentno6" class="clocksegmentno"></div>
                <br />
                <div class="clocksegmentno_offset"></div>
            </div>
            <div id="segment7" class="clocksegment">
                <div id="segmentno7" class="clocksegmentno"></div>
                <br />
                <div class="clocksegmentno_offset"></div>
            </div>
            <div id="segment8" class="clocksegment">
                <div id="segmentno8" class="clocksegmentno"></div>
                <br />
                <div class="clocksegmentno_offset"></div>
            </div>
            <div id="segment9" class="clocksegment">
                <div id="segmentno9" class="clocksegmentno"></div>
                <br />
                <div class="clocksegmentno_offset"></div>
            </div>
            <div id="segment10" class="clocksegment">
                <div id="segmentno10" class="clocksegmentno"></div>
                <br />
                <div class="clocksegmentno_offset"></div>
            </div>
            <div id="segment11" class="clocksegment">
                <div id="segmentno11" class="clocksegmentno"></div>
                <br />
                <div class="clocksegmentno_offset"></div>
            </div>
            <div id="segment12" class="clocksegment">
                <div id="segmentno12" class="clocksegmentno"></div>
                <br />
                <div class="clocksegmentno_offset"></div>
            </div>

            <div id="secondhand" class="hand"></div>
            <div id="minutehand" class="hand"></div>
            <div id="hourhand" class="hand"></div>
        </div>


Here's the CSS styling.
        <style>
            #clockface
            {
                width:300px;
                height:300px;
                border-radius:50%;
                border:5px solid #FFDD00;
                margin-left:auto;
                margin-right:auto;
                margin-top:10%;
            }

            #clockcenter
            {
                position:absolute;
                z-index:20;
                width:11px;
                height:11px;
                border-radius:50%;
                background-color: #444444;
                margin-left:145px;
                margin-top:145px;
            }

            .clocksegment
            {
                position:absolute;
                z-index:5;
                width:20px;
                height:150px;
                margin-left:140px;
                margin-top:0px;
                -webkit-transform-origin:50% 100%; 
                transform-origin:50% 100%;
            }

            .clocksegmentno
            {
                width:100%;
                height:20px;
                -webkit-transform-origin:50% 50%; 
                transform-origin:50% 50%;
                color:#444444;
                font-size:15px;
                text-align:center;
            }

            .clocksegmentno_offset
            {
                background-color:#444444;
                width:1px;
                height:5px;
                margin-left:auto;
                margin-right:auto;
                margin-top:-10px;
            }

            .hand
            {
                position:absolute;
                z-index:10;
                -webkit-transform-origin:50% 100%;
                -webkit-transform:rotate(0deg);
                transform-origin:50% 100%;
                transform:rotate(0deg);
            }

            #secondhand
            {
                margin-left:149px;
                margin-top:50px;
                width:3px;
                height:100px;
                background-color:#444444;
            }

            #minutehand
            {
                margin-left:148px;
                margin-top:20px;
                width:5px;
                height:130px;
                background-color:#222222;
            }

            #hourhand
            {
                margin-left:147px;
                margin-top:70px;
                width:7px;
                height:80px;
                background-color:#000000;
            }           
        </style>


The CSS class hand is a style that encompasses all the properties that the hour hand, minute hand and second hand have in common.
- position:absolute,z-index:10 because you need these guys to overlap, and stay above the segments.
- transform-origin:50% 100% because each of these "hands" is actually a rectangular div which will be rotated by its bottom center,
- transform:rotate(0deg) is the default rotation for all of them. This needs to be specified because it will change later.

The hourhand, minutehand and secondhand divs all have different heights, widths and background colors. And because they have different heights and widths, they have different margin-top and margin-left properties too. The end result is that their center bottom has to be pointing dead center of the clockface div. The math is pretty simple, figure it out yourself.

This is what you should have right now. Of course, it's not displaying the time correctly, unless it happens to be 12 noon or 12 midnight for you. We'll move on to that next.


Displaying the correct time at the start

Modify your startclock() function like so. This declares the nowdate variable, which is set to the current date and time. Also the variables secondpos, minutepos and hourpos, which will hold the values for degrees of the rotation of your hands.

For more on JavaScript Date functions, check the following link out: (http://www.w3schools.com/js/js_dates.asp)

function startclock()
{
    var nowdate=new Date();
    var secondpos,minutepos,hourpos;


    for (i=1;i<=12;i++)
    {
        if (i<12)
        {
            document.getElementById("segment"+i).style.transform="rotate("+(i*30)+"deg)";
            document.getElementById("segmentno"+i).style.transform="rotate(-"+(i*30)+"deg)";
            document.getElementById("segment"+i).style.webkitTransform="rotate("+(i*30)+"deg)";
            document.getElementById("segmentno"+i).style.webkitTransform="rotate(-"+(i*30)+"deg)";              
        }

        document.getElementById("segmentno"+i).innerHTML=i;
    }
}


Now this. Every second, the second hand moves by 6 degrees. How to we figure that? Well, the second hand moves 60 times in one revolution. One revolution is 360 degrees. So 360/60 is 6! So here we get the current value of nowdate's seconds multiplied by 6 and assign the value to the variable secondpos. If the result is 360, we don't need to move the second hand at all. Otherwise, we move the second hand by secondpos degrees.
function startclock()
{
    var nowdate=new Date();
    var secondpos,minutepos,hourpos;

    for (i=1;i<=12;i++)
    {
        if (i<12)
        {
            document.getElementById("segment"+i).style.transform="rotate("+(i*30)+"deg)";
            document.getElementById("segmentno"+i).style.transform="rotate(-"+(i*30)+"deg)";
            document.getElementById("segment"+i).style.webkitTransform="rotate("+(i*30)+"deg)";
            document.getElementById("segmentno"+i).style.webkitTransform="rotate(-"+(i*30)+"deg)";              
        }

        document.getElementById("segmentno"+i).innerHTML=i;
    }

    secondpos=nowdate.getSeconds()*6;
    secondpos=(secondpos==360?0:secondpos);

    document.getElementById("secondhand").style.transform="rotate("+secondpos+"deg)";

    document.getElementById("secondhand").style.webkitTransform="rotate("+secondpos+"deg)";

}


The logic is repeated for minutes.
function startclock()
{
    var nowdate=new Date();
    var secondpos,minutepos,hourpos;

    for (i=1;i<=12;i++)
    {
        if (i<12)
        {
            document.getElementById("segment"+i).style.transform="rotate("+(i*30)+"deg)";
            document.getElementById("segmentno"+i).style.transform="rotate(-"+(i*30)+"deg)";
            document.getElementById("segment"+i).style.webkitTransform="rotate("+(i*30)+"deg)";
            document.getElementById("segmentno"+i).style.webkitTransform="rotate(-"+(i*30)+"deg)";              
        }

        document.getElementById("segmentno"+i).innerHTML=i;
    }

    secondpos=nowdate.getSeconds()*6;
    secondpos=(secondpos==360?0:secondpos);

    minutepos=nowdate.getMinutes()*6;
    minutepos=(minutepos==360?0:minutepos);


    document.getElementById("secondhand").style.transform="rotate("+secondpos+"deg)";
    document.getElementById("minutehand").style.transform="rotate("+minutepos+"deg)";

    document.getElementById("secondhand").style.webkitTransform="rotate("+secondpos+"deg)";
    document.getElementById("minutehand").style.webkitTransform="rotate("+minutepos+"deg)";
}


Next, the hour hand. This one is slightly different. The time operates on a 24 hour format, so you need to figure out which number the hour hand points towards. For instance, whether the hour 4 or 16 (4am or 4pm), the hour hand should still point towards "4".

So first, we get the number of hours in the nowdate variable. If the value's greater than 12, subtract 12. Then multiply by 30. Why 30? Because there are 12 numbers, each one separated by 30 degrees! If the result is 360, change it to 0, because that would mean the hour hand doesn't budge.

But that's not all. The hour hand doesn't point right at the number unless the minute hand is pointing at 12, ie on the hour. So we figure out how much more the hour hand needs to move. Each number is separated by 30 degrees. So we take the minute hand's position and divide by 360 to obtain the ratio. The ratio is then multiplied by 30, and the result added to hourpos.
function startclock()
{
    var nowdate=new Date();
    var secondpos,minutepos,hourpos;

    for (i=1;i<=12;i++)
    {
        if (i<12)
        {
            document.getElementById("segment"+i).style.transform="rotate("+(i*30)+"deg)";
            document.getElementById("segmentno"+i).style.transform="rotate(-"+(i*30)+"deg)";
            document.getElementById("segment"+i).style.webkitTransform="rotate("+(i*30)+"deg)";
            document.getElementById("segmentno"+i).style.webkitTransform="rotate(-"+(i*30)+"deg)";              
        }

        document.getElementById("segmentno"+i).innerHTML=i;
    }

    secondpos=nowdate.getSeconds()*6;
    secondpos=(secondpos==360?0:secondpos);

    minutepos=nowdate.getMinutes()*6;
    minutepos=(minutepos==360?0:minutepos);

    hourpos=nowdate.getHours();
    hourpos=(hourpos>12?hourpos-12:hourpos)*30;
    hourpos=(hourpos==360?0:hourpos);
    hourpos=hourpos+((minutepos/360)*30);


    document.getElementById("secondhand").style.transform="rotate("+secondpos+"deg)";
    document.getElementById("minutehand").style.transform="rotate("+minutepos+"deg)";
    document.getElementById("hourhand").style.transform="rotate("+hourpos+"deg)";

    document.getElementById("secondhand").style.webkitTransform="rotate("+secondpos+"deg)";
    document.getElementById("minutehand").style.webkitTransform="rotate("+minutepos+"deg)";
    document.getElementById("hourhand").style.webkitTransform="rotate("+hourpos+"deg)";
}


There you go, now it tells the time! But since it's not moving, it only tells the correct time twice a day. Heh heh.


Making the hands move

Now this is simple. We could simply make this program calculate the time and display the positions of the hands every second. But that's lazy and inefficient. The minute and hour hands only move once a minute. So let's add the move_secondhand() function, and set it to an interval of 1 second.

Check out this link to learn more about JavaScript Timer functions! (http://www.w3schools.com/js/js_timing.asp)
    document.getElementById("secondhand").style.webkitTransform="rotate("+secondpos+"deg)";
    document.getElementById("minutehand").style.webkitTransform="rotate("+minutepos+"deg)";
    document.getElementById("hourhand").style.webkitTransform="rotate("+hourpos+"deg)";
  
    setInterval(function(){move_secondhand();},1000);
}

function move_secondhand()
{

}


First, we get the current position of the second hand. For this, because we'll be doing this repeatedly for different hands, we'll make the getcurrentpos() function. This function accepts the name of the object to be moved, and returns a number that says how many degrees this element is currently rotated by. For example, if the current value of the secondhand div's transform property is "rotate(20deg)", we strip out "rotate(" and "deg)" to give you the number.

Check out JavaScript's String replace() method. (http://www.w3schools.com/jsref/jsref_replace.asp)
    document.getElementById("secondhand").style.webkitTransform="rotate("+secondpos+"deg)";
    document.getElementById("minutehand").style.webkitTransform="rotate("+minutepos+"deg)";
    document.getElementById("hourhand").style.webkitTransform="rotate("+hourpos+"deg)";
  
    setInterval(function(){move_secondhand();},1000);
}

function getcurrentpos(varobj)
{
    var currentpos=document.getElementById(varobj).style.transform+document.getElementById(varobj).style.webkitTransform;
    currentpos=currentpos.replace("rotate(","");
    currentpos=currentpos.replace("deg)","");
    currentpos=parseInt(currentpos);

    return currentpos;
}


function move_secondhand()
{
    var pos=getcurrentpos("secondhand");
}


Then we increment that value by 6. The second hand moves by 6 degrees every time, remember? And then we rotate the secondhand div.
function move_secondhand()
{
    var pos=getcurrentpos("secondhand");
    pos+=6;

    document.getElementById("secondhand").style.transform="rotate("+pos+"deg)";
    document.getElementById("secondhand").style.webkitTransform="rotate("+pos+"deg)";

}


But wait, there's more. If the second hand has moved to 360 degrees, we reset the rotation to 0, and then call the move_minutehand() function. Because once the second hand moves to 12, the minute hand moves!
function move_secondhand()
{
    var pos=getcurrentpos("secondhand");
    pos+=6;

    if (pos==360)
    {
        pos=0;
        move_minutehand();
    }


    document.getElementById("secondhand").style.transform="rotate("+pos+"deg)";
    document.getElementById("secondhand").style.webkitTransform="rotate("+pos+"deg)";
}

function move_minutehand()
{

 
}


So the first part of the move_minutehand() function is almost identical to the move_secondhand() function...
function move_minutehand()
{
    var pos=getcurrentpos("minutehand");
    pos+=6;

    if (pos==360)
    {
        pos=0;
    }

    document.getElementById("minutehand").style.transform="rotate("+pos+"deg)";
    document.getElementById("minutehand").style.webkitTransform="rotate("+pos+"deg)"; 
 
}


...albeit with a slight difference. The hour hand only moves when the minute hand has travelled in multiples of 72 degrees. That means it only moves when the minute hand has moved 72, 144, 216, 288 or 360 degrees. Take note, that's 5 instances. Why's that? Because in the space of one hour, the hour hand only moves 30 degrees. And since each movement is 6 degrees, that means it only moves 30/6=5 times. 360 degrees divided by 5 (5 instances, remember?) is 72 degrees. So for every 72 degrees the minute hand travels, the hour hand moves.
function move_minutehand()
{
    var pos=getcurrentpos("minutehand");
    pos+=6;

    if (pos%72==0)
    {
        move_hourhand();
    }


    if (pos==360)
    {
        pos=0;
    }

    document.getElementById("minutehand").style.transform="rotate("+pos+"deg)";
    document.getElementById("minutehand").style.webkitTransform="rotate("+pos+"deg)";  
}

function move_hourhand()
{

}


And of course, the move_hourhand() function performs pretty much like the others, except that it doesn't cause any other parts of the clock to move.
function move_hourhand()
{
    var pos=getcurrentpos("hourhand");
    pos+=6;

    if (pos==360)
    {
        pos=0;
    }

    document.getElementById("hourhand").style.transform="rotate("+pos+"deg)";
    document.getElementById("hourhand").style.webkitTransform="rotate("+pos+"deg)";

}


There you go, check this demo out!
















Now, wasn't that a handy exercise?
T___T

Thursday 19 May 2016

Film Review: Grace

Yet another Social Media-themed horror movie? Is this turning into a thing?

When Grace, also known by its Thai title as Awasarn Lok Suay, appeared in theaters here, I was leery of throwing away another twelve bucks and another couple hours of my time after what happened with Friend Request. Only one thing spurred me on. Grace is a Thai horror thriller. And no one does horror like the Thais. Only the Japs and Koreans come a close second.


Grace is meant as a cautionary tale about the hazards of Internet popularity, with Facebook again one of the driving forces behind the plot. But by the third blood-splattered corpse, you'll probably forget about all that and enjoy the violence. Because no one does violence like the Thais.

There's also a fair bit of very unsexy sex, most of it off-screen, but in a context horrific enough to capture the imagination. Because no one does rough sex like - well, you get the idea.

Warning - mild spoilers ahead, sexual scenes and violence

Because I think this movie is worth a watch, I'll endeavor to keep spoilage to a minimum. Not that there's all that much plot in there. It's all about the execution, see? (Execution, geddit? Hur hur)

The Premise

Care is an Internet idol, whose existence seems to be defined by the number of comments, Likes and Shares on her Facebook page and blog, Summer Trick. Ple, her best friend and online fiction writer, maintains that blog.

Grace is a former Internet idol for reasons which you will discover during the show. In her jealousy, she and her accomplice Jack kidnap Care and Ple, and the torture begins.

The Characters

Apinya Sakuljaroensuk as the titular character, an Internet idol fallen from grace (snicker). She was cute enough, but it was the acting that wowed me. Got a little over-the-top towards the end, but perhaps that's the nature of the business when playing psycopaths.

Nuttasit Kotimanuswanich as Jack, Grace's pervy and lecherous companion who likes to leer at cute girls in Cosplay uniforms and jerk off to Hentai porn. What an amazingly loathsome performance. One-dimensional, sure. But he fit the role so well, I hated him way before he did anything nasty.

Napasasi Surawan as Care, the annoyingly perky and cute Internet idol. Not sure I blame Grace for wanting to torture and kill her. Within minutes of watching her crap,I was fantasizing about strangling her myself. Jack does filthy things to her during the show, and even then I'm not sure I sympathize. She definitely gets the lion's share of the torture. On-screen punching bag, that's the character.

Latthgarmon Pinrojnkeerathi as Ple. The role took a back seat to Care, and it's something of a surprise at the end when she gets the spotlight shone on her, and she gets her turn as psycho bitch. But by then, one gets the sense that the movie has gone on just a wee bit too long.

Unknown actor as Nay, the shy and quiet nerd who is Care and Ple's photographer and unfortunately gets a serious case of "wrong place, wrong time". He wasn't even the target, and he was just minding his own business.

Unknown actress as Pim, one of the villains of the film, who contribute to Grace's eventual derangement with a cruel prank taken to extremes.

Unknown actor as Earth, the obligatory pretty boy role that turns out to be Grace's undoing. He was pretty enough, but bland. With a capital B.

The Mood

Mostly bouncy and cheerful in the beginning as we walked through the sheer joy that is Care's seemingly perfect life. Got bloody midway through, with loads of tension throughout. Somewhere at the end, while remaining dark, the violence got a bit corny. Be warned though, that this tale is not told in a totally linear way. Scenes are intercut with flashbacks which aren't obviously so, thus a bit of confusion might result.

What I liked

The acting - have I mentioned that Nuttasit Kotimanuswanich and Apinya Sakuljaroensuk really got their game faces on for this one? Apinya in particular. She really pulled out a whole range of expressions - meek and awkward at first, confident later, then crushed and depressed followed by cynical, sadistic and homicidal. As mentioned earlier, the entire movie is intercut with flashbacks, and it's not always clear when a certain scene is happening. Apinya takes care of that very well with the on-screen contrasts in personality.

The glorious, glorious violence. Now if there's something Thai horror always delivers, it's this.

What I didn't

The whole gang-rape/Internet shaming thing that eventually led to Grace wandering up the psycho path. I get why it was a necessary plot device. It just felt totally overused to me and I could see it coming a mile off. Having seen it in Shutter and more recently, Senior, this was a serious case of deja vu. Still, compelling enough as a reason to start killing people, I suppose.

Cosplay's not really my thing. Again, I get why it was a necessary plot device, with Grace being a seamstress and into making costumes and all. I get it, yes. But it does nothing for me and I just don't have to particularly like it.

The ending, with the chase scene between Ple and Grace, felt awkward and forced, like the movie was extending way past its closing time.

Conclusion

Moral of the story: Don't piss off Thai women. They're fucking nuts.

My Rating

7 / 10

Watchable. Take a stab at it!
T___T

Friday 13 May 2016

Ten Job Ad Descriptions to run away from, really fast

Every six months, I make it a point to survey the market and read job advertisements. Not because I want to leave my job, but because I want to keep my finger on the pulse of the web industry. However, due to being hellishly occupied with work and school, I shelved this for pretty much the whole of 2015.

When I finally got back to it recently, I was in for a rude shock. Appalled does not even begin to cover it. Was it me, or had the standards of job advertisements in the web industry fallen shockingly low since I last checked? That was when I started compiling this list of job ad sins. It was a bit of a struggle deciding on a title for this. "Ten ways to look like a complete amateur on a job ad"? "Ten ways to ensure no self-respecting web developer applies for your company, ever"?

No, I will, for the most part, not be including live examples. Because if I did, let me assure you that this list would not be stopping at ten. I will, however, do some paraphrasing.


1. Horrible grammar

This one's a bit of a no-brainer. The odd spelling error here and there is forgivable - actually, hell no it isn't. Not in light of the fact that there's spellcheck and all sorts of nifty tools available these days, and the fact that you're generally supposed to proofread your shit before making it live. That said, I'm prepared to overlook the odd spelling error or two. But when you add bad punctuation and inconsistent capitalization into the mix, I am not going to be regarding your job ad with anything other than derision.

Learn to spell, will ya?

I am a professional, and good golly, I expect - no, demand - a reasonable standard of English from my prospective employers. On the other hand, web developers whose first language isn't English should not mind too much - they probably won't even notice.

Come on. I know us web developers don't earn big money, but calling us "developoors" is a gross exaggeration.
MNC seeks an experienced web developoor.

More examples...
- applicants are expected to have proificiency in Java and Ruby.
- You will be working on our propreitory database management system.

The cruelest irony
- Should conversed well in English and Bahasa.


2. Glaring technical errors

The forward slash is meant to be used when certain things belong together, or are interchangeable.

An example would be
- HTML5/CSS3
- LESS/SASS
- MySQL/Sql Server/Oracle
- XML/JSON

But not this. I'm not sure any web developer wants to work for people who don't understand that Java and JavaScript don't belong together.
- Java/JavaScript
- SDLC/MVC

Odd one out.

And then you have this beauty...
- you should be well-versed in programming languages such as AJAX, ASP.NET, jQuery, MySQL, HTML, Python

Of the above, only one could be classified as a programming language. Don't laugh. It's on so many job ads, in varying permutations, that it stopped being funny a while back. Developers generally want to work for, or alongside people who know what they're doing.

Sure, perhaps a non-technical person such as HR wrote the job ad. Pray tell, what kind of company has so little common sense that it would allow a non-technical person to draft a technical job description?


3. Meaningless requirements

You get this in a huge number of job ads, and they all mean the same thing - absolute squat.

You should be:
- self-motivated
- self-starter
- creative, out-of-the-box thinker
- enthusiastic
- detail-oriented
- a great team player

These things are nigh impossible to prove. Everyone and his dog thinks he's creative and a self-starter. No web developer is going to tell you "I'm boring and unimaginative, and I need the occasional pep talk to keep me motivated".

An out-of-the-box developer?

How is a web developer supposed to prove enthusiasm? Have a GitHub account and contribute to the open source community? Well, then perhaps your job ad should have said this...
You should have a GitHub account which showcases your contributions to the open source community.

See? Say what you actually mean. Wasn't that easy? And way more meaningful than copying some clever-sounding buzzwords from everyone else's job ad?


4. Requirement creep

And sometimes, you get a job description like this. The requirements are so numerous, it makes one wonder how it is humanly possible for any one individual to have them all.
- Well-versed in CMSs such as WordPress and Drupal.
- Expertise in e-Commerce technologies.
- Comfortable with both Windows and Linux environment.
- Have previously participated in projects through at least two successful SDLCs.
- Extensive experience in database systems, preferably SQL Server.
- Mastery of Photoshop and other image-editing tools.
- Expertise in HTML and CSS, and CSS preprocessors like LESS and SASS.
- Must be well-versed in design and UI.
- Mastery of SEO and internet marketing.
- Proficiency in JavaScript and JavaScript libraries like jQuery and MooTools, as well as AngularJS, React and Meteor.
- Deep knowledge of C# is a must.
- Experience in other programming languages such as Java and Ruby.
- Have written apps for both iOS and Android.
- Should be able to deliver twice as fast as the average developer.
- Typing speed of at least 80 wpm.

We call this "requirement creep" because it probably started out as a small and reasonable list of technologies the new hire is supposed to be proficient in, and somewhere along the way, some bright spark remarked "it would be better for him to have deep knowledge as opposed to merely proficiency in C#" or "knowing AngularJS isn't enough - we do a bit of React too, and some Meteor", or even "it would be nice if he was a fast typer as well".

What else did you miss out? Should he fart unit tests and burp functioning code, too?

Santa's in town,
and he'll grant all
your wishes.
I get it - you want the best possible value for your money. So does everyone else. But bear in mind that such a talented individual will probably not be applying for a job - you'll have to poach him from somewhere else and extract him from his current employer's cold dead fingers. And that's if you could afford him.


5. Stupid descriptions

This one really makes me cringe.
Groovy, exciting startup looking for PHP Jedi whose Force is strong in the code.

Looking for a ninja?

Seriously, don't be an idiot. This goes double for job ads with descriptions like "Database Guru", "Digital Samurai", "Code Ninja", "Software Wizard", "Rockstar Programmer", "Superstar Developer" and so on. The web development industry already seems to have problems being taken seriously - people seem to think all we do is make websites. And buddy, you're not helping.

If this is an attempt to appear witty, stop trying so hard. Because it's producing the opposite effect.



6. Too many words

Being grammatically and technically correct won't save you if you don't know when to stop writing your description. Some descriptions are so convoluted with overly long words that by the time the developer's finished reading it all, he's lost the sense of what the ad was trying to say.

Wall of Text effect.

Take this for example
You will be expected to gather clients' requirements through regular meetings and collate them into system specifications for your fellow developers and document these requirements using accepted conventions to illustrate data flow and entity relationships. Upon which you will implement these requirements in proper object-oriented design following industry-accepted best practices and...

Oh snap, where was I? I probably nodded off after the second sentence. Couldn't all that have been adequately condensed into this?
Must be familiar with the Software Development Life Cycle.

Everybody wants to sound like they know stuff, and that unfortunately tends to translate to using ten sentences when you only need ten words. Well, here's something else for you to know - keep it short, and cut the crap.



7. Obsession with years of experience

I understand that in many industries, years of experience is a relevant metric. But where web development - indeed, any kind of software development - is concerned, all bets are off. Web development is such a wide and varied field that no two web developers are likely to have the exact same skillset or progression. Unlike, say, bricklaying. It would be a safe bet to say that a bricklayer with 10 years' experience would have developed muscles pertinent to mixing cement and laying bricks.

EDITOR'S NOTE: If you are a bricklayer and feel that your job scope is way more complex than just mixing cement and laying bricks, please accept my humble apologies.

But for something like this...
- must have 5+ years' experience in software development, at least 2 in mobile environment

It takes someone of average intelligence to learn the basics of software development anywhere between 6 months to a year, perhaps less for those among us who are more gifted. Beyond that, a developer could spend the next few years just reusing those basics and getting better at them, or branching out into other aspects of software development - different technologies, different methodologies, and so on. Just what is having "5+ years' experience in software development" supposed to prove?

Think this guy has
enough experience?

This next one takes that obsession to a new extreme.
- 7 years experience in Java.
- 4 years of experience in Windows server environment.
- 5 years or more in Social Media technologies.
- At least 3 years using C++
- 2 years or more in HTML/CSS/JavaScript
- 2 years or more in...

Or for the utterly ridiculous
- 5 years or more in HTML5.

HTML5's specification was stable in 2014. It first became a thing back in 2008. It is now 2016. In order for the applicant to have 5 years' experience in HTML5, he would have to be one of the founding members of the HTML5 specification. Let's say I cut the job ad some slack and assume the poster meant HTML instead of HTML5. This is HTML, dude. A school kid could learn HTML in a few weeks. Exactly what is an individual with 5 years' experience in HTML supposed to do for you? Do nothing but write EDMs? Write a book on the history of Netscape, maybe?

HR needs to stop trying to apply general rule-of-thumb to web development. It doesn't work.



8. Needing that degree

Many job ads seem more interested in the web developer's academic qualifications rather than his ability.
- Candidate should possess a Bachelor's degree in Computer Science, Information Technology or any other related discipline.

Having one degree and three diplomas, I probably should be the last to complain about this. But the fact is that this betrays a lack of understanding as to how web development works. A vast percentage of the web is created by self-taught developers with little to no formal computer science education. Why's that? Because you don't need a goddamn Computer Science degree to do web development. There's plenty of learning material on (gasp!) the web.

Degrees FTW!

A formal Computer Science degree simply gives a better idea of what the developer should have learned in school, but even that is a poor gauge for what skills he has kept current. I remember learning data structures and memory management and Boolean Algebra when I was a teenager, mugging for exams. How much of it have I actively used in web development? Pitifully little. Academic qualifications mean very little, especially if said qualifications were earned ten years ago and you're in a field that evolves every couple years.



9. Laundry list

I wrote about this back in February in response to something the managing director of Fixx Digital said, but it bears repeating.

Some job ads have a very specific list of skills they want their web developer to have. Way too specific.
- proficient in PHP 5.5 and above.
- knowledge of CodeIgniter.
- familiar with MySQL version 6.0 onwards.

I get it. I do! You want someone to fit into that pigeonhole, someone you don't have to spend time training, who may just up and leave anyway. I've said it before and I'll say it again - this is terribly shortsighted. You're missing out on potentially great hires as opposed to people who simply happen to have that specific skillset.

Check those boxes!

Try this instead.
- proficient in PHP, preferably version 5.5 and above.
- knowledge of MVC frameworks such as CodeIgniter.
- familiar with SQL databases such as MySQL.

See what I did there? The general skill was listed there, followed by a preference or example. This means that candidates applying for the job will at least have the foundation rather than the specific skillset. And if they don't know the specific technology, they can always learn. They have the foundation, don't they?

If you're not willing to invest in people, why should people invest the best years of their youth in your company?



10. Outright douchebaggery

I don't actually want to flog that dead horse and bring to life the specter of Sugar Technologies' disastrous job ad back in 2014, but this serves as a great example of what to write if you want to piss developers off.

Watch the attitude.


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.

A certain amount of arrogance is healthy. But if you're going to act like people should be grateful to be working for you, you'd better be more than just another start-up out of millions in sunny Singapore. And yes, almost all start-ups will claim they are that special. Let's just see who's left standing after the next few years, shall we?

At the end of the day...

Your company's job ad affects the kind of applicants you get, which in turn affects the kind of employees you eventually get. Many job ads I see could be worded a little more carefully and some of them just need to be killed with fire.

Web developer looking for a halfway decent job ad,
T___T