2018 Year In Review

As today is the last day of year 2018, this is the time to reflect what I've written for the past year again, something that I've done since 2017, 2016, 2015 (when I first started the This Week I learned (TWIL) posts), 2014 (not sure what happen, can't find anything), and 2013. As I re-read all previous posts throughout this year, it dawned to me that my perception of time was way off. There were certain events which I thought were written down in June but occurred in January instead. Worse, there were certain posts that I questioned myself, "Wait, did I wrote that?". Nevertheless, thinking in writing is a good way to explore your thoughts for the past 365 days.

Some quick summary of each month for the whole year.

January. Betta fish breeding methods, logs, market pricing, and diseases handling. Career planning relatively to your age and what you should be doing for this year, the usual new year resolutions crap. Some thoughts on movie and passing of a famous illustrator. Revisit walking steps counting and appreciation of Chinese writing (I should do this more this year). Guitar duet is fun, only if you have a partner in crime. Also, some passing rant about front end development. Do revisit the CrushEntropy and Open Aquarium.

February. Technology stuff, the never ending quirkiness in MySQL, Git, and Perl. More walking steps counting. Again, Betta fish breeding in relation to Sturgeon's Law, floating plants, Dropsy diseases and Epsom Salt. Containers hype and the usual hype cycle in tech world repeats itself again every year. Watched the best NBA play move of the year (IMHO). Do reread and understand that productivity is not learning.

March. Lots of Betta fish breeding projects and lighting issue in relation to algae boom. Relearning Chinese and reusing English words I've learned each week in writing. Using the right medication cured some really old wounds. The perils and irony of applying project management technique in reality.

April. Even more Betta fish breeding project, diet (its stomach size is as big as one tiny pellet), types, and history. Some history on React and best way to understand React is to build it from scratch. GDPR going to be enforced soon. The usual quirkiness in Git, Perl and MySQL.  Appreciation for Chinese poem and more English words learning. Ubuntu upgraded to 18.04. Things to follow up, do blood pressure reading for both arms and measure the differences and don't waste your 25000 mornings.

May. More Betta fish breeding projects. Learned more HTTP protocol and rediscovered some Perl (with Travis CI), MySQL, and Docker stuff. Look into FORMS again.

June. What happened this month? Writing style changed to Q&A type. Is your SO still breeding Betta fish? Yes, she is. I heard you're still doing Perl? Yeah, exploring Moo, AUTOLOAD, overloading, map, eval, and dispatching. The aftermath of GDPR implementation. Revisit JANKI method and a critical component.

July. Exploring other fishes like Zebra fish and Anabas. Derived a Betta growth table so we can make sure we're feeding the fishes adequately. More discussion on Betta fish colour type and aquarium tropical fish diseases. Computer hardware stuff. On the artsy side, movies and music. And lastly, the usual MySQL rants and React. Follow up with UCLA's Guided Meditations audio tracks; and chop wood and carry waters.

August. Continue back Betta breeding project and learned about wild Bettas. Revisit audio stuff but nothing done yet to the setup. Meal prep, my friend, meal prep. Books and more books. The Fn + Space key combination blew my mind away. Most important things regarding time, Temporal Illusion, Telescoping Effect, and Chronostasis. Ask yourself, have you figure things out yet?

September. Different strategies in reading book, three books at a time, hard, medium, and easy level. Reading experience will be further improved by active reading. Focus on strength training instead of cardio workout as building muscle burns more fat. Something about BPA and plastic containers. Something else about TypeScript, Perl, and MySQL, Git, and Ubuntu's Snap. Do start reading with pencil. Also, stop treading water, learning to learn.

October. Another Betta breeding project. Home ownership (buy or rent) and property in MY, just hold and wait. Perl's constant, my goodness. Lots of front end stuff that a developer should knows.

November. Going analogue (reading, writing, meditating, sleeping, or cooking) is probably the best thing ever happened to this fast paced life. The fundamental is always important, learn your kick timing in swimming. Ubuntu upgraded to 18.10. Study liberal arts may be better instead of STEM. Found an anime worth watching and also stumbled upon an anime that I wish I can unwatch, for humanity sake, seriously, that was so effed up.

December. Breeding Betta again. Blogging marathon, cleared up all pending blog posts from the past. Windows as a development platform (Babun, Zsh, or Scoop) still quite a lot to be desired except maybe VSCode is faster and fluid compare to GNU/Linux. Revisited LXD and MySQL. Finished up one pending Coursera's course. Make sure your insurance policy is "guarantee renewable". Long awaited news, the death of Internet Explorer, good way to conclude the year. Be content and learn to live with less, good to fit into one bag.

That was a quick summary of each month blogging posts. Now we will continue with the details reflection on projects that occurred this year.

Betta fish breeding project. We have started roughly 40-plus projects but only 27 Betta pairs managed to mate. Out of those 27, 17 was considered as successful, 3 were partially successful (the male or female Betta succumbed to illness after we removed it from the breeding tank), and 10 were failures as the whole population was wiped out. The good news is, some of the Betta fishes from our first successful breeding project, BSL20171231, were still alive and healthy. The most successfully project was BSL20180518, where we obtained quite a few good Super Red male. Solid colour Betta was far more easy to breed in term of colourization compared to Koi or Marble. Unfortunately, no female Betta were found for us so we can continue our second generation breeding project (more on this in coming post about Betta fish genetics).

Reading (books or research papers). 10-plus books and scientific literature. Nothing much and this can / should be improved for this coming year. Research papers are more fun to read than books, although some really needs time to digest the content especially you're unfamiliar with the domain.

Writing. 109 blog posts this year, 32 more posts than last year. As I realized, put aside grammar and spelling, if you have something to say, you can always write something up. I'm very well aware of where I'm lacking when come to writing. What remains is tuning my writing process (ritual, word choices, editing, and environment). Nevertheless, TWIL will proceed as usual. And for the writing strategy, still the same, striving for quantity over quality but on different topics instead of technical stuff.

Learning (MOOC courses or something else). TypeScript, React (yet another framework and another abstraction over HTML), and more Perl, especially writing CPAN modules. Managed to finish one online courses (long pending) this year (it was fun). Will continue with other online courses, not really into STEM but more towards liberal arts subjects. Sadly, I didn't have time and motivation to look into the embedded stuff.

Health. Supposed to be walk or move more but a changed of plan in the second part of the year. Rigorous swimming training, consistent meal time (especially dinner and thanks to meal preps), healthy food (more vegetables and fruits, and almost no processed and sugary food and drinks), and adequate sleep. The combination of all theses leads to planned weight loss (1kg per month) where my weight almost reached the safe range of healthy BMI and I've lost two inches of my waist. Focus on strength training instead of cardio workouts as muscle burns more calories. Long term plan is to age slowly and gracefully.

FOSS contributions. Four Perl's modules. Can be better and nevertheless, is a start somehow compare to all those years. Will continue this as usual.

This Week I Learned 2018 - Week 52

Last week post or every damn thing from the past. As this is the last week of year 2018, this will be the last second post of this year before the reflection post at the eve of the new year.

What is the plural of fry (a group of little fish)? Is fries, as in like french fries. Every time when I jotted down my observation note on Betta fish breeding, I always confuse about the grammar.

The use of carcinogenic pesticides in our local rice, will this ever get regulated and monitored? Doubt so but our neighbour country, SG will surely let us know. While pesticide residues found in our food sources (especially beloved chili) and diet is still worrisome, there is still lack of conclusive evident linking pesticides to cancer.

Who is Larry Wall and how he is like? The creator of Perl programming language, the author of "The Three Virtues of a programmer", whose favourite colour is Chartreuse, an INFP, and unassuming. Also, some said he is Weird Al in disguise..

How to Get Things Done When You Don't Feel Like It? Use and apply these five strategies: (1) Gamify your process. Start with the smallest possible step that you don't have any excuses not to start. (2) Reserve calendar time for every project. Mark it in the calendar as any other important items in your life. Allocated a short period to do your next smallest item. (3) Get other people involved. Accountability is the key here. We will likely follow through what we promise others. Example is the daily scrum. (4) Talk about it. Externalizing problems by venting it out. (5) Practice the art of "precrastination". Do something else satisfying that release "dopamine" like checking off a to-do list or a short break.

Scoop: Command Line Application Installer For Windows

While looking through some Rust stuff, I stumbled upon Scoop, a command line application installer for Windows. While there exists package managers for Windows like Chocolatey, Ninite, CoApp, and Babun (a Windows shell for Cygwin), why the needs of another similar tool? Initial impression after setup the tool indicated that Scoop sits between Chocolatey and Babun. It uses PowerShell to manage the console environment and software installation and let you use *nix softwares in Windows environment. Read the wiki for further justification and differences.

Installation is quite straight forward, just open PowerShell and type this command.
iex (new-object net.webclient).downloadstring('https://get.scoop.sh')

Before we proceed with customization, we must set up the permission so that Microsoft Security Essentials won't slow down our downloads and installation of other softwares.
scoop install sudo
sudo Add-MpPreference -ExclusionPath 'C:\Users\foobar\scoop'

Next, we also need to add additional directory list to the tool. You can see the full list of available software in the `default` and `extra` directory. Get the full list of directories if you want to add more bucket.
scoop bucket add extras

Let's proceed with some customization of the PowerShell console. The default contrast was just too glaring and hurt my eyes. Once you've set this up, restart PowerShell and we will get back the regular *nix terminal prompt (~ $) and Solarized colour theme using concfg, a Windows tool that imports or exports console settings.
scoop install pshazz
scoop install concfg
concfg import solarized-dark

Let's install Git then. It seemed that all the built-in GUI tools were installed as well.
scoop install git
Installing 'git' (2.20.1.windows.1) [64bit]
PortableGit-2.20.1-64-bit.7z.exe (40.3 MB) [======================================] 100%
Checking hash of PortableGit-2.20.1-64-bit.7z.exe ... ok.
Extracting dl.7z ... done.
Linking ~\scoop\apps\git\current => ~\scoop\apps\git\2.20.1.windows.1
Creating shim for 'git'.
Creating shim for 'gitk'.
Creating shim for 'git-gui'.
Creating shim for 'tig'.
Creating shim for 'git-bash'.
Creating shortcut for Git Bash (git-bash.exe)
Running post-install script...
'git' (2.20.1.windows.1) was installed successfully!

Let's try to install another software, my dear Perl. Instead of Cygwin's version, it installed the Strawberry Perl instead.
scoop install perl
scoop which perl

What I like about Scoop? For a start, fast console interface, centralized application installation path (everything in `scroop` folder in your home directory), and you don't need to go to each website and download different Windows installer for any softwares you want to install. Any dislikes? Downloading software packages was quite slow compare to downloading through the web browser.

Reducing Blood Pressure Through Omni Heart: A Variation of DASH Diet

Maintaining good health is one of the core criteria for a good quality of life. Unfortunately, in this modern society, convenient access to all basic necessities, unhealthy life style, and overly intake of processed food leads to all sort of health risks. More so for those who are genetically susceptible to these risks. In Chinese, these health risks are known as "三高症", literally translated to "three high diseases" which includes "高血压" (high blood pressure), "高血糖" (high blood sugar), and "高脂血" (high blood cholesterol).

The typical answer to prevent this is, just lose weight. Yes, this is possible if you're young, having good genetic (be grateful to your parents), and have an active life style which allows anyone to pamper themselves with those processed food which are high in sugar, sodium (use interchangeable with salt but there are other food sources that produce this as well), and fat. What if you're not belongs to the former group of people that is impossible to achieve weight loss? Nothing but eating a healthy diet.

What is the most effective diet for reducing blood pressure then? The Omni Heart diet, which is a variation of DASH (Dietary Approaches to Stop Hypertension) diet. The core principle of DASH diet is to consume high nutrients foods mostly consists of vegetables, fruits, nuts, and low-fat dairy with small amounts of saturated fat, trans fat, and cholesterol. The OmniHeart diet recommends on taking more proteins instead of carbohydrates to reduce blood pressure even further. A comparison of three different diets have shown that OmniHeart is the most effective approach. The screenshot (Source: Harvard Health Publishing) below shows the DASH as well as the variation of Omni Heart diet plan for a daily 2000 calories intake.

As for any behaviour changes, following OMNI Heart or DASH diet turns out to be quite a challenges, especially you're from other parts of the non-western world. What is the equivalent menu items for those living in Asia? The menu was catered for those living in the western world. Certain food sources like berries, yogurt, nuts, and others are quite expensive. Furthermore, those who are lactose intolerance have to find other replacements. For any diets, planning ahead is essential and home cooking is not possible for those who have a daily busy schedule.

The recommended approach is to take the first step and follow this guide. Make adjustment along the way and replace with local ingredient if possible.

Flatpak in Ubuntu 18.10

While reading through the application list created using Rust, I stumbled upon this app, Neovim-GTK, a GUI interface for Neovim editor written using Gtk-rs, Rust binding for Gtk. Looking through the project's Git repository, there are two ways to install the app, either you compile the code or install it through Flatpak. Since I'm running on Ubuntu 18.10, to install this app, I've no choice but to install and setup Flatpak first.

Flatpak, another universal installer GNU/Linux besides Snap and AppImage. We will see in coming years which format will win the universal installer "wars". Features wise, Flatpak is quite similar to Snap, the only different is it can use shared libraries from other "flatpacked" package. For comparison of all three universal installers, check this page.

Back to our Flatpak installation in Ubuntu. We will install the necessary software and repository.

If you're running earlier Ubuntu versions, anything before Ubuntu 18.10 (Cosmic Cuttlefish), then you will need to add this PPA repository.
$ sudo add-apt-repository ppa:alexlarsson/flatpak
$ sudo apt update

Otherwise, just install the software as usual.
$ sudo apt install flatpak
$ sudo apt install gnome-software-plugin-flatpak
$ sudo flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo

Now, continue with the installation of Neovim-GTK using Flatpak.
$ wget https://github.com/daa84/neovim-gtk-flatpak/releases/download/v0.2.0-test5/nvim-gtk_x86_64.flatpak
$ sudo flatpak install nvim-gtk_x86_64.flatpak
Required runtime for org.daa.NeovimGtk/x86_64/master (runtime/org.gnome.Platform/x86_64/3.28) found in remote flathub
Do you want to install it? [y/n]: y
Installing in system:
org.gnome.Platform/x86_64/3.28                  flathub                  6d1d0ebbd724
org.freedesktop.Platform.VAAPI.Intel/x86_64/1.6 flathub                  82006efc71d3
org.freedesktop.Platform.ffmpeg/x86_64/1.6      flathub                  d757f762489e
org.gtk.Gtk3theme.Yaru/x86_64/3.22              flathub                  03e8b087a55c
org.gnome.Platform.Locale/x86_64/3.28           flathub                  2823e3d81b74
org.daa.NeovimGtk/x86_64/master                 org.daa.NeovimGtk-origin bcdaf15ce78a
  permissions: ipc, network, pulseaudio, wayland, x11
  file access: host, xdg-run/dconf, ~/.config/dconf:ro, ~/.config/nvim:ro
  dbus access: ca.desrt.dconf
Is this ok [y/n]: y

Run Neovim-Gtk. Initial impression, the app was really fast compare to Gvim, which is understandable since it's just a bare essential Neovim GUI wrapper.
$ flatpak run org.daa.NeovimGtk

Installation size was large (1-plus GB downloaded) due to the all the dependencies. If you're low on disk space, Flatpack-based installation is not the preferable right choice compare to plain old source code compilation and installation.

Betta Spawn Log : BSL20181223 : HMPK Super Red (M) x HMPK Super Red (M)

The fourth breeding project for Super Red Betta and the continuity (the same pair) of the breeding project, BSL20181105 which was started almost two months ago. We hope to achieve two goals on this project. First, increase the number of Super Red Betta we have right now so we can have more pair to breed and fix in coming generations. Second, determine how many times a female can mate and breed. From what we read online (not scientific proven or we haven't found any literature on this yet), a female Betta can breed for three till six times.

After both male and female Betta was removed from the breeding container in BSL20181105, we put them next to each other and feed both fishes well. Furthermore, we placed both fishes into Indian Almond leaves water and regular water changes (siphoned the waste and 25% water replacement). You can said it was under constant conditioning for almost two months. When both fishes were making bubbles then we decided to proceed ahead.

One thing we observed was male Betta was under constant stress and succumbed to illness after we've separated it from the fry. Hence, we tried to create an stable condition for both pair, especially the male. Survival rate of the pair is as crucial as the fry.

Log Notes
Since we have already conditioned this pair for almost a while (both already making bubbles), we just put two fishes into a large breeding container without separation and waiting for the male to make bubble nest.

2018-12-23 (1st week)
No bubble nest seen so we're assuming that both fishes were not ready to mate yet. However, yesterday was Dongzi Festival, which ended the raining season and weather became more sunny and windy.

We're quite surprised that we saw some fry were swimming vertically. Immediately removed the female Betta and the fish was health and swam actively. We did not use fresh new water but instead water from the breeding container so that the fish won't be stress due to water hardness changes. We will remove the male after one week if the fry manage to survive that long. As shown below, the fry was barely visible but the male was busy picking them up to the bubble nest.

2018-12-30 (2nd week)
Male Betta was removed. The usual daily BBS feeding.

2019-01-06 (3rd week)
Daily BBS feeding.

2019-01-13 (4th week)
Daily BBS feeding. Some juvenile fishes were seemed to have grown. Not really a large spawn compare to previous spawn.

2019-01-20 (5th week)
Daily BBS feeding and first 50% water changes.

1/ We've read that a male Betta can mate with several female Betta within the span of few weeks. A healthy female, will need 7 to 14 days to ovulate eggs and it can breed three to six time in its life span. But this is scientifically unproven observation from other breeders we've read only.

Rust Installation in Ubuntu 18.10

When was the last time I looked at Rust? Oh right, it was almost 5 years ago (how time flies). The Amazon Firecracker piqued my interest in Rust again and I'm curious to check out Rust again. There are several installation methods available. These days, it's easier to use custome tool like Rustup or Docker to manage and switch several and different versions compare to default distro packages.

Using Rustup
This is the default installation method. However, we using installing this using the LXC/LXD container. This is the fastest way to get Rust running in your environment compare to other methods (more on this).
$ lxc exec rust-rustup bash
[email protected]:~# curl https://sh.rustup.rs -sSf | sh

This will download and install the official compiler for the Rust programming 
language, and its package manager, Cargo.

It will add the cargo, rustc, rustup and other commands to Cargo's bin 
directory, located at:


This path will then be added to your PATH environment variable by modifying the
profile file located at:


You can uninstall at any time with rustup self uninstall and these changes will
be reverted.

Current installation options:

   default host triple: x86_64-unknown-linux-gnu
     default toolchain: stable
  modify PATH variable: yes

1) Proceed with installation (default)
2) Customize installation
3) Cancel installation
> 1
info: installing component 'rustc'
info: installing component 'rust-std'
info: installing component 'cargo'
info: installing component 'rust-docs'
info: default toolchain set to 'stable'

  stable installed - rustc 1.31.1 (b6c32da9b 2018-12-18)

