GNU Octave for continuous integration

Cross-platform developers for Matlab / GNU Octave run into numerous compatibility issues. Rather than wait for frustrated users to report such a bug, use GNU Octave with continuous integration. GNU Octave is available on continuous integration services including GitHub Actions, Travis-CI, AppVeyor and Azure Pipelines. In general, we strongly recommend using Octave ≥ 4.2 as the Matlab compatibility is much better in newer GNU Octave releases.

Using Matlab for continuous integration is not available in the “free” CI cloud services, and would require a custom CI setup (e.g. Jenkins) with appropriate Matlab license. Another possibility might be GitHub Actions self-hosted runner or equivalent self-hosted CI like AppVeyor

GNU Octave CI

Here are CI templates using GNU Octave tests of .m code. Octave runtests() is incompatible with the advanced functionality of Matlab runtests(), so we use our own test scripts.

GitHub Actions

Make a “".github/workflows/ci.yml”":

name: ci

    - "**.m"
    - ".github/workflows/ci.yml"


    runs-on: ubuntu-latest
    - uses: actions/checkout@v2
    - run: |
        sudo apt -yq update
        sudo apt install -yq --no-install-recommends octave
    - run: octave --eval "test_myfuncs.m"
      working-directory: tests

    runs-on: windows-latest
    - uses: actions/checkout@v2
    - run: choco install octave.portable
    - run: octave --eval "test_myfuncs.m"
      working-directory: tests


Make an .appveyor.yml including:

- Visual Studio 2019
- ubuntu

build: off

- cmd: choco install octave.portable
- sh: sudo apt-get install -yq --no-install-suggests --no-install-recommends octave > /dev/null

- octave-cli test_myfuncs.m


Make a .travis.yml including:

language: minimal
group: travis_latest

    - octave

  - os: linux
  - os: windows
    language: sh
    - choco install octave.portable
  - os: osx
    - brew install octave > /dev/null

- octave-cli test_myfuncs.m

For advanced users, consider setting up a Docker image to avoid the repeated GNU Octave installs.


For non-Windows laptops developing for Windows, consider a Windows virtual machine.

Switching from Jekyll to Hugo

Hugo can have 100x faster build times than Jekyll. Hugo offers a more powerful design experience. We recommend Hugo in general for fast, HTML5 standard compliant and robust static site generation.


Download Hugo binary

The Hugo Jekyll importer seemed broken, so we created a Python-based Jekyll to Hugo converter.

Select theme

Clone a theme into your site. Here we use “hugo-flex” theme–we have an example hugo-flex template.

cd ~/myHugoSite

git submodule add themes/hugo-flex

Enable the theme by adding to config.yaml a line:

theme: hugo-flex

Markdown syntax

Hugo Markdown parsing may use different default options or parser than Jekyll. As a result, you may need to manually fix pages’ Markdown syntax.

Categories, Tags

You may need to rewrite the internal page links to categories and tags, something perhaps like:

find content -type f -name "*.md" -exec sed -i 's,](/category/#,](/categories/,g' {} +


find content -type f -name "*.md" -exec sed -i 's,](/tag/#,](/tags/,g' {} +


To convert options you might see in examples between TOML and YaML etc. consider this web converter.

last modified metadata

Sometimes you make minor updates to a blog post without wanting to change the main posted date of the article. To have this update time reflected in the article metadata, telling search engines the “freshness” of the article, enable the last updated metadata from Git commit time by adding to config.yaml:

enableGitInfo: true

configure RSS

It’s typically beneficial to set a limit to the number of posts in the site RSS feed. This can speed the site build by a factor a 10 for large sites, and improve the update speed of search engines. Check that the RSS limit is working by checking localhost:1313/index.xml from the site preview hugo serve.

In config.yaml:

rssLimit: 10

To disable RSS for taxonomies (tags, categories) that aren’t useful for many site, additionally add to config.yaml:

  - HTML
  - HTML
  - HTML

overriding theme files

A key design pattern in Hugo is overriding theme files without editing the theme files themselves that are in a Git submodule. Use the lookup order for partials and templates. This will keep your web design clean, minimal and DRY.

redirect page URL

Hugo front matter tag aliases is equivalent to Jekyll redirect_from.

- /old-url

Fix Gfortran stack to static warning

GCC / Gfortran 10 brought new warnings for arrays too big for the current stack settings, that may cause unexpected behavior. The warnings are triggered like:

 integer :: ibig2(1000,1000)
      |                     1

Warning: Array ‘ibig2’ at (1) is larger than limit set by ‘-fmax-stack-var-size=’, moved from stack to static storage. This makes the procedure unsafe when called recursively, or concurrently from multiple threads. Consider using ‘-frecursive’, or increase the ‘-fmax-stack-var-size=’ limit, or change the code to use an ALLOCATABLE array. [-Wsurprising]


If the array is in a procedure (subroutine or function) one can workaround this warning by simply adding recursive to the front of the procedure statement. Recursive was meant to be the default for Fortran 2018 standard.

recursive subroutine foo()


As with the Intel Fortran heap-arrays command-line options, there could be a penalty in speed by having large arrays drive off the stack into heap memory.

Git difftool with Visual Studio Code

Many developers already use Visual Studio Code, which is a small and distinct program from Visual Studio available for Linux, MacOS and Windows. Currently, VS Code isn’t capable of 3-way merge, so look to Meld for git mergetool.

Configure Visual Studio Code for Git

