MacBook Air 11-inch (Late 2010) revive

Recently, I revived my old laptop HP Pavilion dv3, due to the need of second computer to do my research study.

Since it is revived, and works smoothly, I then revived a tablet which was not used, Samsung Galaxy Tab 10.1 (P7500). I flashed the AOSP 7.1.2 Nougat. And it is revived also. However, the hardware specification is too antique, it can neither install Google Chrome nor Firefox. Most of the apps failed to run. ūüė©

Then lastly, there is a MacBook Air 11-inch (Late 2010), which I have installed Arch Linux onto it before. However, because it has been long time didn’t update all the packages, there are a lot of troubles.

For instance, after partial upgrade, when I ran pacman or pacman-key --init, it complained about

error while loading shared libraries:

Even after I boot with Arch Linux LiveUSB, this issue was hardly to be solved. This is because existing packages fulfil the dependencies, but the linked shared libraries’ versions were different.

Another issue was that it complained about

error: failed to commit transaction (invalid or corrupted package (PGP signature))
Errors occurred, no packages were upgraded.

This is even worst. The final solution was to install the latest gnupg, gnutls, and libassuan (as described here). Once pacman can work, then all the upgrades should work fine.


MacBook hot (heat) issue

After finished upgrading Arch Linux, there was an issue that I noticed when I first time installed Arch Linux on Mac. The machine was very hot, and the fan was spinning loudly. I firstly thought it was because of the WiFi device driver issue, because this happened even I run Arch Linux with TTY only.

I tried to install macfanctld (according to this), thermald, and cpupower (according to this). But none them solved the over heating issue.

Then after some readings from the forum (such as this post), the possible root cause was the graphic card driver issue, which Nouveau is not compatible with Mac. In order to solve this, I found the solution here (related post here) which allows me to use NVidia graphic card driver. This is a fantastic solution. I tested, and it works.

One thing to note. In the description of the solution, it says

cat << EOF
setpci -s "00:17.0" 3e.b=8
setpci -s "04:00.0" 04.b=7

Where the “00:17.0” and “04:00.0” may differ for each machine. However, “3e.b” and “04.b”, are just magic number that I just follow them. Though I don’t know what they mean actually.

Now MacBook Air is revived without overheating issue.


Bash history for each project

Previously, I tried to use zsh when I am working, so that my default bash history will not be filled with project related commands, especially git commands. Because some of my bash history are useful like ffmpeg related commands. So, I tried to distinct project work and non-project work with zsh and bash, so that they have different shell histories.

However, there are two problems when I use zsh,

  1. All my projects use the same zsh history. The old history may be lost if I have too many commands (depends on HISTSIZE variable).
  2. zsh is slow with git auto-completion.

However, zsh has one thing better than bash, that is, auto-completion navigation. Let’s say your directory has various sub-directories, double tab will bring to directory navigation that can be controlled with arrow keys. This is useful for me to navigate to non-alphabetic directories, like the directory with CJK characters.

Due to the slowness of git auto-completion as mentioned above, I decided to find an alternative solution, so that I can use bash instead of zsh, and separate the shell history from non-project work. At the end, I come out with this,


# source any shell script, like rvm or nvm

touch "$PWD/.bash_history"
history -a
export HISTFILE="$PWD/.bash_history"
history -r
export PS1='\[\033[1m\]\u@\h \[\033[0m\]\w$(__git_ps1 " (%s)")\$ ' # custom prompt to differentiate from default prompt

So, add the above content to a file like in the project directory. Whenever starting with the project, run

source ./

Hence, the .bash_history will be saved and used in the project directory.

Rename files according to date

I recently wrote a Perl script, that renames the files in a directory according to the date, in the format “YYYYMMDD ##” where “##” is the running number.


Because I used to download the photos using the mobile apps like Weibo or Twitter, however the file names are almost random. This made me hard to organize these photos on my computer.

The artists (or celebrities) usually share a set of their photos, so when I download these photos, the files should have mtime (modified time) in the correct order.