Rust is installed now. Great!

To get started you need Cargo's bin directory ($HOME/.cargo/bin) in your PATH 
environment variable. Next time you log in this will be done automatically.

To configure your current shell run source $HOME/.cargo/env

Checking Rust-based tools version.
[email protected]:~# rustc --version; cargo --version; rustup --version
rustc 1.31.1 (b6c32da9b 2018-12-18)
cargo 1.31.0 (339d9f9c8 2018-11-16)
rustup 1.16.0 (beab5ac2b 2018-12-06)

Using Default Distro Package Manager
Again, bootstrap the environment using LXC/LXD.
$ lxc launch ubuntu:18.10 rust-pkg
$ lxc exec rust-pkg bash          
[email protected]:~# apt update; apt upgrade
[email protected]:~# apt install rustc

Checking Rust-based tools version.
[email protected]:~# rustc --version; cargo --version; rustup --version
rustc 1.30.0
cargo 1.30.0
rustup: command not found

Using Docker Image
Using Docker official image (the official image is based on Debian). Image size seemed way to big, roughly around 1.6 GB.
$ docker pull rust
$ docker image list | grep rust
rust                latest              d6daf33d7ea6        3 days ago          1.63GB

Luckily slimmer image available, roughly half the size. You just have to pull using the right tag. Reduction is size was due to the clean up steps and slimmer base Docker image.
$ docker pull rust:slim
$ docker image list | grep rust
rust                slim                a374accc3257        3 days ago          967MB
rust                latest              d6daf33d7ea6        3 days ago          1.63GB