Use VS Code for Git difftool by adding to ~/.gitconfig:

    tool = vscode
[difftool "vscode"]
    cmd = code --wait --diff $LOCAL $REMOTE


HDF5 in GNU Octave

Currently, the HDF5 capabilities of GNU Octave are very limited and are not generally useful for loading large HDF5 files from arbitrary sources. One of the most viable HDF5 Octave libraries has not been updated since 2015 and doesn’t work with recent Octave releases.

Basic HDF5 functionality

The HDF5 capabilities of Octave are not generally useful because the only way to load HDF5 files is to greedily load the entire file into a “struct” via the load() command. The save('-hdf5') command puts the HDF5 variables into an arbitrary group layout that may not be useful for your project.


A possible alternative would be to use Octave NetCDF4. NetCDF4 is a subset of HDF5. Such a file format change would have to be with concurrence of others on your project.

Microsoft Surface Go long-term review

I have used a 2018 Microsoft Surface Go for over a year. On average, much of my “admin” work use (Word / PowerPoint / grading / email / videoconferencing) and non-gaming personal use (media consumption, webinars) were done on the Surface Go. I found the 2018 Surface Go (Pentium 4415Y CPU, 8 GB RAM, 128 GB SSD) to be perhaps the best value I’ve ever had in a computer, in terms of usefulness versus price. The 2020 Surface Go 2 looks as good of a deal–however, the entry-level Surface Pro 7 has proportionatly more capability for the money. The benchmarks and initial reviews of the Core m3 2020 Surface Go 2 are favorable.

If yourself or a loved one including STEAM students / workers would benefit from a secondary device, consider the Surface Go 2 Core m3 model (8 GB RAM, 128 GB SSD) or the entry-level Surface Pro 7 (8GB RAM Core i5).

Video conferencing

The 2018 Surface Go can be adequate for videoconferencing in general, as long as you’re not using other programs at the same time. The 2018 Surface Go CPU isn’t powerful enough for the advanced features like Zoom background replacement without a green screen. While headsets are better for any laptop over the internal microphone, there isn’t a problem using the built-in array microphones of the Surface Go for speaking to live groups.

Voice commands

The 2018 Surface Go generally seems to have a great array microphone. It is relatively straightforward to dictate a first draft of text using Windows Voice Commands to compose text with the Surface Go. This is accomplished in general by pressing ⊞ Win+h in any application, bringing up a dictation bar. Windows voice dictation accuracy is not nearly as good as Android’s voice typing system, but it is OK. Especially if it’s been a long day and you just want to close your eyes and let a stream of consciousness flow.


The Surface Go can be charged at least in three ways, which we find quite flexible:

  • OEM 24 watt (Surface connector)
  • USB-C PD to Surface connector adapter (need 15 volt USB-C PD adapter, works with older Surface too)
  • USB-C PD 18 watt or higher charger


The 2018 Surface Go is fine to play video from YouTube and similar at the full screen resolution. The web browser is a bit slower on the 2018 Surface Go than on a mid-range laptop priced 3 times higher than the 2018 Surface Go.


The main downside of the 2018 Surface Go is as expected, the relatively slow dual-core Pentium 4415Y. However for most uses I find the 2018 Surface Go to feel faster than a loaded 2014 i7-4650U Surface Pro 3, despite what the benchmarks say. If one is building code and running simulations, those will feel slower on the 2018 Surface Go, like a 5+ year old laptop would feel.

Choosing a tablet PC for creative work

Since at least 2018, the creative work (school, STEAM) tablet market has had Windows and Linux devices as a great choice. Features to consider in a tablet for creative work include:

  • Windows or Linux OS instead of iPadOS or Android
  • cost $500-700
  • microSD slots to expand storage cheaply
  • 128 GB SSD instead of too-small 64 GB (unless you know a microSD card is fast enough for your work)

We don’t recommend the sub-$200 tablets in general due to poor display resolution and slow CPUs.

Windows LTE tablets are in the $700 range, but with mobile phone hotspot plans commonplace, LTE in the tablet may not be necessary. Whatever tablet one is considering for creative work, don’t neglect the ~ $100 keyboard price.

Why not Android tablets

We do not recommend Android tablets in general because they are not as well suited for creative STEAM work, especially a concern for education. We would like to see children become more creators than consumers.

Get more cost effective electronics

Typically look at last year’s models (new, and especially refurbished) to get them at about half the price of this year’s models. For refurbished electronics, the “bathtub curve” of early failure has already been worked out.

Windows select audio source / sink per app

As on Linux, it’s possible to select the audio source and sink on a per-app basis. This interface is buried in Windows control panel. The current name is “App volume and device preferences”. You can set the volume, source (input) and sink (output) for each app.

This is helpful say when an app where one-way high fidelity audio is desired instead defaults to two-way low fidelity audio. Also, modern Bluetooth devices may have the ability to use two-way audio with high fidelity listening by using A2DP for output with headset microphone input.

find MAC of Bluetooth device on Window

PyBluez can work on Windows as well as Linux.

To just find the MAC address of a Bluetooth device quickly in Windows, look under:

Windows Device Manager, Bluetooth, (select device in list), Properties, Details, Bluetooth Device Address

Read battery level

It’s possible to do certain things like read Bluetooth headset battery level without using PyBluez.

However, since Python socket.AF_BLUETOOTH only exists when the Bluetooth development library is installed into Python, this doesn’t generally work for Windows.