Banana Pi M5 Pro Quick Review

My old ODROID-U3 has been giving me quite some headaches. Its old USB 2.0 ports and 100Mbps Ethernet port are also very limiting in 2023. Its power supply is not the best (not an uncommon issue with HardKernel’s products, certainly not uncommon among the older generation of single board computers). A hardware upgrade is therefore necessary.

I don’t really use it for anything else other than a humble home server to stream videos, music, and sometimes photos. Generally used as a private file share system at home. I already bought an 1 TB USB 3.0 HDD, so I definitely need a device that supports USB 3.0 at least. To not have a limiting network I/O, it should also have 1Gbps Ethernet port.

Why not buying a popular Raspberry Pi 4? Well, I tried, but it’s out of stock everywhere. That’s why I turned to its alternatives, initially I was going to buy another HardKernel’s ODROID product, but its pricing in Europe is just way too high than the price on its website. Unfortunately, (not sure if this has anything to do with Brexit), there is a minimum order requirement to ship to the UK. I’m building a cluster or something, so looking again…

Ta-da! I found Banana Pi, the name is a bit.. knock-off, and the manufacturer is in China, I’ll let you connect the dots. Banana Pi M5 is not the newest model, but it’s comparable to Raspberry Pi 4 and ticks all of my boxes. Long story short, I bought it from Ali-Express where it’s much cheaper than Amazon or other local retailers here. They were also running some sales on bundles, so I ended up buying it with a metal case, yet paying less.

On paper, it provides even better performance than Raspberry Pi 4! More importantly, it’s readily available! One thing I did pay extra attention to is the availability of upstream Linux images, having suffered quite a bit there with HardKernel’s products. Thankfully, Banana Pi has Armbian support (rated platinum for Banana Pi M5, whatever platinum means). To save even few more pennies, it comes with an onboard 16GB eMMC storage!

It’s been faithfully serving its purpose on the shelf next to the router for a couple of weeks now. Reliable little machine that’s fast and responsive! If you’re thinking of buying a single-board computer like Raspberry Pi, but couldn’t find available stocks, Banana Pi might fit in.

Chrome OS, Linux Containers and Application Launchers

So I installed the great brunch framework on my laptop after a hiatus of a couple of months. I still dislike the fact that the Linux containers are running under a VM on Chrome OS. Sure it is more secure as the containers won’t be able to access the host hardware directly etc. It is also slightly inefficient. So I tried both chromebrew and brioche. Note that brioche only supports brunch (thus half of this post won’t apply to official Chrome OS builds).

Continue reading “Chrome OS, Linux Containers and Application Launchers”

Number Rounding Business

Rounding numbers is probably one of the topics in primary school. In school, we’ve learned that half rounds up, anything less than half rounds down. For example, 0.5 rounds to 1, but 0.4 rounds to 1. Duh, I’m stating the obvious you think. It only came to my attention that this is NOT really the default behaviour in a very popular programming language: Python.

Here, is a simple example to try in your own Python console.

Continue reading “Number Rounding Business”

Merge Pandas DataFrame with Nested Dictionary

Not an avid Pandas or Numpy user myself, but I had to spend some time lately to optimise probably a fairly common process: looking up a nested dictionary (2 or more levels) to find the right values element-wise for a column in a Pandas DataFrame. If it’s not clear, the problem I’m trying to solve here is to optimise a look-up function that can be done with .apply() to something more performant.

You might say, why not using .map()? Because the look-up function is not y = f(x), no, it is more like y = f(x, a) or even y = f(x, a, b), depending on the level of nestedness.

As mentioned earlier, this can be implemented with .apply() by supplying a Python function that does the look-up. However, .apply() is very slow (it’s not vectorised). The solution here is actually straightforward (I’m very new to Pandas and it took me some time to get here so I decided to make a note here for this). We first flatten the nested dictionary to have different levels of keys as tuples, which allows us to create a DataFrame with MultiIndex. With MultiIndex, we can easily apply .merge to join the DataFrame objects.

Hopefully the code snippet is more understandable.

import pandas as pd

