Wednesday, 29 May 2019

The Good Old Variable Swap

A very elementary exercise in programming entails variable swapping. That's when a and b are variables with values, and you use computer logic to swap their values. Most programming classes teach the use of a temporary variable, like so. I'm just going to write this in QBasic as an example. In this case, the value of a is 3 and the value of b is 2.

DIM a = 3
DIM b = 2
DIM c

c = a
a = b
b = c


In the example above, c is used as a variable to temporarily house the value of a, while a assumes the value of b. To complete the process, b takes on the value of c (which held the old value of a) and presto - a is now 2 and b is now 3.

Swapping glasses of water.

This is often illustrated using two glasses of water. If you wanted to swap the water in one glass with the water in the other glass, how would you do it? You can't just swap it straight away - you would need a third glass (or container) to facilitate the transfer.

Now for the tough bit...

How do you swap the values of two variables without using a third variable?

There's no practical use for this, by the way. But it's sometimes asked as a brainteaser, or to test a programmer's logical skills. So try this. First, we assign the variables. Again, the value of a is 3 and the value of b is 2.
DIM a = 3
DIM b = 2


Now, we add a and b together and assign the value to a. a is now 5.
DIM a = 3
DIM b = 2

a = a + b


Next, we know the combined value of a and b is 5, and is now the value of a. We also know the current value of b, which is 2. So the old value of a must be 5 - 2 = 3. Thus, we assign that value to b.
DIM a = 3
DIM b = 2

a = a + b
b = a - b


Since b is now 3, which is the old value of a, then the old value of b has to be 5 - 3 = 2. We assign that value to a.
DIM a = 3
DIM b = 2

a = a + b
b = a - b
a = a - b


And the variables are swapped! The analogy of the glasses of water isn't applicable here anymore. Interesting, eh?

There are other ways, of course. Let's examine another one.

Using the XOR operator...
DIM a = 3
DIM b = 2

a = a ^ b
b = b ^ a

a = a ^ a
b = b ^ b


This works too, and it's arguably more elegant than the first example. However, I prefer the first example because it's presented in layperson logic. Primary school arithmetic. It reinforces my belief that you don't have to be a rocket scientist to learn programming. Of course, these work only if the values are numeric.

In Python, you could do this, and it would work regardless of what data types a and b are. But I dunno, that just seems to defeat the entire purpose of the exercise.
a, b = b, a

That's all. Glass dismissed!
T___T

Saturday, 25 May 2019

Ten tech languages that may resemble people you know

If you're a developer, or even just a tech hobbyist or IT student, you've probably dabbled in quite a few languages. Ever notice just how human some of these languages seem? By "human", I don't mean "natural language", though that certainly helps. No, I mean, some of these languages may exhibit characteristics that look suspiciously similar to those of your friends, or just people you know.

Let's go through a list of some of the languages I've used...

Editor's Note: This list is not limited to just programming languages. Any tech language is fair game.

1. COBOL

COBOL is the crotchety old ex-military woman who has coffee with you every morning and yammers on incessantly about her bratty grandchildren. It's been half a century since she first started working, but she's a tough old coot and refuses to retire.

COBOL is an old, intimidating lady.
IDENTIFICATION DIVISION.
PROGRAM-ID. HELLO-WORLD.
PROCEDURE DIVISION.
DISPLAY "Hello world!".
STOP RUN.

She's fairly cantankerous and not very sociable, and if you don't know her well, she can seem very intimidating. She rarely speaks in a whisper - every sentence is loud and abrupt. She's also unabashedly old-school, and to hell with you if you have a problem with that. (And yes, I think of COBOL as a female entirely because of Grace Hopper).

Treat COBOL with respect. She's been around a long time and may even be around long after you're gone. A lot more people would miss COBOL than they would miss you. She's that important. She shouldn't be, but she is.


2. Java

Java is a classy businesswoman. She's so classy she has her own garbage collector. Unfortunately, she's also a bit of a snob and tends to objectify everything. She's also very opinionated and has very fixed ideas as to the correct way of doing things. She absolutely refuses to communicate any other way. She hates comparisons with that tramp JavaScript (see further down the list). Java also thinks of herself as edgy, but she really gets off on popularity just like JavaScript - she's just a lot more coy about it.

Java's a bit of a
pretentious snob.
public class HelloWorld
{
    public static void main(String[] args)
    {
        System.out.println("Hello, World");
    }
}

Keep Java around. She can be useful when you're trying to reach a wider audience because of her popularity - and, her reputation for being proper and "classy" will give you some cred -  though her penchant for doing things the long and pedantic way is a pain in the ass for times you need to keep it simple. Java doesn't do simple. She is something of a pontificator - she never uses a simple one-liner when she can use five lines to bring her point across. Perhaps she thinks this makes her look intelligent, though sadly, she just comes across as really insecure.

