Sunday, 29 September 2019

Web Tutorial: Ada Lovelace Day Generator

We celebrate Ada Lovelace Day next month!

Ada Lovelace Day is a day dedicated by computer geeks and mathematicians worldwide, to a woman who is commonly recognized as the mother of modern computing, Ada Lovelace. It falls on the second Tuesday of October, and while it's nice and easy to remember, sometimes we just want the exact date for any given year.

That's where today's web tutorial comes in! Using ReactJS, we'll generate the exact date for Ada Lovelace Day from any user input year.

We begin with a HTML/ReactJS layout. Stuff will generally be in a div with an id of appContainer.
<!DOCTYPE html>
<html>
    <head>
        <title>Ada Lovelace Day</title>

        <style>

        </style>

        <script src="https://unpkg.com/react@16/umd/react.development.js"></script>
        <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
        <script src="https://unpkg.com/babel-standalone@6.26.0/babel.js"></script>
    </head>

    <body>
        <div id="appContainer">

        </div>

        <script type="text/babel">

        </script>
    </body>
</html>


Now, in appContainer, we'll insert two more divs, with ids of adaContainer and genContainer, respectively.
        <div id="appContainer">
            <div id="adaContainer">

            </div>

            <div id="genContainer">

            </div>   
        </div>


genContainer will hold the components, but adaContainer will hold this lovely little image I found.

ada.png