Checking the container and Rust-based tools version.
$ docker run --rm -it rust bash
[email protected]:/# rustc --version; cargo --version; rustup --version
rustc 1.31.1 (b6c32da9b 2018-12-18)
cargo 1.31.0 (339d9f9c8 2018-11-16)
rustup 1.16.0 (beab5ac2b 2018-12-06)

Coursera - Writing in the Sciences - Week 8

Continue with week 8, the final unit of this course.

8.1: Talking with the media
The main objective if you've published your paper which caught the attention of the media or journalists? Basically the media needs something for them to write a clickbait title (or newshook) to drive readership. You, as a researcher should focus on what is the take home newsworthy message and how that message will affect people.

When giving number, use whole number instead of percentage or fractions. For example, instead of "20% increased risk" (sounds alarming), it's better to write it as "eleven cases in ten thousands per year may be affected".

8.2: Panel Interview
Discussion with her three ex-students, Dr. Kit DelgadoDr. Crystal Smith-Spangler, and Dr. Eran Bendavid.

Each university has their own media relation person who are in charge of press release. Practice the interview with them if possible and go through the list of documents needed for the interview. Also, good to do background check on journalists who are interviewing you. On the safe, you can ask for the questions ahead of interview session.

Don't let the journalist mislead you to speculate on something. Refocus back to the original topic.