3. SQL

You know the library nerd who has read a lot of stuff and is just bursting to share it with you? SQL is that guy. Or "Sequel", as he likes to be called, because it sounds cool.

SQL reads a lot.
SELECT "Hello World!";

SQL is a wealth of knowledge - there's rarely anything he hasn't read about. Problem is, he can be a major windbag. He gets carried away. If you make the fatal mistake of asking him for everything he knows about stuff, you could be there all night because the dude just doesn't know when to stop talking unless he runs out of information. Sometimes the key to getting along with SQL is to filter. The more specific the filter, the better.


4. PHP

PHP is the blue-collar workman who wanders around in battered workboots and stained jeans. He's comfortable to hang out with, but he gets judged hard by fashion snobs and anyone who associates with him gets judged as well. In recent times, he's attempted to spruce up his image by learning new things and wearing new clothes, but they always seem a little ill-fitting on him. Clothes maketh the man, but in his case, everybody can see that beneath all that jazz, he's ultimately the same guy. Props for effort, though!

PHP is a handyman.
echo "Hello World!";

The problem is, PHP was basically an odd-job guy until people started calling on him to do everything. At some point, he got overworked and stopped being able to keep up.

PHP is still a good guy to hang with, but you may outgrow him at some point.

5. BASIC

BASIC is a few years younger than COBOL, but opted to retire much earlier. He's an elderly gent who likes to keep things simple yet flexible. You may remember playing very rudimentary computer games (like chess) with him back in the day.

BASIC is a retiree.
PRINT "Hello World!"

The guy's always glad to see you, and he's still great for teaching kids how to code. Keep him around for nostalgia, if nothing else.

6. Ruby

A young spirited lass who's low-key yet effective. Ruby doesn't call attention to herself or put on airs. Basically, Ruby is a great communicator. Unlike Java or C++, who are just wordy, Ruby is friendly and easygoing and tries hard to use common sense to interpret you so you don't have to jump through hoops to be really explicit with her. This sometimes takes her a while, but the effort doesn't go unnoticed. She's probably the easiest person to get along with, and doesn't judge you.

Ruby's your best friend.
She understands you.
puts "Hello World!"

Everyone needs a friend like Ruby. Content not to hog all your attention and hum along amicably in the background, she's useful in a pinch for undertakings both big and small.

7. HTML / CSS

HTML used to be the fun single guy you could hang out with all night. He was the guy who introduced you to the Internet and all its wonders, your constant companion as you roamed the information highway.

HTML and CSS are a
lovely chic couple.
<h1>Hello World!</h1>

However, ever since he got hitched with CSS, it's exceedingly rare to see them without each other. CSS dresses HTML up nicely - he was frankly a little plain and shabby before she came along - but he's the one who gives her existence meaning. Without HTML, there is no CSS. They're a lovely couple nonetheless.

8. Markdown

HTML has a much younger and poorer cousin. His name is Markdown. He does a lot of the same things as HTML back in the day, but in an even less verbose way.

Markdown is HTML's
younger poorer cousin.
# Hello World!

When you need to do documentation, that's when Markdown really shines. Some see him as HTML-lite, which isn't too far from the truth... but when you need a fast and friendly way of rendering a webpage without too many bells and whistles or just a way to slightly spruce up an otherwise boring text file, Markdown is your guy. He's a simple fellow, but in his limited scope, he gets shit done just fine.

9. JavaScript

What can we say about JavaScript, or JS, as we like to call her? She's a bit of a good-time girl. She's sexy, playful (or "promiscuous" as this guy would say) and isn't choosy about who she hangs with, and she's really casual. You don't have to slowly tease or romance her to make her give up the goods. Treat her as shabbily as you want. She likes it!

JS is an easy girl.
alert("Hello World!");

In her early days, she used to only engage in hot threesomes with HTML and CSS. But she's moved on to greater things now. These days, she's everywhere. She can add color and flash to your shopfront, or she could be the hardworking engine at the back making things work.

At the heart of it all, JS is one hell of a capable woman who can get serious and professional with you, yet cut loose like a wild thing in a different setting. Just don't give her your heart. She'll break it, though she never breaks her promises. (heh heh)

10. C++

C++ is that senior marathoner whom you need to be very explicit with. He's capable of doing some truly awesome stuff, but communicating with him can get a bit hairy at times. He runs fast - astonishingly fast - and when you need real power, C++ is who you call. Despite his advanced age, this guy is speedy and robust.

C++ runs fast, even at his age.
#include <iostream>

int main()
{
    std::cout << "Hello, World!";
    return 0;
}