So let's start styling. Set all divs to have a red outline. Then give appContainer this height and width, and align it to the middle of the screen.
        <style>
            div {outline: 1px solid #FF0000;}
           
            #appContainer
            {   
                height: 500px;           
                width: 450px;
                margin: 5% auto 0 auto;
            }   
        </style>


OK so far? Great.


Now, make sure both adaContainer and genContainer have 100% width. They'll have different heights. adaContainer will have a deep grey bottom border while genContainer will have a thicker light grey top border.
        <style>
            div {outline: 1px solid #FF0000;}
           
            #appContainer
            {   
                height: 500px;           
                width: 450px;
                margin: 5% auto 0 auto;
            }

            #adaContainer
            {   
                height: 300px;           
                width: 100%;
                border-bottom: 1px solid #444444;
            }

            #genContainer
            {   
                border-top: 2px solid #CCCCCC;
                height: 200px;           
                width: 100%;
            }       
        </style>


The special effect isn't all that apparent due to the red outline, but never mind for now.


Now use the image as adaContainer's background. Set the background-size property to contain. The image should be aligned bottom.
            #adaContainer
            {   
                height: 300px;           
                width: 100%;
                border-bottom: 1px solid #444444;
                background: url(ada.png) center bottom no-repeat;
                background-size: contain;
            }


Oh, we're off to a great start!


Now for some serious business!

In the script tag, declare the class AdaLovelaceDay with a constructor method, constructor(). In it, call the super() function using props as an argument (so that we can use this to set state), then set state with two properties - year (default 0) and adaLovelaceDay (default empty string). The class should also have a componentDidMount() method, because we want stuff to happen on page load. And of course, we'll have a render() method which returns the component markup.
        <script type="text/babel">
            class AdaLovelaceDay extends React.Component
            {
                constructor(props)
                {
                      super(props);
                      this.state =
                      {
                          "year": 0,
                          "adaLovelaceDay": ""
                      };
                  }

                componentDidMount()
                {

                }

                render()
                {
                    return (

                    );               
                }
            }

            ReactDOM.render(<AdaLovelaceDay />, document.getElementById("genContainer"));
        </script>


Bind the showAdaLovelaceDayForYear() method to the constructor, then declare the method.
                constructor(props)
                {
                      super(props);
                      this.state =
                      {
                          "year": 0,
                          "adaLovelaceDay": ""
                      };
                      this.showAdaLovelaceDayForYear = this.showAdaLovelaceDayForYear.bind(this);
                  }

                showAdaLovelaceDayForYear(renderYear)
                {

                }

                componentDidMount()
                {

                }


What the showAdaLovelaceDayForYear() method does is accept the parameter renderYear, which is a four-digit number representing the year for which we want to find the second Tuesday of October. So we start by declaring a variable, day, which we set to 1. And the variable tuesdays, which we set to 0.
                showAdaLovelaceDayForYear(renderYear)
                {
                    var day = 1;
                    var tuesdays = 0;
                }


Use a While loop, set to continue only if tuesdays is less than 2.
                showAdaLovelaceDayForYear(renderYear)
                {
                    var day = 1;
                    var tuesdays = 0;

                    while (tuesdays < 2)
                    {

                    }
                }


Declare a variable, october. Set it to a date using the Date() function, and passing in the arguments renderYear, 9 and day. Since day is 1, you've basically set october to the first day of October (we use 9 because the count starts at 0, so the 10th month, October, is represented by 9) in the year renderYear.
                showAdaLovelaceDayForYear(renderYear)
                {
                    var day = 1;
                    var tuesdays = 0;

                    while (tuesdays < 2)
                    {
                        var october = new Date(renderYear, 9, day);
                    }
                }


Use the getDay() method on october. If the result is 2, which means it's a Tuesday, increment tuesdays.
                showAdaLovelaceDayForYear(renderYear)
                {
                    var day = 1;
                    var tuesdays = 0;

                    while (tuesdays < 2)
                    {
                        var october = new Date(renderYear, 9, day);
                       
                        if (october.getDay() == 2) tuesdays++;
                    }
                }


If tuesdays is still less than 2 at this point, increment day. So this continues until you reach the second Tuesday of October, and by that time, day would be the... well, you get the idea.
                showAdaLovelaceDayForYear(renderYear)
                {
                    var day = 1;
                    var tuesdays = 0;

                    while (tuesdays < 2)
                    {
                        var october = new Date(renderYear, 9, day);
                       
                        if (october.getDay() == 2) tuesdays++;

                        if (tuesdays < 2) day++;
                    }
                }


The rest is fluff. Declare the variable adaLovelaceDay and set it to the value of day, then depending on what day of the month it is, append either "st", "nd" or "th" to it. It's not absolutely necessary, but it's pretty, so let's do it!
                showAdaLovelaceDayForYear(renderYear)
                {
                    var day = 1;
                    var tuesdays = 0;

                    while (tuesdays < 2)
                    {
                        var october = new Date(renderYear, 9, day);
                       
                        if (october.getDay() == 2) tuesdays++;

                        if (tuesdays < 2) day++;
                    }

                    var adaLovelaceDay = day;
                    if (day == 1 || day == 21 || day == 31)
                    {
                        adaLovelaceDay += "st";
                    }
                    else if (day == 2 || day == 12)
                    {
                        adaLovelaceDay += "nd";
                    }
                    else
                    {
                        adaLovelaceDay += "th";
                    }
                }


Finally set state. Use the setState() method to modify the properties year to renderYear and adaLovelaceDay to adaLovelaceDay.
                showAdaLovelaceDayForYear(renderYear)
                {
                    var day = 1;
                    var tuesdays = 0;

                    while (tuesdays < 2)
                    {
                        var october = new Date(renderYear, 9, day);
                       
                        if (october.getDay() == 2) tuesdays++;

                        if (tuesdays < 2) day++;
                    }

                    var adaLovelaceDay = day;
                    if (day == 1 || day == 21 || day == 31)
                    {
                        adaLovelaceDay += "st";
                    }
                    else if (day == 2 || day == 12)
                    {
                        adaLovelaceDay += "nd";
                    }
                    else
                    {
                        adaLovelaceDay += "th";
                    }

                    this.setState({"year": renderYear, "adaLovelaceDay" : adaLovelaceDay});
                }


In the componentDidMount() method, run the showAdaLovelaceDayForYear() method, passing in the current year as an argument. So upon page load, the first thing this script does is get Ada Lovelace Day for the current year.
                componentDidMount()
                {
                    this.showAdaLovelaceDayForYear((new Date()).getFullYear());
                }


That's all well and good, but...

Yeah, we're getting there. Since we've set the state and all, we'll need to display it. That's where render() comes in! It will return this div, id adaText, with the following template string.
                render()
                {
                    return (
                            <div className="adaText">
                                Ada Lovelace Day is on <b>{this.state.adaLovelaceDay} October</b>.
                            </div>
                    );               
                }


Style adaText. Just do what looks nice for you.
            #genContainer
            {   
                border-top: 2px solid #CCCCCC;
                height: 200px;           
                width: 100%;
            }   

            .adaText
            {
                height: 1.5em;
                width: 80%;
                margin: 0 auto 0 auto;
                padding-top: 1em;
                font-size: 16px;
                font-family: arial;
                text-align: center;
            }


And here we go! Ada Lovelace Day for 2019 is... 8th October!


Hold on, we're not done!

What's the point if we only get to forecast the current year? This would be a lot more useful if we included controls in the interface to input other years. We'll make the numbers of each four-digit year mutable via the interface.

In the render() method, declare an empty array, digitGens. Use a For loop to run 4 times.
                render()
                {
                    var digitGens = [];

                    for (var i = 0; i <= 3; i++)
                    {

                    }

                    return (
                            <div className="adaText">
                                Ada Lovelace Day is on <b>{this.state.adaLovelaceDay} October</b>.
                            </div>
                    );               
                }


On every iteration, push a new element into the digitGens array. It will be an object containing the properties number and id. number is set to each digit of the four digit year stored in the state. We'll first need to convert it to a string, then extract the character at the appropriate position. id is set to the current value of i in the For loop.
                render()
                {
                    var digitGens = [];

                    for (var i = 0; i <= 3; i++)
                    {
                        digitGens.push
                        (
                            {
                                "number": this.state.year.toString().charAt(i),
                                "id": i
                            }
                        );
                    }

                    return (
                            <div className="adaText">
                                Ada Lovelace Day is on <b>{this.state.adaLovelaceDay} October</b>.
                            </div>
                    );               
                }


While we're here, give each element in digitGens a inc() and dec() method. That method will call this component's changeYear() method, passing in the argument true for incrementing, and false for decrementing. (I know, we haven't created the changeYear() method yet. Soon!) Also, since this would be out of scope inside that For loop, we first declare the variable functionParent and set it to the value of this, and then use functionParent in place of this in the For loop.
                render()
                {
                    var digitGens = [];
                    var functionParent = this;

                    for (var i = 0; i <= 3; i++)
                    {
                        digitGens.push
                        (
                            {
                                "number": this.state.year.toString().charAt(i),
                                "id": i,
                                "inc": function() {functionParent.changeYear(true);},
                                "dec": function() {functionParent.changeYear(false);}
                            }
                        );
                    }

                    return (
                            <div className="adaText">
                                Ada Lovelace Day is on <b>{this.state.adaLovelaceDay} October</b>.
                            </div>
                    );               
                }


Now, declare the variable digitGen (note the singular) and set it to the value of a map() method run on the digitGens array.
                render()
                {
                    var digitGens = [];
                    var functionParent = this;

                    for (var i = 0; i <= 3; i++)
                    {
                        digitGens.push
                        (
                            {
                                "number": this.state.year.toString().charAt(i),
                                "id": i,
                                "inc": function() {functionParent.changeYear(true);},
                                "dec": function() {functionParent.changeYear(false);}
                            }
                        );
                    }

                    var digitGen = digitGens.map(
                        (item, key) =>
                        {
                            return (

                            );
                        }
                    );

                    return (
                            <div className="adaText">
                                Ada Lovelace Day is on <b>{this.state.adaLovelaceDay} October</b>.
                            </div>
                    );               
                }


We're going to use the digitGens array to generate a series of four number-scrollers mini-components. So, what happens is that a div with class of yearGen (note that we use className in order to avoid confusing the Babel compiler) contains two divs. The first div is styled using genDigit and contains the number.
                    var digitGen = digitGens.map(
                        (item, key) =>
                        {
                            return (
                                <div className="yearGen">                                   
                                    <div className="genDigit">
                                        {item.number}
                                    </div>   
                                    <div>
                   
                                    </div>
                                </div>
                            );
                        }
                    );


The second div is styled using buttons and has an id of digit plus the current element's id property. It contains two buttons. The buttons have data attributes, namely, i. Set that value to the id property of the current element. The onClick event handlers in each button will call the current item's inc() and dec() methods respectively. The button's text are HTML symbols ▲ and ▼.
                    var digitGen = digitGens.map(
                        (item, key) =>
                        {
                            return (
                                <div className="yearGen">                                   
                                    <div className="genDigit">
                                        {item.number}
                                    </div>   
                                    <div id="digit{item.id}" className="buttons">
                                        <button data-i={item.id} onClick={item.inc}>&#9650;</button>
                                        <button data-i={item.id} onClick={item.dec}>&#9660;</button>                 
                                    </div>
                                </div>
                            );
                        }
                    );


Next, we enclose the returned div in an outer div, and style the outer div using genContent. Put the entire digitGen component in it, just before the div.
                    return (
                            <div className="genContent">
                                {digitGen}

                                <div className="adaText">
                                    Ada Lovelace Day is on <b>{this.state.adaLovelaceDay} October</b>.
                                </div>
                            </div>
                    ); 


Don't forget to create the changeYear() method! Leave it blank, for now.
                showAdaLovelaceDayForYear(renderYear)
                {
                    var day = 1;
                    var tuesdays = 0;

                    while (tuesdays < 2)
                    {
                        var october = new Date(renderYear, 9, day);
                       
                        if (october.getDay() == 2) tuesdays++;

                        if (tuesdays < 2) day++;
                    }

                    var adaLovelaceDay = day;
                    if (day == 1 || day == 21 || day == 31)
                    {
                        adaLovelaceDay += "st";
                    }
                    else if (day == 2 || day == 12)
                    {
                        adaLovelaceDay += "nd";
                    }
                    else
                    {
                        adaLovelaceDay += "th";
                    }

                    this.setState({"year": renderYear, "adaLovelaceDay" : adaLovelaceDay});
                }

                changeYear(inc)
                {

                }

                componentDidMount()
                {
                    this.showAdaLovelaceDayForYear((new Date()).getFullYear());
                }


Yikes. This looks like a horrible, horrible mess. Let's clean this up.


First, ensure that genContent occupies the full height and width of its parent.
            #genContainer
            {   
                border-top: 2px solid #CCCCCC;
                height: 200px;           
                width: 100%;
            }   

            .genContent
            {   
                height: 100%;           
                width: 100%;
            }

            .adaText
            {
                height: 1.5em;
                width: 80%;
                margin: 0 auto 0 auto;
                padding-top: 1em;
                font-size: 16px;
                font-family: arial;
                text-align: center;
            }


Each div styled using yearGen should be 150 pixels tall. They should take up 25% of their parent's width, because there are four of these suckers, and four of 25% makes up... 100%! Float them all left. genDigit basically determines how each number looks. Use personal taste here. But do center the text using the text-align property.
            .adaText
            {
                height: 1.5em;
                width: 80%;
                margin: 0 auto 0 auto;
                padding-top: 1em;
                font-size: 16px;
                font-family: arial;
                text-align: center;
            }   

            .yearGen
            {
                height: 150px;
                width: 25%;
                float: left;
            }   

            .genDigit
            {
                width: 100%;
                height: 100px;
                font-size: 80px;
                font-family: verdana;
                font-weight: bold;
                text-align: center;
            }


Much better.


Now for the buttons. The container, buttons, takes up full width and text content is centered. The button tags are styled to be small squares with rounded corners, and a little margin.
            .genDigit
            {
                width: 100%;
                height: 100px;
                font-size: 80px;
                font-family: verdana;
                font-weight: bold;
                text-align: center;
            }   

            .buttons
            {
                width: 100%;
                text-align: center;
            }   

            button
            {
                margin: 0.25em;
                width: 2.5em;
                height: 2.5em;
                text-align: center;
                border-radius: 20%;
            }


Excellent!


To prevent the text from overlapping, set the clear property to both.
            .adaText
            {
                clear: both;
                height: 1.5em;
                width: 80%;
                margin: 0 auto 0 auto;
                padding-top: 1em;
                font-size: 16px;
                font-family: arial;
                text-align: center;
            }   


Yep...


And hey, while you're at it, remove the red lines.
div {outline: 0px solid #FF0000;}


Great!


Now let's deal with the changeYear() method. Declare yearString and set it to the state object's year property, converted to a string. Then declare digits, which will be an array of yearString's numbers.
                changeYear(inc)
                {
                    var yearString = this.state.year.toString();
                    var digits = yearString.split("");
                }


Finally, declare index, which will be the element's dataset's custom attribute i. Remember setting that while creating the sub-elements? This will tell you which number's buttons are being clicked.
                changeYear(inc)
                {
                    var yearString = this.state.year.toString();
                    var digits = yearString.split("");
                    var index = parseInt(event.target.dataset["i"]);
                }


Now, use the map() method and the parseInt() function to convert all elements of the digits array back to numbers.
                changeYear(inc)
                {
                    var yearString = this.state.year.toString();
                    var digits = yearString.split("");
                    var index = parseInt(event.target.dataset["i"]);

                    digits = digits.map(function(x) {return parseInt(x)});
                }


inc is true if incrementing, and false if decrementing. So if inc is true, check if the digit to be incremented is less than 9, and increment the number if so. This is to set a limit for the number... because in a year string you obviously can't go above 9.
                changeYear(inc)
                {
                    var yearString = this.state.year.toString();
                    var digits = yearString.split("");
                    var index = parseInt(event.target.dataset["i"]);

                    digits = digits.map(function(x) {return parseInt(x)});

                    if (inc)
                    {
                        if (digits[index] < 9) digits[index]++;
                    }
                    else
                    {
                    
                    }
                }


If it's decrementing, more checks are needed. We don't want the first digit to be a 0 ever, so first check if it's the first digit (i.e. index is 0), then decrement only if the number is greater than 1. That means you get a 1, minimum.
                changeYear(inc)
                {
                    var yearString = this.state.year.toString();
                    var digits = yearString.split("");
                    var index = parseInt(event.target.dataset["i"]);

                    digits = digits.map(function(x) {return parseInt(x)});

                    if (inc)
                    {
                        if (digits[index] < 9) digits[index]++;
                    }
                    else
                    {
                        if (index == 0)
                        {
                            if (digits[index] > 1)
                            {
                                digits[index]--;
                            }   
                        }
                        else
                        {
                       
                        }                      
                    }
                }


If it's any number other than the first, check if the number is more than 0 before decrementing. That means all other numbers can be decremented all the way to 0.
                changeYear(inc)
                {
                    var yearString = this.state.year.toString();
                    var digits = yearString.split("");
                    var index = parseInt(event.target.dataset["i"]);

                    digits = digits.map(function(x) {return parseInt(x)});

                    if (inc)
                    {
                        if (digits[index] < 9) digits[index]++;
                    }
                    else
                    {
                        if (index == 0)
                        {
                            if (digits[index] > 1)
                            {
                                digits[index]--;
                            }   
                        }
                        else
                        {
                            if (digits[index] > 0)
                            {
                                digits[index]--;
                            }                           
                        }                      
                    }
                }


Next, set yearString to be the joined string of all the numbers in the digits array. Then call the showAdaLovelaceDayForYear() method, passing in yearString converted back to an integer, as an argument. Remember that showAdaLovelaceDayForYear() changes the state of the component, updating the year and adaLovelaceDay properties?
                changeYear(inc)
                {
                    var yearString = this.state.year.toString();
                    var digits = yearString.split("");
                    var index = parseInt(event.target.dataset["i"]);

                    digits = digits.map(function(x) {return parseInt(x)});

                    if (inc)
                    {
                        if (digits[index] < 9) digits[index]++;
                    }
                    else
                    {
                        if (index == 0)
                        {
                            if (digits[index] > 1)
                            {
                                digits[index]--;
                            }   
                        }
                        else
                        {
                            if (digits[index] > 0)
                            {
                                digits[index]--;
                            }                           
                        }                      
                    }

                    yearString = digits.join("");

                    this.showAdaLovelaceDayForYear(parseInt(yearString));
                }


Well, now click on the buttons, increment and decrement as you wish, and the generated Ada Lovelace Day should change! That's the power of ReactJS binding, right there. Try changing the year to 2018. Does Ada Lovelace Day change to 9th October?


Wishing you all a happy and productive Ada Lovelace Day!

Decades after her death, look how far we've come. It's nice to remember the amazing woman who got us started down the road towards computing as we know it today.

All my Love(lace),
T___T


Monday, 23 September 2019

Ten Inspirational Film Moments For A Web Developer

Tech movies are great and all, but it may surprise you to know that I do watch other movies, and TV shows. And while film is, for the most part, simply mindless entertainment to me, there have been odd times when certain scenes in them inspired me in my web development career.

Today, I will be sharing some of the scenes in movies and TV shows that struck that note. And here they are, not in any order of significance.

1. True Detective Season 2

A crime thriller series where crime boss Frank Semyon (Vince Vaughn) is holding court with his subordinates during the very first episode.

True Detective Season 2

Some serious shit has gone down, and one of Frank's stooges suggests a desperate course of action. Frank shuts him down with the following line:

"Never do anything out of hunger. Not even eating."


This singular truth can be applied to so many situations. Never wait till you're hungry to eat - you'll end up eating things that aren't good for you, or eat too much. Never wait till you're thirsty to drink water - if you're thirsty, you're already dehydrated. Never wait till you're unemployed to start monitoring the job market - you'll end up taking any old job.

Basically, never do anything out of desperation. Because when you're in dire need, you tend to make sub-optimal choices. You tend to take what's available instead of what's best in the long run. When I attend a job interview without actually needing a job, I can negotiate (or not negotiate, as is my style) without feeling any pressure to capitulate. I can afford to weigh my options carefully. And most significantly, I can make choices that I will not regret later.

Don't do anything out of hunger. You'll probably end up doing something really stupid.

2. Unfinished Business

Vince Vaughn again, and this very tepid comedy, while utterly forgettable, had one scene that struck me deep.

Unfinished Business

In it, Dan Trunkman (Vince Vaughn) and his employee, the unfortunately named Mike Pancake (Dave Franco), are sitting around a little group passing a bong, when Dan starts talking about why he wants to send his son to private school - to avoid bullies. And Mike, while normally managing to sound like a total retard, has this surprising little pearl of wisdom.

"You know the worst part with teasing? My dad would say, forget about it and ignore it, son. But he doesn't understand because in his day, kids would get teased at school all day but then they could go home. And nowadays, you come home and there's Facebook, and there's Instagram, and the bullies can get at you through all of that stuff. And it never really stops."


That was a truth about cyberbullying that thoroughly resonated. With the rise of tech, our lives have changed. Including school bullying. School bullying is no longer "school" bullying because people can now bully you wherever you go, as long as you're logged in. And we all need to understand that.

The solution? Don't let them.

Look, I know it's easier said than done, but hear me out. If you accept the fact that people are going to be total assholes every time you log on, the solution is not to stand up for yourself and have the last fucking word... because you should have higher standards. Some people have nothing more meaningful in life to do than win battles on the Internet. That's on them. You can quietly pity them, but don't be an idiot and validate their existence by joining them.

3. The Intern

I watched this movie originally because there was nothing else showing. It's about an old guy who signs up to be an intern at an up-and-rising startup, and ends up imparting wisdom and friendship and all that jazz.

The Intern

It was OK, but the one thing that stood out, aside from a very tasty-looking Rene Russo (hey I'm a seventies kid, so fuck you), was the scene where the titular intern Ben Whittaker (Robert De Niro) is shooting the breeze with some of his much younger colleagues, Jason (Adam DeVine) and Lewis (Jason Orley).

Jason: Wait, so you're saying you shave every day?
Ben: Yes.
Lewis: Even on Sundays?
Ben: Every day.
Jason: OK, and even if you know that you're not gonna see anyone that you know?
Ben: Yes.


See? Ben has a routine. Granted, it's a very minor one, but he keeps to it. And he does it even when nobody's looking. That's integrity and discipline. Sure, this three-second scene didn't make me start shaving every day (because sometimes I like a little fuzz on my chin) but when you apply it to other things, it holds just as true.

When I code, I'm obsessive about the spacing - both horizontal and vertical. The indentation. The casing. I try to keep things as visually neat as possible. Why, you may ask? The laypeople don't care as long as it works, and the techs aren't likely to notice. Well, if recognition is what you're going for, great. But I'm doing this because it's the right thing to do, or possibly because I'm OCD.

It may seem like a really small thing, just like shaving. But I firmly believe that if a professional can't be trusted with small things, then that professional can't be trusted with bigger things.

4. Captain Marvel

This is a superhero movie, and despite the controversy Brie Larson stirred up, I actually didn't hate it. Aside from some very cringey in-your-face feminist moments where I felt the film-makers were trying just a wee bit too vigorously, it met my KPIs for mindless fun.

Captain Marvel

Still, there was some inspiration to be taken from this particular scene. In it, Yon-Rogg (Jude Law) challenges Captain Marvel (Brie Larson) to a good old-fashioned fist fight, to prove to him that she can beat him without using her powers. Instead, Captain Marvel summarily hits him with an energy blast, and as she stands over his stunned body, utters the following line.

"I have nothing to prove to you."


Now, let's be clear: I think the character did the right thing. The stakes were too high to let her ego get in the way, and she did what was both sensible and efficient. She did not play Yon-Rogg's game, but simply did her own thing. But that line... for the love of God, what a stupid line. See, when you really don't have anything to prove to people, you don't do something counter-intuitive like defiantly declare it in the manner of some rebellious teenager. That was what Captain Marvel came off as, and this particular line inspires me not to do something this dumb. If you don't have anything to prove, make your decisions accordingly and don't waste time pointing it out.

A couple years ago, some loudmouth at work asked me what I was doing for the weekend. In all seriousness, I told him I would be trying to render a pie chart using CSS. He laughed and told me that was a waste of time, and I should be looking up new and cutting-edge technologies in my spare time, just like him.

Damn, someone was trying really hard to impress me there. Perhaps too hard.

Did I play his game? Hell, no, I did not. The next time he asked what my plans were for the weekend, I merely said I'd be screwing around with QBasic, and let him think he'd won. Like Captain Marvel, I did my own thing and didn't let anyone bait me into playing some meaningless game of one-upmanship. Unlike Captain Marvel, however, I had so little to prove to this dude that I didn't even feel the need to inform him of that fact.

Less is more, Captain Marvel.

5. Goldeneye

Back in 1995, I watched my first Pierce Brosnan-led Bond movie. And it was so good. Mindless actions? In spades. I remember it as the first time I ever saw Femke Janssen on screen as a hammy psycho chick, and it was so, so good.

Goldeneye

But the thing that really stood out for me was the computer nerd Boris (Alan Cumming) who had this habit. Whenever he accomplished something via his programming skill, he would pump his fists and dramatically declare...

"Yes! I am invincible!"


I've had similar moments while working. Successfully resolved a bug? Got some code to run? Output was exactly as expected, with no surprises?

Yes! I am invincible!

And yep, I would even do it in Alan Cumming's adorable Russian accent. Though, these days, I'm happy to occasionally say I am inevitable, just like Thanos.

6. Justice League

Another superhero movie, and while I generally think DC superhero movies aren't as good as the Marvel ones, there was an inspirational moment tucked away in this one.

Justice League

Flash (Ezra Miller) and Batman (Ben Affleck) are having a little conversation as they head off to hunt down the supervillain Steppenwolf. Flash is experiencing some panic and self-doubt, and Batman gives him some sage advice.

Flash: Okay, here's the thing. See, I'm afraid of bugs, and guns, and obnoxiously tall people, and murder. I can't be here. It's really cool you guys seem ready to do battle and stuff, but - full transparency - I've never done battle. I've just pushed some people and run away!
Batman: Save one.
The Flash: What?
Batman: Save one person.
The Flash: Uh... which one?
Batman: Don't talk, don't fight. Get in, get one out.
The Flash: And - and then?
Batman: You'll know.


This is actually very sensible advice. I've been in situations where I had to learn a new piece of tech - programming language, DevOps, API calls - and I had no goddamn clue how to do anything. And every single time, it was a similar mantra that got me started. Do something simple. Accomplish one basic objective, nothing else. Finish it, then go from there.

It could be a Hello World program. Playing around with an interface. Copy-pasting code, and then changing it to see what happens. Nothing significant, or spectacular. Just something to get me started.

The lesson to learn here is, many things look intimidating until you roll up your sleeves and just dive right in. I've learned a lot of stuff this way. Sure, I may not have gone very deep into those things, but at least I'm a lot less intimidated by them than when I practically knew nothing about them. And that's something.

Save one. Get in, get out. You'll know what comes next after you do it. You just need to take that first step.

7. Narcos Season 1

Narcos is a docu-drama about the life of infamous Colombian druglord Pablo Escobar (Wagner Moura), and the agents who try to bring him down, Steve Murphy (Boyd Holbrook) and Javier Pena (Pedro Pascal). It's a glorious smorgasbord of violence, sex and utter testosterone-laced badassery on all sides. I loved everything about this show, especially the fact that it's set in the sixties and seventies. Nothing like a little retro, eh?

Narcos Season 1

In the show, not everyone likes Boyd Holbrook narrating the scenes. But I do, and below is one of those times his lazy drawl hit me like a thunderbolt.

"When you kill someone, you lose all your leverage the moment they're dead. Now, you take someone's children away from them, you'd be amazed what they'd do to get them back."


Now, this is a little dark, but I like to think of it every time I'm being chewed out for something I did at work. Miswrote code, got caught napping during a meeting, spent too much time on my phone, or whatever. It's tempting to get demoralized when that happens, but really, that's probably when you're least in danger of getting fired.

Employers generally don't waste time warning employees that they're planning on dismissing. They just dismiss them, period. You're getting that warning because they still value you as an employee; either that, or replacing you on short notice is going to be a gigantic pain in the ass. That's not to say you don't have to check yourself, but going all Chicken Little the moment you're verbally warned, is an overreaction.

What employers do want (and expect) to see after you've been warned, is for you to visibly buck up. They expect you to react as though your kids have been taken away and you want them back. So do that. Whereas if you were to be fired, they can't reasonably expect to get any extra performance out of you.

8. True Detective Season 1

It's a buddy-cop crime thriller where the story spans decades. I enjoyed this one thoroughly, and I'd totally recommend it if you're into psychological thrillers.

True Detective Season 1

Rustin Cohle (Matthew McConaughey) and Martin Hart (Woody Harrelson) reunite after several long years to team up on an investigation, and they're starting to ask each other how things have been. Then Rustin drops this gem in Matthew McConaughey's trademark Southern drawl.

"Life's barely long enough to get good at one thing. So be careful what you get good at."


I'm in my forties now, and truth be told, there are many years which I spent unproductively, getting experienced in things that don't matter professionally. Like how to carry yourself in shady nightclubs. How to stack a Dungeons And Dragons character till he's basically unkillable. How to say the right things to a woman to get into her knickers.

I'm not saying that only professional skills matter... but damn I should have concentrated more on them when I was younger. Programming languages. Frameworks. Databases. Tech trends. As opposed to doing only stuff that was fun. Like, why the hell did I work so hard on being good in bed? It's not like I was training to be a gigolo. And twenty years on, that shit is no longer going to matter.

9. The Master of Tai-Chi

An example from Hong Kong! A Cantonese martial arts period drama I used to watch. This show is about a martial arts practitioner Mo Ma (Vincent Zhao) and his rivalry with Tuen Hiu-Sing (Raymond Lam). At first, Hiu-Sing kicks Mo Ma's ass in a fight, but as the show progresses and Mo Ma grows in maturity, he unlocks the secrets of Tai-chi. Mo Ma and Hiu-Sing eventually become friends as they work together to overcome a Police Chief, Chai Wai (Wilson Tsui).

The Master of Tai-chi

There's nothing really memorable about this show. It's painfully formulaic and pretty trite when you take away the action scenes. However, one thing stood out for me. Chai Wai, the show's villain, has hired a mercenary, Moon Yau-Ngo (Derek Kok). Yau-Ngo is supposed to get a shady task done, but he refuses. When Chai Wai asks him why, he declares...

"大丈夫有所为,有所不为"


Don't bother running this through Google Translate, because it'll make no goddamn sense. It barely even makes sense if read in Mandarin. It's a Cantonese phrase, which basically means: there are things a true man can do, and there are things a true man can't do.

That was what made the character interesting. Yau-Ngo is under no illusions here that he's anything but a bad guy. But he also thinks of himself as a true man. The two aren't mutually exclusive, unless you have totally no sense of nuance. From Yau-Ngo's point of view, he's an accomplished martial artist, and can kick ass. Certain actions are so craven that he considers himself above them. Chai Wai wasn't impressed with Yau-Ngo's statement, but does Yau-Ngo give a shit? Nope.

Everyone needs an ethical bottom line like our villainous friend there. I'm not saying I won't lie. But I won't make rash promises and once a promise is made, I'll do my dardest to keep it. I won't borrow money frivolously, or allow myself to forget about paying it back. And I won't pretend to be sick just so that I can have a day off from work to attend a job interview. Those are just a few of my personal bottom lines. And I don't care if anyone's impressed by those rules, because, again, those are my bottom lines.

10. The Karate Kid


No, not the original classic. This is the remake in 2010, which was inexplicably named the same despite the martial art in question being Chinese Kung-fu, not Karate.

The Karate Kid

The movie wasn't spectacular, but it was serviceable. What really helped was the part when Mr Han (Jackie Chan) is training Dre (Jaden Smith) for the first time during an iconic scene, and ends the lesson with an impassioned speech.

"Kung-fu lives in everything we do, Xiao Dre. It lives in how we put on a jacket, how we take off the jacket. It lives in how we treat people. Everything is Kung-fu."


Everything is Kung-fu. Words to live by. When Mr Han incorporated Kung-fu into actions that Dre was familiar with, the learning process became a whole lot clearer.

This mantra helped a lot in my tech learning process. Everything is web development. In some small part, it's also the inspiration behind the phrase work is part of life.

Let's stop thinking of tech as this oh-so-mystifying thing and realize that its roots are steeped in everyday life. Technology is not some unfathomable mystery. It is an extension of everything we know. A whole chunk of it is based on logic and common sense. Apps that solve everyday mundane problems (maps, bus schedules, pizza delivery) are built because mobile devices and the Internet exist. Rows and columns were a thing long before there were databases. Tech terms are words that had other meanings before the first computer was produced.

Being able to see parallels in the world around me, and use analogies while trying to understand the principles behind another aspect of technology, has helped me make sense of what I was learning.

And that's all!

The film moments that inspired me were mostly innocuous. But we all take inspiration from the strangest places. In fact, arguably, the ability to do so is pretty damn important. Because, you know, everything is Kung-fu.

I am invincible!
T___T