Yet, I don’t need to rename the file to the time precision like “HH:MM:SS”. I just need the date and followed by the running number, because it looks shorter.

Though we can just use the file browsers to sort the files according to the time, it is still inconvenient to browse the images by changing the sorting condition. Furthermore, mtime can be changed, and this will void the purpose of the sorting.

Lastly, the randomized filename is just meaningless to me. Rename them according to the date is much more useful, in my opinion.




Why Perl?

In my opinion, Perl is less famous like Python in the present day. But I prefer to use Perl, due to the popularity in most Linux distribution. For example Perl is the base package of Arch Linux. Once I installed Arch Linux, I can run Perl script immediately.

Though Python is great, backward incompatibility sometimes causes issue, which I may need to maintain the script. If I write with Perl, I can pay less effort to maintain the script.


WARNING! And usage

As the script mentioned,

Rename is irreversible. Recommend to make a backup.

The usage is,

./ ./target_dir

Where target_dir is the directory that contains the files you want to rename. It will not rename the files recursively.


After renaming the files, a log file will be created. It is used just in case you want to revert the file name. (But you have to do this manually.)

MySQL and PostgreSQL GUI tools

I am using Arch Linux, and recently there are some issues on MySQL Workbench and pgAdmin 4.

MySQL Workbench with the latest version 8.0.12 has issue to make connection through the SSH tunnelling. As a result, I have to downgrade to version 6.3.10. However, with the recent upgrade of icu package to 62.1, it breaks the MySQL Workbench 6.3.10. In order to solve this, I duplicate the following files,


So, it is a temporary solution until the package is fixed.

Then, for the PostgreSQL, I use pgAdmin. But again, with the recent upgrade of Python to version 3.7, which causes pgAdmin fails to start. I tried to run pgAdmin through Python 3.6 using virtualenv¬†, but it doesn’t work. So, I have tried other solutions.

I tried Adminer. It depends on PHP and Apache server, similar to phpMyAdmin. However, it is less intuitive, compared to phpMyAdmin. Because Adminer doesn’t allow inline editing value.

So, I tried SQL Workbench/J. It requires Java and PostgreSQL JDBC. Once installed required package, it can work perfectly. Similar to Adminer, SQL Workbench/J can work with database other than PostgreSQL, such as MySQL.


Catechism and the Pope

I am neither theologian nor bible scholar. But just a Catholic layperson and would like to share my opinions.

The most recent hot issue is the changing of the Catechism about death penalty by Pope Francis. Then throughout the Twitter, I can see there are a lot of debates on this issue, including some people criticising the Pope.

Therefore, in this post, I will share some of my understandings.

Regarding the Catechism of the Catholic Church (CCC), according to USCCB Question 17,

Because the Catechism presents Catholic doctrine in a complete yet summary way, it naturally contains the infallible doctrinal definitions of the popes and ecumenical councils in the history of the Church.

However, there were interesting articles about authority of the CCC and non-infallible teachings, which should be read as well.

Next, Pope is not a saint. Throughout the Church history, there were some bad popes.

There are some Twitter users share about Summa Theologiae article whether it is lawful to kill sinners. However, we must bear in mind that Summa Theologiae is a great theological work, but it is not infallible.

Since I am not an expert, I cannot discuss more about the death penalty.

However, I would like to share some of the related chapters and verses from the Bible.

St John Gospel chapter 8 mentioned about an adulterous woman, which according to the Law of Moses, she should be stoned to death. However, Jesus responded to the crowd, “Let the one among you who is without sin be the first to throw a stone at her”.

Therefore, I am asking myself, if I support death penalty, what is my actual intention? Because of my hatred and my anger towards someone? Or is it because, if my beloved is murdered, I can revenge in the name of justice? And also, if I oppose death penalty, what is my actual intention? Do I just simply follow whatever Pope says?