C++ has few social skills to speak of and is only popular with the really brilliant guys. He has a reputation for being just as wordy as Java. The only difference is that C++, due to having a really specialized job, actually needs to be verbose. C++ rarely run the simple races - that's for lesser mortals like PHP and Ruby.

Disclaimer

Any of these descriptions remind you of people you actually know? That's just a coincidence. But that really hammers home the point, doesn't it; tech languages have very human characteristics, probably as a result of having been written by actual humans and worked on by a huge number of other humans.

std::cout << "Bye, Reader!";
T___T

Wednesday, 22 May 2019

Tough Times Ahead For Huawei?

Everyone's talking about it - everyone with a mobile phone and access to the Internet, that is.

A couple days ago, Google stunned the world by announcing that it was blocking Huawei's access to Google Play and Android updates. This was in response to the USA sanctions imposed on China trade as part of the US-China Trade War. Huawei's problems were compounded when suppliers such as Infineon Technologies and Qualcomm announced a halt to shipments to Huawei until they could figure out if said business arrangements were in violation of US Trade Law.

Is Huawei in trouble?


Is Huawei in trouble? The China tech company certainly appears to be in dire straits. After all, without suppliers, how do parts for devices get assembled? Without access to user technology such as apps, how will users use Huawei phones at all?

It would be premature to write Huawei off at this point in time. If it were any other company in any other country, maybe. But this is China, and China has its own ecosystem of apps, and more importantly, a large enough domestic market to support it. In fact, it's this very market that companies such as Facebook and Google wanted to tap back then, but failed.

Sure, Huawei phones won't be able to use Gmail. But the Chinese use QQ. True, no Google search. But the Chinese use Baidu. Getting the idea yet, or am I going to have to trot out the hundred and one alternatives for the apps that the Chinese are not going to miss? This situation really affects non-Chinese Huawei users the most... and all I can say is, tough titty, folks.

The USA may just have miscalculated, though. With a strong domestic market and their own technology, there is a distinct possibility that Huawei being forced to get creative could result in them digging deep and emerging from this with stronger, superior tech. Undoubtedly, it'll take time. But again, this is China. They've been around like, forever. They've got nothing but time.

Unfair practices?

People are going on and on about unfair practices on the part of the USA, and others are retaliating with retorts that China started it by banning Google and Facebook a while back.

First of all, China did not ban Google. Not deliberately, anyway. By default, all external parties are banned unless they adhere to China's policy of censorship. Not that I like censorship, but China's been completely consistent here. Comply, or fuck off. Google opted for the latter, because those restrictions went against the freedom of information it stands for. One could, of course, make a case for China eliminating competition for search engines and Social Media such as Baidu and Weibo, but on the surface at least, China's position is pretty legitimate.

Secondly, it's a Trade War, children. There's nothing fair or unfair about it. It is what it is.

Are you Team China or Team USA?

Personally, I couldn't give a monkey's left nut. Why do I have to choose a side? I'm a consumer. I'm on the consumer's side. And if this results in Huawei blossoming in its independence and churning out a new generation of devices that will break the Android and iOS stranglehold on global markets today, all the better. Tech wins.

As to who wins this Trade War, your guess is as good as mine. I think China and USA severely underestimate each other.

China has weathered many a storm over millennia, and this latest thing is merely a blip in a long history full of violence and turmoil. It's really difficult to see the Chinese breaking a sweat over this. They may seem arbitrary and inflexible, but damn if they don't know how to take a beating.

The USA may seem complacent and smug, but remember you're dealing with the spirit that manufactured the nuclear bomb, and even used a couple to end World War Two.

Looks like it's their wei or the highwei! (hur hur)
T___T

Thursday, 16 May 2019

There's working hard... and there's 996 (Part 2/2)

One of the people weighing in on the 996 work culture is none other than Alibaba's Jack Ma, supporting the practice and calling 996 a "huge blessing". This raised a huge uproar in China's tech community, and Jack Ma is currently at the top of a list labelled "Capitalists" in the 996.ICU GitHub Project.

Let me, in all fairness, say something about hard work. Hard work is not a bad thing at all. But it is far from the only thing. It's certainly no substitute for results. No one cares if you work yourself to death, if you don't produce results.

Hard work is the bare minimum anyone can give. There are plenty of people who aren't exceptionally bright, very talented or deeply experienced. What they can give their employer, in lieu of all that, is hard work and integrity. In fact, when I was a novice programmer (in many ways, I still am) with almost no relevant experience, the only value I could give my then-employer was hard work. Hours of my life. And he certainly didn't go easy on me whenever I screwed up, on account of all those free hours I willingly gave him.

Any idiot can be hardworking. It is the lowest form of value an employer can expect. That really is the default setting, and spending twelve hours a day in the office doesn't make you special. Because literally anyone could spend time slogging in the office if they really wanted to. I'd go so far to say that any employer who values hard work over results is a fool, and a dangerous one at that, precisely because they're fools in positions of power. Keep clear of such people.