8.3: Writing for general audiences
There is a career in science writing. When writing for general audience, be concise, clear, and engaging (telling a story). Focus on the take home message (this has been stressed repeatedly over the course).

8.4: Writing a science news story
There is a format for this type of writing according to this structure.
(1) Lead. First paragraph (1 - 2 sentences) that is catchy and short.
(2) Nut Graf. 5 W's (who, what, where, why, and when) and 1 H (how).
(3) First quote (3 - 6 paragraphs) and bring in the human element (evidence or opinion).
Use noun-verb for attribution. For example,
Do this. "Blah blah blah...," Professor X said.
Don't do this. "Blah blah blah...," said Professor X.

(4) Body which includes what was done before, what was done in this study as in key experiments or key findings, and last implication or caveats.
(5) Kicker. Create parting thoughts for ending. Use quote if necessary.

8.5: Interviewing a scientist
Lecture given by Amy Adams, Directory of Science Communication at Standford.

How to interview and write for general public. For a start, no jargon.

What kind of questions that elicit good quotes? Here are a few.
(1) What is the significant of this work?
(2) Who will benefits from this work?
(3) What do you think when you got the result?
(4) What made you look into this question?

Use the quote as it. Don't modify the quote.

Anatomy of a interview. The steps as follows:
(1) Can you describe the key finding?
(2) Why is this important?
(3) How does that work?
(4) Is there anything you want to add?

8.6: Social media
Why we need to engage in social media? Promoting yourself, cause, brand, or institution. It also connect with other like minded person.

Effective of social media depends on what you want to measure. Focus on this before that using social media.

Engage but don't teach. In other words, create awareness.

8.7: Concluding Remarks
Effective writing and communication is essential to fence off an increase number of science

Learning Objectives
(1) Recognize the importance of communicating science with broader audiences.
(2) Be prepared to be interviewed by a journalist.
(3) Recognize the difference between writing for scientific audiences and writing for lay audiences.
(4) Understand the structure of a science news story.
(5) Learn tips for how to interview a scientist.

This Week I Learned 2018 - Week 51

Last week post or something else from the past years.

Are we at the end of hardware virtualization performance? Yes, according to the trend of the Amazon EC2 Virtualization Types. However, in the end, we just go back to bare metal somehow. The rapid improvement in virtualization made setting up homelab and data hoarding possible, cheap, and fast.

Meanwhile, what the heck is Firecracker (official announcement from Amazon)? New virtualization tool based on Kernel-based Virtual Machine (KVM). Interestingly, checking its Git repo indicates that the project was written in Rust, due to its origin started from Chrome OS Virtual Machine Monitor (crosvm), which was written in Rust. Why? Serverless platform, and for Amazon, the removal of VM like Fargate which leads to further cost reduction. Similar, Nitro, the Amazon latest hypervisor, also leverages on KVM but only the core modules to achieve near bare metal performance.

How do you automatically clean up orphaned Docker containers, instances, volumes, networks, or images? If you use Docker for your daily development, your environment accumulates these leftover artifacts unless you're diligent enough to do the clean up yourself. My "research" (ahem, googling) found two tools, docker-gc and docker-clean. The former is written in Golang and thus make it more portable compare to the later in Bash. But why such feature is not built into Docker itself?

What the heck is MVC-L? A concept popularized by OpenCart. Nothing fancy, just an additional Language (L) layer added to the pattern. Combine with another existing extension pattern to MVC, HMVC, we will have HMVCL. Is software pattern still a thing these days?

Is being an independent ISP still a thing in 2018? Yes, it still is, especially in rural area. Whole infrastructure is based on Ubiquiti and Microtik hardware.

How to update parent state from child component in React? Callback in the parent component as a prop to the child component. Treat each component as a class and props as parameters passed to the instance of the class itself. The basis concept is quite straight forward and what was I thinking?