nested_dict = {
    "A": {
        "Apple": "Red",
        "Banana": "Green",
    "B": {"Apple": "Green", "Banana": "Yellow"},
df = pd.DataFrame.from_dict(
        "Fruit": {0: "Apple", 1: "Banana", 2: "Banana"},
        "Price": {0: 0.911, 1: 1.734, 2: 1.844},
        "Bucket": {0: "A", 1: "B", 2: "A"},

# Method 1: .apply()
# Apply Python function element-wise, as slow as a regular for loop
df1 = df.copy()
df1["Color"] = df1.apply(
    lambda row: nested_dict.get(row["Bucket"], {}).get(row["Fruit"]), axis=1

# Method 2: .merge()
# Vectorized, much faster (even though the big O is the same)
df2 = df.copy()
# The only overhead is to construct a dataframe with 'MultiIndex'
nested_df = pd.DataFrame.from_dict(
        (inner_key, outer_key): value
        for outer_key, outer_value in nested_dict.items()
        for inner_key, value in outer_value.items()
nested_df.index = pd.MultiIndex.from_tuples(nested_df.index)
nested_df.rename(columns={0: "Color"}, inplace=True)
df2 = df2.merge(nested_df, how="left", left_on=("Fruit", "Bucket"), right_index=True)

Building KDE Frameworks on Windows from Source

Some notes on how to build KDE Frameworks packages from source on Windows using Visual Studio tools.

To do so, you need to first have a version of Qt compiled by MSVC installed. Some system environment variables to be set, using Qt 5.15.2 as an example:

  • PATH needs to add C:\Qt\5.15.2\msvc2019_64\bin
  • Qt_DIR needs to be set to C:\Qt\5.15.2\msvc2019_64

Example instructions for building CMake-based projects (all KDE projects), the command below should be executed in x64 Native Tools Command Prompt.

mkdir build && cd build
cmake .. -G "NMake Makefiles" -DCMAKE_INSTALL_PREFIX="C:\Qt\5.15.2\msvc2019_64"
nmake && nmake install

This will install the compiled KDE module into the Qt installation path. You can install it elsewhere, but if you do, make sure you update PATH environment variable accordingly.

A New Termux Mirror

TL; DR. is a new Termux packages mirror! Maintained by me, synchronised every six hours, located in the United Kingdom, hosted by Oracle Cloud.

In the full article below, I’ll write up how to set up a Termux mirror (or in general, a Debian packages repository mirror).

Continue reading “A New Termux Mirror”

Building Qt for Termux Android

This is by all means, not the first blog post about Termux. It serves as a journal for myself, as well for anyone who’s interested in cross building Qt or Qt-related projects for Termux (which is a native Linux environment for Android) from their x86_64 machines.

We already have @xeffyr who has done a great amount of work on building Qt for Termux. The work I’ve done recently would be 10 times harder, if not for what’s achieved by them already.

If you’re new to cross building for Termux, I recommend you to start with Developer Wiki.

Continue reading “Building Qt for Termux Android”

Fedora Linux with MATE Desktop on Android

I know some of you geeks have already done something like that, running a GNU/Linux distribution on top of an Android device. It’s an interesting time, with projects like proot we don’t need root privilege on our Android devices to run a containerized Linux environment. Here in this post, I’ve written down the steps that I’ve taken to have a usable desktop environment up running on my Galaxy Tab S5e (this blog post has been written up purely within such environment).

Continue reading “Fedora Linux with MATE Desktop on Android”

Building Linux Kernel on Odroid-U3

This is the year 2020, Odroid-U3 is far from a powerful ARM development board in today’s standard, but it is still more than capable! Quad-core ARMv7 CPU and 2GB RAM, which means I can still run some light services and test my toy projects without paying any fees to AWS or Azure. The year 2020 also means that this little device can be powered by the mainline Linux kernel without many troubles (if any)! Better than that, the process is ridiculously straightforward!

In this post, I put together the steps I did to build the Linux kernel using upstream mainline source code natively on Odroid-U3. If you’re interested in cross-building from your x86 machines, you can find plenty of tutorials on that on the Internet.

Continue reading “Building Linux Kernel on Odroid-U3”

Virtual Linux Desktop Experience in Azure

I wouldn’t believe that I will be writing this 10 years ago. It’s 2020 though. Microsoft has improved a lot of services for Linux, ranging from developer tools like Visual Studio Code, to the protagonist today: Azure (cloud computing). Azure has steadfastly become a real credible alternative to Amazon EC2 (or AWS in general). Today, I want to share my experience of using a virtual machine on Microsoft Azure cloud. To be more specific, it is a Linux desktop virtual machine (SLES 15).

Continue reading “Virtual Linux Desktop Experience in Azure”