Old trusty workhorse.

When you spend extra time in the office, you're basically sending the signal that you're a workhorse who has nothing else to offer. That's certainly valuable if you're just starting out, but once you start selling yourself as an experienced developer, it sends the wrong message. Because experienced developers are supposed to be good enough not to have to work to death in order to get things done. If you're a supposedly experienced developer but slog like any noob, you're not an asset. Why would you expect an employer to pay you the wage of an experienced developer if you work like a novice? Because you work hard? Really?

Another thing about Jack Ma and hard work

Look, I respect the man. Honestly, I do. He started from practically nothing and he hauled himself up to where he is today, by virtue of hard work. I give him all the props in the world. This man is incredible.

Does this mean that just because Jack Ma succeeded this way, you will too? Hogwash.

See, Bill Gates dropped out of college and went on to found Microsoft. When people tell me they intend to do the same and cite Gates as an example of what they can achieve, my eyes roll all the way to Mars and back. Dude, Bill Gates dropped out of Harvard. This means he got into Harvard. And this in turn means that he was good enough to get into Harvard in the first place. What run-of-the-mill educational institute are you dropping out of? And assuming you're in somewhere even more prestigious than Harvard, do you have the business acumen of Bill Gates to make it? He succeeded in the 80s. That's a very different era from now.