In the parent component.
render() {
    return <Child action={this.handler} />

In the child component.
render() {
    return <Button onClick={this.props.action} />

Coursera - Writing in the Sciences - Week 7

Continue with week 7.

7.1 Writing a review article
Why you need to write a narrative review article or literature review? It lets you understand the current primary literature in your field of study. And by doing so, learn to read, organize, and summarize papers, and lastly write it out. By doing so, you will get an overview of the field of study. Furthermore, the review paper is a good resource for anyone to quickly dive into the the are of study.

There are three types of review articles.
(1) Non-systematic review. Also known as "narrative" review, not comprehensive, and is also a qualitative review.
(2) Systematic review. To summarize all relevant studies in a systematic way following pre-defined criteria. This is also a quantitative review.
(3) Meta-analysis. Basically a systematic review but using statistical techniques to pool data. This is something that I've never heard before.

What is the structure of a review articles?
(1) Abstract. Write this last as discussed in the previous week.
(2) Introduction. Define the aim.
(3) Method. Search strategy.
(4) Body. Main content of the review. Group it by methodology or theme. Upon this, analyze, interpret, critique, and synthesize these studies.
(5) Conclusion and future directions. Discuss recommendation and gaps. What's next for this field of study you've identified?

7.2 Grant I
Why you need to write research proposal? You're applying for grant for your research. Certain research need significant fund to proceed ahead. There are committee that review and approve this, learn the application and review process.

For successful application, you will need to identify the gap or niche in the area of research. Some questions to ask yourself.
(1) Is the question important?
(2) What is the overall goal?
(3) What specifically can be done?
(4) What is the expected payoff?

Note you're not a sole research. Research grant will be used and allocated for a whole research team. Build your team.

Plan your research. Ask yourself.
(1) Is there a need.
(2) How will be the specific aims be accomplished?
(3) How long will the project take?
(4) What is next?

Read the editorial post, "Ten Simple Rules for Writing a Postdoctoral Fellowship".

7.3 Grant II
Whole section focus on tips and strategies on writing Specific Aims document. Again, write the document follows these four key questions.
(1) Is the question important?
- Attention grabbing first sentence.
- Bring reviewers up to speed.
- Frame the knowledge gap/need.

(2) What is the overall goal?
- Big-picture goals.
- Objective of this proposal.
- Best bet / hypothesis.
- Supportive preliminary data.

(3) What specifically can be done?
- Aims.
- Working hypothesis.
- Methods.

(4) What is the expected payoff?
- Return on investment.
- Related to goals of the funding announcement.

7.4 Grant III
Further investigation and key questions to ask yourself before proceed ahead.
(1) Is there a need?
(2) How will the project be accomplished?
(3) How long will the project take?
(4) What is the payoff and what is next?

The outline of the research plan.
(1) Background/Significance.
(2) Aims.
(3) Timeline.
(4) Conclusion and future directions.

7.5 Writing letters of recommendation
When a student ask you to write a letter of recommendation, request below information from him/her.
(1) CV / resume.
(2) Information about the position / award.
(3) The dateline.
(4) Specific information on how to submit the information.

Note this is academic type recommendation letter, so the format of the letter should be following old-fashioned letter.

One interesting note. When you're asking for recommendation letter, you should avoid recommenders who ask your to draft your own letter. I wonder why?

7.6: Writing personal statements
Why we need this? Scholarship (usually), internship, or jobs.

Some tips.
(1) Make is personal (duh).
(2) Give specific examples and stories.
(3) Don't read your CV line by line.
(4) Avoid big words or cliches.
(5) Show interest in / flatter your readers. Do your homework!
(6) Explain gaps and failures.

Learning Objectives
(1) Understand how to write review articles.
Nothing much into the details of how to write review articles. The meta-analysis review article was quite new to me.

(2) Become familiar with the grant-writing process.
Always a long winding process. Lots of red tape.

(3) Understand how to write a strong letter of recommendation.
Both sides should prepare well. Rejection is understandable.

(4) Understand how to write a strong personal essay.

Coursera - Writing in the Sciences - Week 6

Continue from week 5.

6.1 Plagiarism
How do we write something original like your ideas or thoughts? You can to different materials on the said topic and understand it before you can form your opinions on it. From there you then convey your ideas in written words. In short, read a lot and differently, copy and quote the materials, and write from memory. Why? plagiarism is not really just word for word copy, we can subconsciously copy the author's sentence structure or word choices.

Self-plagiarism is also not acceptable. No need to republish something old as new. If the manuscript have been published in other journal, it's illegal to republish in other journals due to copyright rules.

There are tools that detect plagiarism like CrossCheck, Turnitin, PlagScan, or iThenticate. I've personally used Turnitin before and quite accurate to a point.

Be careful with miscitation and inaccurate citation as well. The issue with primary and secondary source, especially when we did literature review.

To be safe, just quote your writing in you are not sure.

6.2 Authorship
If you're collaborating a paper with multiple authors. Discuss this upfront.

Don't put your name in any papers as co-author if you don't want to take full public responsibility or fully responsible for the paper. You can put those who help in acknowledgement section.

What sequence of names should be placed in the paper.  First name is the primary author. Last name is the senior author or team lead like your advisor. But the sequence order may be different from one journal to another journal.

Ghost or honourary author is actual writer that draft the paper but no authorship in the paper. Guest author someone that lend his name to boost the paper, usually research done or sponsored by an organization, especially the medical literature. Example is the incident of Merck's Vioxx medicine scandal.

6.3 The Submission Process
(1) Pick the journal you want to publish.
(2) Follow the write style and convention.
(3) Get all copyrights sign off and submit your paper.
(4) Feedback from the publishing journal. Rejected but still able to resubmit. In other words, you should revise based on the reviewers feedback and resubmit again.
(5) Resubmit and comment on the reviewer's feedback.
(6) Final proof reading on the final print.

How to handle criticism will determine your success in publishing your paper. Separate your ego from the review.

According to the book Guidebook to Better Medical Writing Revised Edition by Robert L. Iles, good writing and good presentation (tables or figures) are essential for getting your paper published.

6.4 Interview with Dr. Bradley Efron
According to Wikipedia, he is an American statistician. So his opinions is based on statistics papers. Some of his key points.

(1) Statistics papers have both philosophical and technical side.
(2) Paper is written not only for publishing but also for reading as it's an essay for communication. Follow the writing style of journalist. Good heading that piqued the interests of the reader to continue reading the story.
(3) Send your paper to the right journal.
(4) Treat journal like a magazine (which is true) and it should be fun to read.
(5) Focus on the abstract or introduction (the beginning) and add in good figures and styling. Make it easy (dumbing down) and fun to read your paper.
(6) Go read papers published by good writer in your field.
(7) If you're publishing for the first, let editors know so they will be more understanding.
(8) Even himself have his papers rejected.
(9) Less papers is better. Quality over quantity.
(10) Rejection is common. Don't take it personally.

6.5 Interview with Dr. George Lundberg
According to Wikipedia, he is a pathologist, writer, and editor. He will share his opinions on publication process and getting your paper published.

(1) Journal wants papers that make it looks good. Hence, quality and ground breaking papers are well sought.
(2) Pick the journal that fits your goal. Want to improve your CV or get funding, go for high impact journal. Want to influence the industry, something else instead.
(3) Use the publication process to improve your research and writing.
(4) Don't write too long. Short and clear. Following the instructions for journal.
(5) Don't draw conclusion beyond the data.
(6) Edit your writing, be as mean as possible and ask for reviewers to review before submitting.
(7) No one like rejection. Everyone experience it.
(8) Eugene Garfield created the impact factor. He disagree with the usage of impact factor on journals on readership and citation counts. To him, impact means does it change the field.
(9) Don't resubmit the same paper to different journals, it maybe be sent to the same reviewer.
(10) If the research were funded using public fund, then the paper should be released to the public and not locked behind a publisher payment gateway.

6.6 Interview with Dr. Gary Friedman
Can't find much any information on him

(1) Don't submit repeating finding research paper.
(2) "Salami problem". Splitting your research into multiple papers.
(3) Don't over-evaluation your research or paper.
(4) Don't write a publication paper like a thesis.

6.7 Doing a peer review.
Peer review is good for your learning and understand the whole publication process.

Young peer review is a better reviewer because they are more up-to-date in the current field and more careful in reviewing.

Watch your tone in your review. Be tactful. Instead of identifying problems and criticizing the author(s), suggest a better way of doing it.

Reviewing is not lecturer. It may be condescending.

Reviewing types:
(1) Single-blind review where the reviewer knows who is the author are but not the opposite.
(2) Double-blind review. Both parties don't know each other.
(3) Open review. Both parties are aware of each other.
(4) Post-publication reviews. Done after the publication of the paper in the form of blogs or online comments.

What or how to review?
(1) Write one paragraph on the key finding and importance of the paper.
(2) What are the positive of the paper? Be specific.
(3) What are the limitation of the paper? Be specific.
(4) Don't focus on grammar or spelling issue. Focus on the research or the content itself.

6.8 Predatory journals
Bogus open access journal that was created to make money through scam. This was exposed by John Bohannon in this article, Who's Afraid of Peer Review?

Learning Objectives
(1) Identify and avoid plagiarism.
Be careful of accidentally copy the writing structure.

(2) Understand the peer review process.
Read the publication process and talk to your peer.

(3) Understand criteria for authorship.
Find the right co-author and use acknowledgement when necessary.

(4) Recognize common pitfalls for new authors.
Follow the publication rules and processes. Follow up with the feedback. You are not your research or paper. Differentiate between these two separate things.

(5) Recognize predatory journals.
Seek your advisor or peer advise on these fraud journals.

Coursera - Writing in the Sciences - Week 5

Continue with Week 5.

Way more delay like a year and two months ago. Good I've keep a todo-list and revisit it from time to time. One good lesson when come to learning, the key thing here is not the distraction but the recovery from interference. One bite at a time. One step at a time. One paragraph at a time. You will not feel the task daunting. Otherwise you will procrastinate and won't be able to get started.

5.1: Tables and Figures
Did I wrote my thesis in the wrong sequence? Dr. Dr. Kristin recommended that you should write in such order:

(1) Tables and Figures. No shell table but actual collected data. These are the core idea or story of your paper.
(2) Results. Basically high-level summary of each table and figure.
(3) Methods. What you have done to achieve the results.
(4) Introduction. Background story of your research topic.
(5) Discussion. Probably the longest part of your thesis. If you've done (1) till (4), then this part should come naturally to you. You should already know what to say.
(6) Abstract. "Abstract means to pull out". Yes, that sounds a bit weird. Pull, in the context here means to extract summarized details from other sections.

In the past, my sequence is reverse from (6) to (1). No wonder I spent so much time rewriting the (4), (5), and (6). In other words, focus on the results first and write the other parts later. What about reading a manuscript, the sequence should be (6), (4), (5), (3), (2), and (1).

Some additional reading.
(1) Clinical Chemistry Guide to Scientific Writing.
(2) Essentials of Writing Biomedical Research Papers. Second Edition by Mimi Zeiger

Why tables and figures are important? Because these are the foundation of your manuscript. The two items should be self-explanatory without looking around the elaborated section like method and discussion.

Between tables and figures, which one should you choose? If you need to visually show trends, patterns, or distribution, pick figures. Otherwise, use table when you need to show precision (like number of decimal points), many values, or multiple variables. However, a table or figure may not be need, sometimes a single sentence is sufficient enough.

It's crucial to understand the anatomy of a table which includes title, legend, data, and footer. Likewise for the anatomy of a figure which contains title, legend, picture (primary evidence), diagram, graph, and label. Best to follow the journal guidelines on layout and styling. One trivial rule in styling, remove grid lines from a table (doesn't look professional), just three horizontal lines. Also, add unit of measurements to your variables, for example, Age (years) or Age (months) for toddler. Lastly, don't add unnecessary columns which clutters the table.

Next, graph. There are may types of graphs.
(1) Line graph shows trends over unit of measurement (time, age, or others).
(2) Bar graphs compares group of data at a time point.
(3) Scatter plots shows relationship between two variables or linear correlation (does A causes B?). This graph shows all the data.

If you graph is too complex or cluttered, maybe you should use a table.

When should you use diagram or drawings? If you need to illustrate an experimental set up, workflow (causal diagram), or anatomy of a human or an animal.

5.2: Results
The main focus in this section is to summarize the data by showing relationships and trends through citing data from tables or figures. Do not repeat the raw data from tables or figures data by data. Just focus on the high level summary or take home messages. Pay attention on complementing (not repeating but may highlight) the data in the tables or figures. In summary, result section tells the reader of what you've discover with the supporting data from tables or figures.

Additionally, one key point is result section is what your data shows and discussion section is that your data means.

What verb tense should you use in this section?
(1) Use past tense for completed action like experiment result. Example is "We found that ......"
(2) Use present tense for what is still to be true like showing the table data. Example is "Table 1 shows ......"

You can mix both in the same paragraph. For example, "We found that ...... as Table 1 shows ......".

5.3: Practice writing results
Revise and edit those part where the author is just reading the table, repeating the result line by line in writing. Only pick and highlight important and interesting statistics.

5.4: Methods
Overview of what have been done and instructions for someone else to replicate the study like recipe. Use who, what, when, where, how, and why checklist to guide you to draft the content. These questions should tell in details of material, participant/subject, experimental protocol / study design, measurements of the research, and analyses.

To make your life easy, reference to other papers if the approach is a general well-known method. Also, use flow-diagram to simply your approach, like participant flow again.

What about verb tense?
(1) Use past tense to report method. For example, "We measured ......".
(2) Use present tense to described how data is presented in the paper. For example, "Data are summarized ......". Why? When you read the paper, the data are still being summarized to you.

Is okay to use passive voice or mix of passive and active voice in this section. A lot of emphasis is on the method or the variables.

Read the BMJ Christmas issue or archive for some humourous and light reading.

5.5: Introduction
Some general rules, typically 3 or 2 to 5 paragraphs, don't focus on general ideas but hypothesis or aim of the paper. Read the details rules recommended by Thomas M. Annesley in his paper, "It was a cold and rainy night" : Set the Scene with a Good Introduction. Following this top-down structure to plan the content.

(1) Background, known information.
(2) Knowledge gap, unknown information.
(3) Hypothesis, question, purpose statement.
(4) Approach, plan of attack, proposed solution.

Or a similar structure.

(1) What's known or background. (paragraph 1)
(2) What's unknown or limitations and gaps in previous studies. (paragraph 2)
(3) Your burning question, hypothesis, or aim. (paragraph 3)
Example of phrases are "We asked whether ......", "Our hypothesis was ......", "Our aim/s were ......".
(4) Your experimental approach. (paragraph 3)
(5) Why your approach is new, different, and important to fill in the gaps. (paragraph 3)

5.6: Introduction practice
Find any papers that interests you and mark these three sections from the introduction section.
(1) What's known or background.
(2) What's unknown or gaps or limitations.
(3) The aims of approach of this specific study.

5.7: Discussion
Start this section by following these four rules.
(1) Answer the question asked.
(2) Support your conclusion (your data, others' data).
(3) Defend your conclusion (anticipate criticisms)
(4) Give the "big-picture" take-home message.

In the discussion section, your writing should answer the question that why should anyone cares?

For further breakdown of the structure of this section as shown below.
(1) Key findings that answers the question(s) asked in the Introduction section.
(2) Key secondary findings.
(3) Context.
(4) Strengths and limitations.
(5) What's next.
(6) The "so what": implicate, speculate, and recommend.
(7) Strong conclusion.

And what verb tense to use? Past tense for any discussion of the result of completed experiment (we found that ......) and present tense for the suggestion of the data (the result suggests ......).

5.8: Abstract
Abstract is the combination of "ab" (out) and "trahere" (pull). This means to "pull out" key point from each sections. Length wise, the paragraph should be around 300 to 500 words. The structure as follows:

(1) Background or context.
(2) Question / aim / hypothesis.
(3) Experiment(s) details on materials and methods.
(4) Key results.
(5) Conclusion or the answer to the question. The take home message.
(6) Implications, speculation, or recommendation. Why should reader cares?

Learning Objectives
(1) Understand how to write the sections of an original scientific manuscript.
The key take here is to understand the anatomy of the manuscript (more on this in future post), tables, and figures. Understanding each part and the visual styling will lead to professional looking and readable paper.

(2) Critique poorly formatted tables and figures.
Use the standard good practices.

(3) Practice writing strong Results and Introduction sections.
You will need to read good papers on these two sections.

(4) Summarize the elements of a Discussion section.
Following the steps in the structure.

The Everloving Perl's Constant - Part 2

In the previous post, we've look into declaring and using constant within the same module. How about using a constant from other package?

Let's create a sample `FooBar` module (FooBar.pm) which exports a constant, `COLUMNS` as shown below.
package FooBar;

use strict;
use warnings;
use Exporter qw(import);

use constant COLUMNS => qw(TEST1 TEST2 TEST3);


To use this in another Perl script (test.pl). Notice there are several ways to use and access the `COLUMNS` constant.
use FindBin; # current script path
use lib "$FindBin::Bin"; # append current script path to the Perl's library path
use FooBar 'COLUMNS';

use strict;
use warnings;
use feature 'say';

say FooBar::COLUMNS();
say FooBar->COLUMNS();
say FooBar::COLUMNS;
say (COLUMNS);
say (COLUMNS());


Should we use constant pragma in Perl? No, according to Damian Conway in this book, Perl Best Practices. Instead he advocates that we should "use named constants, but don't use constant."  What he meant if you want to use constant in Perl, use the Readonly module instead of the constant pragma. However, Perl Best Practices was written in 2005, 13 years ago. Hence, which begs the question, does the recommend practices still relevant for these days? Nope, even Modern Perl 4th Edition, published in 2016 also discourages the use of bareword constant.

So, if we still want to use constant in Perl, what is the modern take (as in 2018) on Perl's constant? Discussion at Reddit leads to two Perl modules, Const::Fast or ReadonlyX. I like the former for its speed (even though benchmark results doesn't differ much) and simplicity as shown below (example taken from the module doc).
use Const::Fast;
const my $foo => 'a scalar value';
const my @bar => qw/a list value/;
const my %buz => (a => 'hash', of => 'something');

I've read and seen developers who work around this problem by using  scalar through `our`and uppercase to declare variables.

Some even encapsulate these constants within a subroutine (which is true anyway as constant in Perl is an anonymous subroutine) with predefined values.
    return qw(TEST1 TEST2 TEST3);

Nothing wrong with that as there are developers who don't even want to bother with Perl's caveat. Furthermore, benchmark shows that these two methods, using variable or subroutine, is faster than using constant pragma. Maybe they are right. Perl, a weakly-typed and TMTOWTDI programming language, should be "abused" and treated like one.

In the end, should we even bother? Yes. After the comparison of 21 Perl modules that implement constant (yes, 21 bloody ways and that was written in 2012), it's good to stick to a standard way of using constant in your code base. Be it a constant pragma or Const::Fast module, just stick to one.

The Everloving Perl's Constant - Part 1

Constant in Perl is a pain in the arse to use rather than not use. It took me quite a while to figure this out. And again, Perl's TMTOWTDI strikes again.

Following this question asked in SO, let use this example as shown below.
package FooBar;

use strict;
use warnings;
use feature 'say';

use constant HTTP_OK => '200';
use constant COLUMNS => [qw/ TEST1 TEST2 TEST3 /];

say @{+COLUMNS};


Since `COLUMNS` is a constant reference to an array of three elements, to fetch values from the constant, we must dereference it first through the `@{}` sigil.

However, there is a caveat here. In Perl, compare to other programming languages, a constant is not really a constant in normal convention. Rather, it's a prototype functions or a special kind of subroutine. If you use constant in the context that automatically quote barewords, in this case, dereferencing an array, `COLUMNS` may be interpreted as string and causing compilation errors as shown below.

say @{COLUMNS};

Ambiguous use of @{COLUMNS} resolved to @COLUMNS at test.pl line 11.
Variable "@COLUMNS" is not imported at test.pl line 11.
        (Did you mean &COLUMNS instead?)
Global symbol "@COLUMNS" requires explicit package name (did you forget to declare "my @COLUMNS"?) at test.pl line 11.
Execution of test.pl aborted due to compilation errors.

Thus, to prevent this, we need to tell Perl to ignore automatic quoting. How, there are two ways. First, use a special unaray symbol, like plus or ampersand sign as shown. Second, call the constant as a Perl subroutine.
say @{+COLUMNS};  # first way, plus sign
say @{&COLUMNS};  # first way, ampersand sign
say @{COLUMNS()}; # second way

Similarly, if we want to use a constant in hash key, we have to prevent the automatic bareword quoting. There are many ways.
%response = (HTTP_OK() => 1);
%response = (+HTTP_OK => 1);
%response = (&HTTP_OK => 1);
$response{HTTP_OK()} = 1;
$response{+HTTP_OK} = 1;
$response{&HTTP_OK} = 1;

Not using fat arrow (=>) but plain comma.
%response = (HTTP_OK, 1);

Alternatively, instead of using array reference, we can declare the constant as list instead.
use constant COLUMNS => qw/ TEST1 TEST2 TEST3 /;

Since the `COLUMNS` constant is a list context, assessing it should be placed in the parenthesis. And calling it as Perl sub works as well.
say (COLUMNS); # first way
say COLUMNS(); # second way

Comparing between two ways, initialization using list is more readable as we do not need to dereference the constant. For example, when looping through the constant.
foreach (COLUMNS) {
    say $_;

Instead of dereferencing.
foreach (@{+COLUMNS}) {
    say $_; 

Interesting right? That's the way of Perl's TMTOWTDI.

Bridging a Wireless NIC?

In our previous post, we have setup Pi-hole in LXD through bridging of macvlan network adapter. Thus, our containers share the network segment with the host's machine network. The limitation of such setup is network bridging only works for Ethernet network adapter instead of Wifi network adapter. Because "many wireless cards don't allow spoofing of the source address" (shown in example later) and also a limitation of 802.11. Read this answer for more complete explanation.

Following this guide, I tried to create a bridge using Bridge Control tool, `brctl` and add the wireless network interface, `wlp3s0` to it.
$ sudo brctl addbr wbr0

$ brctl show wbr0
bridge name     bridge id               STP enabled     interfaces
wbr0            8000.000000000000       no

$ sudo brctl addif wbr0 wlp3s0
can't add wlp3s0 to bridge wbr0: Operation not supported

To resolve the shown error above, we need to enable `4addr` option to our Wifi adapter. The `4addr` is used so that "IEEE 802.3 (Ethernet) frame gets encapsulated in a IEEE 802.11 (WLAN) frame".
$ sudo iw dev wlp3s0 set 4addr on
$ sudo brctl addif wbr0 wlp3s0

Trying to obtain an IP from our bridge interface, `wbr0`.
$ sudo dhclient -d wbr0
Internet Systems Consortium DHCP Client 4.3.5
Copyright 2004-2016 Internet Systems Consortium.
All rights reserved.
For info, please visit https://www.isc.org/software/dhcp/

Listening on LPF/wbr0/12:34:56:78:90:01
Sending on   LPF/wbr0/12:34:56:78:90:01
Sending on   Socket/fallback
DHCPDISCOVER on wbr0 to port 67 interval 3 (xid=0x444ed350)
DHCPDISCOVER on wbr0 to port 67 interval 3 (xid=0x444ed350)

And suddenly, we lost connectivity to our Wifi connection and can't find any Wifi network adapter anymore. Because of security reason, it's hard to spoof source MAC address.

To undo this, let's remove all changes we've made. Also, we may need to reboot the machine to regain the Wifi connectivity.
$ sudo brctl delbr wbr0
bridge wbr0 is still up; can't delete it

$ sudo iw dev wlp3s0 set 4addr off
command failed: Device or resource busy (-16)

$ sudo brctl delif wbr0 wlp3s0
$ sudo iw dev wlp3s0 set 4addr off

$ sudo ifconfig wbr0 down
$ sudo brctl delbr wbr0

$ sudo systemctl restart NetworkManager

Nevertheless, there are still different ways to make this works although far more complicated. Since macvlan does not work with wireless adapter, there is an alternative way using ipvlan. However, this was proposed to be included to LXD but postponed since macvlan provides similar features. Furthermore, DHCP will not works in both methods anyway.

This Week I Learned 2018 - Week 50

Last week post or something else from the past instead.

What is the one crucial thing when buying insurance? Make sure it's guaranteed renewable. If not, after a big claim, the said issue will be exclude from your policy upon your renewal. If you have an insurance policy but not guarantee renewable, make it has unlimited coverage. Read the Bank Negara Malaysia (BNM)'s guidelines on this. Meanwhile, something related, when comes to insurance claims, you can claim from multiple insurer for Personal Accident (PA) or life. For medical, only can claim from one insurer.

Do we need to push so hard for Science, Technology, Engineering and Mathematics (STEM) education among young people? Yes and no. Yes, if we want to stay competitive in this industry. No, this will create oversupply of labour and thus wages are kept low. Thus, does not really justify for young people to go into STEM industry where wages are too low and education fee was too high for those looking for good university.

What are the best books of 2018? (via HN and Reddit) Well, you can go through the list from NPRGoodreads, The New Yorker, Science Friday, The Wall Street Journal (politics, children, science fiction, and mysteries), Esquire, Amazon Best Sellers or by category (note best seller), The Guardian, Powell, Five Books (science, fiction, and politics), Library Journal, People, Mental Floss, Indigo, Bill Gates himself (summer and winter), Barnes & Noble, Book Page, Financial Times, History Today, Space  (old and new), Smithsonian (history, science, travel, food, and children), and AV Club. There is one book that caught my attention and found in most of the recommended lists, Madeline Miller's Circe. If you don't have a good material to read for the new year, just check the best books of last year.

What happened when bad water quality and monsoon month (December) meet? Twenty dead fishes. Similar thing happened last year around December where some Betta fishes were dying in mass. Is it water hardness, pH level, ammonia level, nitrite level, or diseases? Our conclusion with  some googling suggested that all possible reason. Drastic water change (like 100%) during raining season will shock the fishes leading to low immune system. Furthermore, irregular water changes increases the possibility of ammonia poisoning overfeed without removing the remains will lead to nitrite poisoning.

One obvious symptom was group of Betta fishes cuddle together at the corner at the tank (see photo below). Last year, the same thing happened to our female sorority tank and we thought because these fishes were "bonding". Our naivety caused the total wipeout of all the female Bettas.

How do you troubleshoot DHCP issue within a container? Use tcpdump. `lxdbr0` is the default bridge network adapter used by LXD.
sudo tcpdump -ni lxdbr0 port 67

Using LXD's Instance Types to Emulate Public Clouds (Amazon, Google, or Azure) Specification

One of the challenges when developing using public clouds provides like Amazon, Google, or Azure is how do we emulate, to the closest specification of their cloud instance locally? LXD, the system container, does have a feature, where you can specify the instance-types during container creation. The public cloud specification is based on the mapping done by the instance type project. While this is not a full emulation of the actual public cloud environment, it's just the essential resource allocations like CPU, memory, disk size, or others. Nevertheless, it's a good and quick way to bootstrap your container to roughly match the resource allocated of these public cloud offering.

Before that, please check the available CPU cores and memory your machine have. In my lappy, we have 4 CPU cores and 7G of memory.
$ nproc && free -g
              total        used        free      shared  buff/cache   available
Mem:              7           6           0           0           1           0
Swap:             0           0           0

How does instance types works in LXD? Let's us create a container based on AWS t2.micro which have the specification of 1 CPU and 1 Gb RAM. All commands are equivalent but using different syntax.
$ lxc launch ubuntu:18.04 c1 -t aws:t2.micro # <cloud>:<instance type>
$ lxc launch ubuntu:18.04 c2 -t t2.micro # <instance type>
$ lxc launch ubuntu:18.04 c3 -t c1-m1 # c<CPU>-m<RAM in GB>

Check our specification of our created containers.
$ lxc config show c1 | grep -E "cpu|memory"
  limits.cpu: "1"
  limits.memory: 1024MB

Again, alternative way to get the config details of the container.
$ lxc config get c1 limits.cpu
$ lxc config get c1 limits.memory

Betta Spawn Log : BSL20181202 : HMPK Metallic Blue (S) x HMPK Metallic Blue (S)

Yet another sibling pair but this time a metallic blue pair. This is the continuity of the previous breeding pair BSL20181105 (Super Red) and BSL20181005 (Super Yellow). Again, the plan was to breed a sibling pair to produce as much fry as much so we can continue breeding multiple generation. If everything goes well and lucky, this will take several generations of breeding.

Male: HMPK Metalic Blue (S)
Age: 4+ months
Temperaments: Normal.
Size: Small (2.5cm body only)
Grade: C

Not the best one we can obtain but nevertheless, the male Betta was healthy and quite active. We fed it well and kept it within the Indian Almond leaves water just to make sure to quarantine it well. Nevertheless, this fish was fresh from the farm and bred in natural environment and fed with live food. Surely, it's better than those bred in house like us.

Female: HMPK Metalic Blue (S)
Age: 4+ months
Temperaments: Highly active.
Size: Small (2.5cm body only)
Grade: B

When we first bought this female Betta, it was so small but we've no choice, there were no female Betta available for this colour. Nevertheless, we decided to proceed ahead as we're confident to condition this female until it's ready to breed. Took us three months to make sure this female was well fed and always in Indian Almond leaves water. Just in case to prevent sickness. Luckily this female turned out to be healthy and very active.

Log Notes
Bought this pair from the Betta farm. The female was so small and we're worried that it may not be a female at all. Nevertheless, we trust the wisdom of the said Betta breeder.

2018-12-01 (1st week)
The pair mated. The female was immediately separated from the male and put into a plastic container. Since we don't have enough overnight water, the female will stay a while within the breeding box.

Female removed so it won't interfere with the male. The male moved the nest several times, most probably of interruption from us.

Black dot or hatched fry were seen in the bubble nest. Estimate the spawn size was roughly 100-plus.

2018-12-09 (2nd week)
Do plan in advanced when you want to breed the fish. The first two weeks are quite crucial as the fry needs to be fed constantly. Otherwise, the whole spawn will starve to death. Hence, if you need to travel, don't breed and also good to have hatch two batch of BBS, in case one batch does not hatch properly. Especially true if you're using expired BBS. We feed the fish two times per day and the growth and colour was noticeable.

2018-12-16 (3rd week)

1/ Always prepare backup food for the first two weeks in case the BBS did not hatch.

Pi-hole with Docker - Installation and Setup

In my previous post, I've covered Pi-hole installation and setup with LXD. For this post, we will try another installation approach, using Docker. Procedure wise, it's quite straightforward, just three steps.
$ docker pull pihole/pihole
$ wget https://raw.githubusercontent.com/pi-hole/docker-pi-hole/master/docker_run.sh
$ bash docker_run.sh

One of the issue that encountered was that the mapped ports maybe have been used for other services. to resolve the port conflicts, especially those using Ubuntu, we have to identify those processes that bind to those ports and stop it.
$ sudo netstat -nltup | grep -E ":53|:67|:80|:443"

Port conflicts with Dnsmasq in Ubuntu can be resolved by disabling its service. However, this is not advisable if you're running services that depends on Dnsmasq like LXD or VPN.

If you like alternative way to properly manage (for example, restarting) the Pi-hole's container, you can write a wrapper shell script and manage it through Docker Compose.

The wrapper shell script based on the `docker-run.sh`.
#!/usr/bin/env bash

IP_LOOKUP="$(ip route get | awk '{for(i=1;i<=NF;i++) if ($i=="src") print $(i+1)}')"
IPV6_LOOKUP="$(ip -6 route get 2001:4860:4860::8888 | awk '{for(i=1;i<=NF;i++) if ($i=="src") print $(i+1)}')"


TIMEZONE="$(cat /etc/timezone)"


exec docker-compose [email protected]

And our `docker-compose.yml` file, modified based on this sample.
version: '2'
    container_name: pihole
    restart: unless-stopped
    image: pihole/pihole
    - ServerIP=$IP
    - ServerIPv6=$IPv6
    - WEBPASSWORD=*foobar*
    - DNS1=
    - DNS2=
    - $DOCKER_CONFIGS:/etc/pihole/
    - $DOCKER_CONFIGS/dnsmasq.d/:/etc/dnsmasq.d/
    - "80:80"
    - "443:443"
    - "53:53/tcp"
    - "53:53/udp"
    - "67:67/udp"