In Gal 2:11, it mentions that Apostle Paul “opposed [Peter] to his face because he clearly was wrong”. Therefore, I don’t think it is wrong to oppose the Pope, if the Pope is wrong. However, we must be careful to ourselves, because the way we oppose may lead to more confusion, especially when we are using social network and we have some followers. And one should pray that he or she is not opposing the Pope because of pride.

In 1 Cor 1:12-13, it says that Corinthians were dividing themselves, some say they belong to Paul, some belong to Apollos, some belong to Cephas, and some belong to Christ. Similarly, this kind of behaviour continues until today. Therefore, as Catholics, we should continually pray for the Pope and the unity of the Church.

Firefox batch download extension: DownloadSelected

In my previous post, I mentioned about DownThemAll on Firefox 56. Now the latest release of Firefox is version 61, but there is no update of DownThemAll for Firefox Quantum support. Using older unsupported version like Firefox 56 is not a good idea, because there will have no security update. Firefox ESR 52 is slower than Firefox 56 as I have mentioned.

Since I have spare time recently, I spent some days to write a Firefox extension, DownloadSelected, to solve my problem.

DownloadSelected demo

The screenshot above shows a list of URLs, which I used Greasemonkey script to generate. Then highlight, right-click, and DownloadSelected. I don’t write any UI elements to indicate the download progress, but I put the progress to the console. Once the files are downloaded, they will be archived into a zip file and a Save As dialog will be shown. The source code can be found here.

This is not a replacement or alternative extension to DownThemAll, but this extension solve my fundamental problem. Main features are:

  1. Bulk download
  2. Download only selected text
  3. Downloaded filenames are based on HTML text instead of URLs
  4. Quantum and Google Chrome compatible


Inheritance and composition

The modern JavaScript with the ES6 syntax and the rise of the popularity like ReactJS, functional programming becomes more and more common. When using React, one of the common practice is to use composition instead of inheritance.

Because I started learning programming when the OOP was the most prevailing paradigm, I was trained to solve the problem by using OOP concepts like polymorphoism, inheritance, encapsulation, etc.

I think JS is the most interesting programming language in the modern technology. It supports server-side and client-side development. With the ES6, it supports OOP keywords like class and also using FP (functional programming) syntax like fat arrow (=>).

In OOP, the most common usage is the inheritance and polymorphoism. The following is an example of inheritance in JS,

class Shape {
  constructor(w, h) {
    this.width = w;
    this.height = h;
  area() {
    return this.width * this.height;

class Rectangle extends Shape {
  constructor(w, h) {
    super(w, h);

class Triangle extends Shape {
  constructor(w, h) {
    super(w, h);
  area() {
    return super.area() / 2;

function main() {
  const rectangle = new Rectangle(4, 5);
  const triangle = new Triangle(4, 5);
  console.log('Rectangle area: ', rectangle.area());
  console.log('Triangle area: ', triangle.area());


The shape area calculation can be re-written to composition instead of inheritance as followings,

class Rectangle {
  constructor(w, h) {
    this.width = w;
    this.height = h;
  area() {
    return this.width * this.height;

class Triangle {
  constructor(w, h) {
    this.width = w;
    this.height = h;
  area() {
    const rect = new Rectangle(this.width, this.height);
    return rect.area() / 2;

Therefore, Rectangle and Triangle do not inherit from Shape. In fact, Triangle uses Rectangle to calculate the area. This is the object composition, and it is same as the way of composition in React. Furthermore, one of the greatest features of JS is closure. This allows React to pass a function with specific logic as a parameter to a generic component. Thus, the generic component can be designed without the prior knowledge of the business/application logic. This will produce a result similar to method override in OOP.

Moreover, the object composition can be re-written to function composition as FP.

const rectangleArea = (w, h) => w * h; // In math, f(x,y) = x * y
const halving = (area) => area / 2; // In math, g(x) = x / 2
const triangleArea = (w, h) => halving(rectangleArea(w, h)); // In math, h(x,y) = g(f(x,y)) = f(x,y) / 2

function main() {
  console.log('Rectangle area: ', rectangleArea(4, 5));
  console.log('Triangle area: ', triangleArea(4, 5));