Similarly, let's take a look at Singapore's own Wendy Cheng. Love her or hate her, she's probably Singapore's most successful influencer to date. And the number of people looking to escape the nine-to-five grind and emulate her, are endless. People think that just because Xiaxue (who isn't very pretty, particularly hot, pleasant or even interesting) can do it, they too, can get on Social Media and make a living being some kind of Internet personality. Newsflash, guys... Wendy Cheng is where she is today because she wasn't trying to copy anybody. And, she is one hell of a shrewd marketer. What have you got - endless selfies and vapid new age-y quotes? Good luck with that.

My point is, just because someone achieved success a certain way, doesn't mean you're going to. In fact, these people were successful arguably because no one else was doing what they tried to to at that time. Now if we have a million people trying to do the same thing and only a handful can succeed, what is everyone's chance of success? Very low. It's elementary. Primary school math!

So when Jack Ma says hard work is a good thing, I believe him. I believe that he means it, because the man has actually lived it. But we have fanboys who think that every word out of Jack Ma's mouth is wisdom from heaven. Let's see a few examples.

"Never give up. Today is hard, tomorrow will be worse, but the day after tomorrow will be sunshine."

"You need the right people with you, not the best people."

"Opportunity lies in the place where the complaints are."


Really? The day after tomorrow will be sunshine? Opportunity lies in the place where the complaints are? I can defecate better stuff than that. Why is this trite shit special? Because it comes from Jack friggin' Ma?

Let me break it down for you - despite my respect for Jack Ma and his claims that he wants to help others achieve success, the stark reality is, there's only so much money to go around. He can't possibly not know this. He's one hell of a smart dude, even if his fanboys aren't. Is he really going to dish out advice that will help people get rich, maybe become heads of large companies like his? No, he's just going to give some vague, generally sensible-sounding soundbites such as espousing on the value of hard work. Alibaba is this successful today because Alibaba has no competition. And it's in Jack Ma's interest to keep it that way.

Mr Ma then goes on to say,
"If you do not do 996 when you are young, when will you? Do you think never having to work 996 in your life is an honor to boast about?"

In that sense, he is perfectly right. When you're young and have the energy, that energy should be dedicated to something worthwhile. You should be prepared to give it your all. But not for your company or your boss. Do it for yourself. There is no sense in working yourself into ICU for a company that can (and probably will) replace you in a heartbeat.

So yes, to hell with the supposedly inspirational Jack Ma quotes. Jack Ma doesn't know how you're going to succeed. Only you know how you're going to succeed. And if you don't, why should anyone else?

Thanks for reading. ICU around!
T___T

Tuesday, 14 May 2019

There's working hard... and there's 996 (Part 1/2)

It's no big secret that I'm rather contemptuous of the term "work-life balance". It's a term that's been bandied around so often that it's lost its meaning. It's some buzzword tossed around by people who have it so good that they're no longer thinking about survival and instead obsessing over having enough time to watch soap operas and whatnot.

That being said, the recent furor over the 996 work culture in China was disturbing. 996 is shorthand for 9AM to 9PM, 6 days a week, akin to, or perhaps even surpassing, the Hustle Culture in Silicon Valley. And what was most disturbing of all was realizing that tech companies in China were making their employees do this, in direct defiance of China's labor laws against compulsory unpaid overtime, which, if we're going to be honest, don't amount to a pile of monkey shit since they're not enforced.

Now, it's also no big secret that I used to pull those ungodly hours years ago. 996? Bitch, please - I was coming in twelve hours a day, Sundays and public holidays. Years later when I was working in a startup, that was 996... and a vacation in comparison. So I'm going to risk sounding like an utter hypocrite when I denounce the 996 work culture in China's tech industry.

You see, spending those hours at work for your own sake is one thing. You're young, you have the energy, pour it into something you love. Learn. Practice. Perfect your craft.

But when the company mandates the 996 work culture, that is something else entirely. That is repugnant. It's like you telling your spouse "I love you" just because he or she told you to say it. My bosses appreciated me putting in all that time precisely because they never asked for it. Not that their appreciation means anything since I was doing it purely for selfish reasons... but enforcing a work culture like that breeds resentment. It leads to bosses taking employees for granted because if 996 is the norm, going above and beyond the call of duty would involve something even more spectacularly insane. Case in point tech workers in China putting up 996.ICU on GitHub, an allusion to ICU (Intensive Care Unit) being where you'll end up after 996.

Because that pace of work isn't sustainable long-term. There is going to be a breaking point somewhere.

About to snap.

You see, even when I was spending the majority of my life at work, there was an objective. The objective was to get better at my job so that one day I wouldn't need to spend that much time honing my craft. Because I understood that despite how much I love my work, like any other human being, I have physical limitations. And as I age, those limitations are going to become increasingly apparent.

Should people spend more time at work? Yes, if they personally see a need to. But no, it should not be, implicitly or explicitly, demanded of workers unless there is commensurate remuneration; or unless these workers own shares in the company, in which case they would be motivated to put in those extra hours anyway.

Work is part of life...

Here, I need to digress a little.

When I said "work is part of life" a couple months ago, I was faced with objection from proponents of "work-life balance". These are people whose entire world is divided into two parts: work and not-work. I consider it an oversimplification, but if it keeps them happy, I'm all for it.

This is how it looks like, using PHP arrays as an example.
$work = ["debug", "test", "code"];
$not_work = ["sleep", "play", "eat"];


On the other hand, if one is experiencing dissatisfaction with the "work-life balance" model, you could try looking at it from my perspective instead. In my perspective, work is part of life, because my world is divided into things we do because we're alive, and things we do because we're dead. And unless you're claiming to be able to work after you're dead, work comes firmly under the $life array. Yes, there's an extra layer to the previous model and I'm viewing everything through that lens.

$work = ["debug", "test", "code"];
$not_work = ["sleep", "play", "eat"];

$life = [$work, $not_work];
$death = [$decay];


But this model only works if you're not working merely to pay the bills. It's only relevant if your work is part of your identity.

...but there should be lines drawn.

Whichever model you employ in your worldview, a certain amount of discipline is advisable. These days, I don't bring work home if I can help it, and I certainly don't answer work emails at home. Why? For the same reason I don't do my goddamn housework in the office. If employers want professionalism, they should be prepared to accept everything that goes with it. I can stay back late in the office; I can even come in on weekends. But once I leave the office, I'm done, dude.

And unless what you're working on is so earth-shatteringly important that success would change life for everyone on this planet as we know it (cure for cancer, mind-controlled mobile phones, flying cars), the company should never take priority over family. If you die in the course of work, your family's going to be devastated. The company's merely going to be inconvenienced.

I can't emphasize this enough. Even if we assume that it's passion and not money that drives you, the workplace is a place you work, end of. Lawyers care about the law - they don't care about the firm they practice in. Surgeons care about saving lives - they don't care about the hospital they operate in. And as a web developer, I care about making good software - I certainly don't care about the company I do it in. Not enough to be operating 996 solely for the company's benefit, anyway.

In essence, I'm not against 996 at all. I'm only against companies that think they're entitled to that level of commitment.

Next

Reflecting on the value of hard work.

Friday, 10 May 2019

Web Tutorial: Lee Bee Wah Lau

Dr Lee Bee Wah is a Member of Parliament for Nee Soon and recently, she's been an Internet meme for the unintentionally hilarious speech she made in Parliament.


It was actually a pretty sanctimonious admonishment to the general public, and drew a fair amount of ire. On my part, I almost doubled over in mirth. Good old Sis Flower - always good for a laugh. This isn't the first time she's been an object of ridicule. She has been quite the sport over the years, providing us with several meme-able moments due to her flair for the dramatic and her penchant for hyperbole, not to mention a hide like a rhinoceros.

In fact, back in 2016, when Joseph Schooling won the Olympic gold, Lee Bee Wah made herself famous with the following remark.


"I'm glad I asked MINDEF to let elite male athletes defer their NS."


This served to look as though she was claiming credit for Schooling's gold medal, and drew flack all around. My friend Benjamin Broekhuizen (who henceforth shall be known as "Ben" because typing his full name is a right pain in the arse), after facepalming heartily, was moved to write some code to express his distaste for that remark. It was a quick and dirty job - PHP with a randomizer to echo the result from a list of grandoise and increasingly silly claims.


Editor's Note: Nobody is saying that Sis Flower actually said these things (other than the first quote), but we're satirizing this particular quote.

Nothing against Lee Bee Wah, but I was tickled when I saw that page. Lee Bee Wah Lau - a portmanteau of her name and the common Hokkien expression of dismay. And then my web developer's brain went to work and I started wondering - what if we didn't have to refresh the page to get a new quote? Maybe just a button to randomize the next quote?

One thing led to another. Simple JavaScript would do the trick... but what's the fun in that? I'm trying to learn ReactJS. Let's use that!

And that's how this web tutorial was born...

What we're doing

We will make use of Ben's content (which he has very kindly shared) and make a new version using ReactJS and front-end binding. Yes, it's a very trivial use of ReactJS, and Ben did comment that it was like using a flamethrower to fry a mosquito, but what the hell man, we all gotta start somewhere, ya dig?

Let's start with some HTML, and a container div with an id of quoteContainer. Also add a little attribution link to Ben. It was his idea.
<!DOCTYPE html>
<html>
    <head>
        <title>Lee Bee Wah Lau!</title>
        <style>

        </style>
    </head>
    <body>
            <div id="quoteContainer"></div>
            <small>
                Original concept by <a href="https://www.linkedin.com/in/bsbroekhuizen/" target="_blank">Benjamin Broekhuizen</a>.
            </small>
    </body>
</html>


Here, we'll add reference links to React, ReactDOM and Babel. It's actually not the recommended way to use ReactJS and would probably not handle large projects very well, but it's great for something of this size and far less intimidating since it follows the typical web development pattern of including the reference link in the HTML itself.
<!DOCTYPE html>
<html>
    <head>
        <title>Lee Bee Wah Lau!</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="quoteContainer"></div>
            <small>
                Original concept by <a href="https://www.linkedin.com/in/bsbroekhuizen/" target="_blank">Benjamin Broekhuizen</a>.
            </small>
    </body>
</html>


Note that the script tag's type attribute is "text/babel". This is relevant because we're using ReactJS, and therefore it requires the Babel to compile. In it, we first define the Quote class. It's a ReactJS component, so declare it as an extension of the react.component class. Note that the script tag is within the body tag itself for ReactJS.
<!DOCTYPE html>
<html>
    <head>
        <title>Lee Bee Wah Lau!</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="quoteContainer"></div>
            <small>
                Original concept by <a href="https://www.linkedin.com/in/bsbroekhuizen/" target="_blank">Benjamin Broekhuizen</a>.
            </small>

            <script type="text/babel">
            class Quote extends React.Component
            {

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


Whatever's returned by the Quote component will be rendered into the quoteContainer div, so do this. ReactDOM's render() method will use Quote (here represented as a tag with no quotes), and the quoteContainer div as an object.
    <body>
            <div id="quoteContainer"></div>
            <small>
                Original concept by <a href="https://www.linkedin.com/in/bsbroekhuizen/" target="_blank">Benjamin Broekhuizen</a>.
            </small>

            <script type="text/babel">
            class Quote extends React.Component
            {

            }

            ReactDOM.render(<Quote />, document.getElementById("quoteContainer"));
            </script>
    </body>


Let's create the render() method of the Quote component.
            class Quote extends React.Component
            {
                render()
                {
              
                }
            }


First, let's use Ben's content array. This will be assigned to Quote's content property.
            class Quote extends React.Component
            {
                render()
                {
                    this.content =
                    [
                       "asked MINDEF to let elite male athletes defer their NS.",
                       "asked God to let there be light",
                       "asked my parents to conceive me",
                       "asked John F. Kennedy to put a man on the moon",
                       "asked Lee Kuan Yew to create modern Singapore from a fishing village",
                       "asked Frodo to destroy the One Ring",
                       "asked for more cowbell",
                       "asked Rosa Parks to sit in the front of the bus",
                       "asked Martin Luther King what he dreamt of",
                       "asked Phelps to take it easy, so Schooling could win and I could take the credit",
                       "asked Indonesia to clean up Batam",
                       "asked Barack Obama to run for President",
                       "asked Obi-Wan Kenobi to save Amidala and her twins",
                       "asked Snape to take care of Harry",
                       "asked Def Leppard to pour some sugar on me",
                       "asked the residents of Yishun to vote for me, so I could ask MINDEF to let elite male athletes defer their NS"
                    ];   
                }
            }


Then we return the result. It's a HTML block (again, with no quotes, because it's not a string) consisting of a div and a blockquote tag. Within the blockquote, we have a templated string. The value of the first element of the content array has been put in.
            class Quote extends React.Component
            {
                render()
                {
                this.content =
                    [
                       "asked MINDEF to let elite male athletes defer their NS.",
                       "asked God to let there be light",
                       "asked my parents to conceive me",
                       "asked John F. Kennedy to put a man on the moon",
                       "asked Lee Kuan Yew to create modern Singapore from a fishing village",
                       "asked Frodo to destroy the One Ring",
                       "asked for more cowbell",
                       "asked Rosa Parks to sit in the front of the bus",
                       "asked Martin Luther King what he dreamt of",
                       "asked Phelps to take it easy, so Schooling could win and I could take the credit",
                       "asked Indonesia to clean up Batam",
                       "asked Barack Obama to run for President",
                       "asked Obi-Wan Kenobi to save Amidala and her twins",
                       "asked Snape to take care of Harry",
                       "asked Def Leppard to pour some sugar on me",
                       "asked the residents of Yishun to vote for me, so I could ask MINDEF to let elite male athletes defer their NS"
                    ];

                    return (
                        <div>
                            <blockquote cite="http://www.teochewthunder.com">
                                I am glad I {this.content[0]}
                            </blockquote>
                        </div>
                    );    
                }
            }


There, you'll see the text rendered on the screen.


Now what?

Well, we've got so much content, it's a shame to let it go to waste. Ben's original concept was that you had to refresh the page in order to get a randomized quote. Let's do that with a button instead. In the button's onclick event, we'll fire off the Quote component's changeQuote() method (which we haven't written yet, hold your damn horses!).
                    return (
                        <div>
                            <blockquote cite="http://www.teochewthunder.com">
                                I am glad I {this.content[0]}
                            </blockquote>

                            <p>
                            <button onClick={this.changeQuote}> More >> </button>
                            </p>
                        </div>
                    );


There, now we have a button.


We will now write the changeQuote() method. Before that happens, since we will be playing with state changes, we need a constructor for the Quote component. props will be passed in as an argument, but since there are no properties passed into the render() method, we don't really need that.
            class Quote extends React.Component
            {
                constructor(props)
                {

                }

                changeQuote()
                {

                }

                render()
                {
                this.content =
                    [
                       "asked MINDEF to let elite male athletes defer their NS.",
                       "asked God to let there be light",
                       "asked my parents to conceive me",
                       "asked John F. Kennedy to put a man on the moon",
                       "asked Lee Kuan Yew to create modern Singapore from a fishing village",
                       "asked Frodo to destroy the One Ring",
                       "asked for more cowbell",
                       "asked Rosa Parks to sit in the front of the bus",
                       "asked Martin Luther King what he dreamt of",
                       "asked Phelps to take it easy, so Schooling could win and I could take the credit",
                       "asked Indonesia to clean up Batam",
                       "asked Barack Obama to run for President",
                       "asked Obi-Wan Kenobi to save Amidala and her twins",
                       "asked Snape to take care of Harry",
                       "asked Def Leppard to pour some sugar on me",
                       "asked the residents of Yishun to vote for me, so I could ask MINDEF to let elite male athletes defer their NS"
                    ];

                    return (
                        <div>
                            <blockquote cite="http://www.teochewthunder.com">
                                I am glad I {this.content[0]}
                            </blockquote>

                            <p>
                            <button onClick={this.changeQuote}> More >> </button>
                            </p>
                        </div>
                    );               
                }
            }


Here, we call the super() method to initialize the constructor.
                constructor(props)
                {
                    super();
                }


Then we define state. It's an object with currentIndex as a property. The default value of this property is 0.
                constructor(props)
                {
                      super();
                      this.state = {"currentIndex": 0};
                }


Next, we bind the changeQuote() method to the constructor using the bind() method.
                constructor(props)
                {
                      super();
                      this.state = {"currentIndex": 0};
                      this.changeQuote = this.changeQuote.bind(this);
              }


In the changeQuote() method, we define a variable, tempIndex, which we set to 0. Then we run a random number function to get a number between 0 and the number of elements in the content array. Finally, we alter the currentIndex property of this component's state, setting it to the value of tempIndex.
                changeQuote()
                {
                    var tempIndex = 0;

                    tempIndex = Math.floor((Math.random() * (this.content.length)));

                    this.setState({"currentIndex": tempIndex});
                }


Now when we click the button, the quote changes! No page reloading needed.


You can skip the next part if you want to. It's just me being anal. Here, I use a Do-while loop to ensure that tempIndex doesn't randomize to the same value twice in a row. The chances of that happening aren't great, but like I said, I'm particular about some things.
                changeQuote()
                {
                    var tempIndex = 0;

                    do
                    {
                        tempIndex = Math.floor((Math.random() * (this.content.length)));
                    }
                    while (tempIndex == this.state.currentIndex);

                    this.setState({"currentIndex": tempIndex});
                }


All good? Cool, let's pretty this up a bit.

For the button, I'm going to set it to a nice light blue and place it center of the page. It'll have round corners and even a hover pseudoselector for some interactivity. Feel free to get creative!
        <style>
            button
            {
                display: block;
                padding: 0.5em;
                font-weight: bold;
                background-color: rgba(150, 150, 255, 0.5);
                color: #FFFFFF;
                border-radius: 5px;
                border: 0px;
                width: 100px;
                margin: 10% auto 0 auto;
                text-align: center;
            }

            button:hover
            {
                background-color: rgba(150, 150, 255, 1);
            }
        </style>


There's your pretty button, right there.


Next, we position the quoteContainer div. It will be 800 pixels in width. The margin property sets it to middle of the page with a 10% margin at the top, and I've given it a red outline for clarity.
        <style>       
            #quoteContainer
            {
                width: 800px;
                margin: 10% auto 0 auto;
                outline: 1px solid #FF0000;
            }

            button
            {
                display: block;
                padding: 0.5em;
                font-weight: bold;
                background-color: rgba(150, 150, 255, 0.5);
                color: #FFFFFF;
                border-radius: 5px;
                border: 0px;
                width: 100px;
                margin: 10% auto 0 auto;
                text-align: center;
            }

            button:hover
            {
                background-color: rgba(150, 150, 255, 1);
            }
        </style>


There it is.


Now let's style the blockquote tag! These tags may be rendered differently between browsers, so it behooves us to keep it as consistent as possible. I'm giving it a width 80% of quoteContainer's width, a height of 8 elements, and setting it in the middle of quoteContainer using the margin property. Text alignment and font is all up to you.
            #quoteContainer
            {
                width: 800px;
                margin: 10% auto 0 auto;
                outline: 1px solid #FF0000;
            }

            blockquote
            {
                display: block;
                width: 80%;
                height: 8em;
                margin: 0 auto 0 auto;
                text-align: center;
                font-family: georgia;
                font-size: 20px;
                font-weight: bold;
                line-height: 2em;
            }


Nice.


Now, the blockquote needs quotes! For this, we'll use the before and after pseudoselectors. Both these pseudoselectors will have display set to block and occupy the full width of the blockquote, with a decreased height and large font size.
            blockquote
            {
                display: block;
                width: 80%;
                height: 8em;
                margin: 0 auto 0 auto;
                text-align: center;
                font-family: georgia;
                font-size: 20px;
                font-weight: bold;
                line-height: 2em;
            }

            blockquote:before, blockquote:after
            {
                display: block;
                width: 100%;
                height: 0.5em;
                font-size: 3em;
            }


The difference, of course, is that before has an opening quote and is aligned left, while after is a closing quote and is aligned right.
            blockquote
            {
                display: block;
                width: 80%;
                height: 8em;
                margin: 0 auto 0 auto;
                text-align: center;
                font-family: georgia;
                font-size: 20px;
                font-weight: bold;
                line-height: 2em;
            }

            blockquote:before, blockquote:after
            {
                display: block;
                width: 100%;
                height: 0.5em;
                font-size: 3em;
            }

            blockquote:before
            {
                content: "\201C";
                text-align: left;
            }

            blockquote:after
            {
                content: "\201D";
                text-align: right;
            }


There are your quotes!


Let's prettify it even more with light blue borders.
            blockquote:before
            {
                content: "\201C";
                text-align: left;
                border-top: 3px double rgba(150, 150, 255, 0.5);
                border-right: 3px double rgba(150, 150, 255, 0.5);
            }

            blockquote:after
            {
                content: "\201D";
                text-align: right;
                border-bottom: 3px double rgba(150, 150, 255, 0.5);
                border-left: 3px double rgba(150, 150, 255, 0.5);
            }


You're doing good!


Now all that's left to do is remove the red outline.
            #quoteContainer
            {
                width: 800px;
                margin: 10% auto 0 auto;
                outline: 0px solid #FF0000;
            }


And there's our final product.

In closing...

Some friends, upon seeing this, have asked me to be careful because this could affect my career. These people are from the older generation of Singaporeans and typically paranoid about being fixed by the Government. They're still under the impression that the Government has the time or inclination to deal with petty issues. It's quite adorable.

Honestly, if this country's leaders can't take a joke, we have far bigger problems than me not having a job.

I'm glad I wrote this web tutorial to change your lives!
T___T