Delete All My Docker Containers

Sometimes you need a clean slate and want to completely blow away your Dockerized dev dependencies. I recently had a little trouble genuinely clearing Docker containers containing a database and a message queue which I wanted completely fresh and empty.

The following commands did the trick.

docker-compose down -v
docker system prune
docker-compose up

docker compose down stops and removes containers in the compose file. -v means “remove named volumes declared in the ‘volumes’ section of the Compose file and anonymous volumes attached to containers. This alone didn’t seem to do what I needed.

docker system prune “Remove all unused containers, networks, images (both dangling and unreferenced)”

This command may also do the trick but I haven’t had a chance to use it yet.

docker-compose down –rmi all

Determine image size in Typescript

Accurately determining the size of an image file sounds simple but the devil is in the details. This is especially true if there are lots of images, the files are stored in S3 or anywhere else that isn’t your local machine, if you have corrupt images mixed in there or any other complexities that come up in the real world.

Personally, I like to throw together a proof of concept when experimenting with third party modules or other tools I have not used before. I’ve been writing code a long time now and now I don’t believe anything works until I see it in action.

Given my wariness I decided to write some throwaway code around figuring out image dimensions in Typescript. The code I am putting up on github is in no way a comprehensive examination, nor is it good for much of anything aside from serving as a starting point for anyone wanting to test out the ‘image-size’ and ‘jimp’ image modules.

The code is at

WordPress plugin won’t deactivate

You go to the plugins page of your WordPress site, click deactivate, the page reloads but the plugin is still active. How does that even happen?

We have encountered this situation twice over the years. In both cases the cause appeared to be some other rogue plugin. Disabling the problem plugin caused the operation of our other plugins to return to normal.

Why that happens and why one plugin appears to be able to inadvertently interfere with other plugins remains a mystery. There is no easy way (afaik) to figure out which plugin is responsible. Finding it requires some trial and error which tends to dull the desire to carry on investigating once you have resolved the initial problem at hand.

I would however suggest looking at when each of your plugins was last updated by the plugin author. Many plugins have a “view details” link on the plugins page. Clicking that typically pops up a dialog. You will find information about when the plugin was last updated on the right hand side. Today our problem plugin said this…

Last Updated: 4 years ago

Right, perhaps not such a big surprise that there was a problem there. Note to self, keep an eye on how long each plugin we use goes between updates. If they get too venerable, find a replacement that is being actively maintained.

Unsetting an element from a PHP array

This is something extremely basic that, for some reason, I find myself looking up every time I need to do it. How do I remove an element from a PHP array?

Perhaps I am overly suspicious but I find myself retesting that this actually works every time I need to do it. To avoid that in the future I am now recording how it is done for posterity.

function printArray($array) {
	foreach($array as $k => $v) {
		echo "$k == $v<br>";

$array = array(1 => 'first', 2 => 'second', 3 => 'third');
echo '<br>Array with 3 elements with set indexes<br>';

echo '<br>After unsetting element with key 2<br>';

$array = array();
$array[] = 'added string 1';
$array[] = 'added string 2';
$array[] = 'added string 3';

echo '<br>Contents of array without specifying indexes<br>';
echo '<br>After removing the middle element<br>';

That code produces the following output.

Array with 3 elements with set indexes
1 == first
2 == second
3 == third

After unsetting element with key 2
1 == first
3 == third

Contents of array without specifying indexes
0 == added string 1
1 == added string 2
2 == added string 3

After removing the middle element
0 == added string 1
2 == added string 3

Note that PHP is clever enough to maintain array indexes when you start unsetting elements even if you didn’t actually specify indexes when you created the array.

Edit a C# table adapter and get hundreds of duplicate attribute errors

Today I ran into a rather bizarre problem that appears to be a bug in Visual Studio itself. It is always fun when the auto-magical functionality of Visual Studio breaks down.

After editing a table adapter in a dataset I hit compile and was greeted with several hundred compilation errors all suggesting that I was redefining things. The locations in the code were relatively nonsensical plus this code compiled 30 seconds ago. Lots of lots of errors like these…

Error CS0579 Duplicate ‘global::System.Serializable’ attribute

Error CS0579 Duplicate ‘global::System.ComponentModel.DesignerCategoryAttribute’ attribute

Digging through the uncommitted changes revealed that the csproj file of the project containing the dataset had been modified in an unusual way. The dataset’s dataset.designer.cs had been joined by a newly created dataset1.designer.cs. For an unknown reason rather than editing the original designer file Visual Studio had left the original alone and created a duplicate designer file alongside it. Both were included in the project and both were essentially identical which explained all of the “already defined” type errors.

After some googling here is how I fixed it.

1) Close Visual Studio

2) Delete dataset.designer.cs

3) Rename dataset.designer1.cs to dataset.designer.cs

4) Using notepad or similar open the affected csproj file. In one or two places I changed a reference to dataset.designer1.cs to instead reference dataset.designer.cs. There was one section that I simply deleted. I entirely removed the Compile block that was including the erroneously created designer file. Below you can see the one we want and the one that has to be removed.

<Compile Include="DataSet.Designer.cs">
<Compile Include="DataSet1.Designer.cs">

5) Make sure that there are absolutely no references to dataset.designer1.cs left in the csproj file. Close and save it.

6) Reopen Visual Studio. Successfully compile.

A very odd problem. Fiddly but simple enough to fix once you know how. Hopefully I will not have to do it too often.

Chinese Character Challenge – Update 1

After posting my Chinese character revision game on reddit I received some excellent feedback.

In the week since then I have been hard at work producing an updated version. Here is a link to the game for those that want to cut to the chase.

Note that I have further updated the game since writing this post and have now moved it to its own domain

Mandarin Mojo

First up, there are some things that remain undone.

1) Play an audio clip so you can hear the words. I simply haven’t gotten to this yet. I suspect it will be tricky but it is definitely on my to-do list.

2) Characters are randomly selected. There is no intelligence that prevents you from being asked about a particular character multiple times while another character gets missed.

3) Wrong answers are also randomly selected. There is no attempt to surround the correct answer with similar but incorrect characters.

4) The explosions flicker quite badly on Firefox despite displaying correctly in Chrome.

The following things are done.

1) You will now have an extra goblin in pursuit every 10 words/phrases. Hopefully this provides a little intensity boost as you progress.

2) A summary is provided of what you have got right and wrong. It simply lists every question in English, pinyin and the character(s) for you to look back on. Correct answers are in white, incorrect answers are in blue.

3) I changed the key you use to start your next round. This is to stop you accidentally starting a new round by already having your finger on the movement keys. Having a break between rounds is important now that there is the ability to look back on the question you got wrong.

4) Longer phrases were sometimes running off the edge of the game board. That should not happen anymore.

5) You can now choose to be supplied questions in English, pinyin or both.

6) Previously the same character would sometimes appear as both a correct and an incorrect answer. This should not happen anymore.

I think that is about it. Hopefully you enjoy it ūüôā

Chinese Character Challenge – A Slightly Less Dull Way to Revise

Recently I was in at Moodle HQ and another programmer there was demonstrating a space game he made that extracted questions from a Moodle quiz. I believe this is it

I began to think about various other kinds of games that could easily draw questions from a quiz. As I am making an attempt to learn to read Mandarin this seemed like a suitable starting point.

First, I trawled through my collection of past projects. I have a whole bunch of playable game prototypes just sitting there. No need to start from scratch if I don’t have to. I quickly settled on doing something with a game prototype called Endless Goblin.

Although I initially intended to pull data from a Moodle quiz I stumbled on a set of text files containing all of the characters I was interested in as well as their definitions. This made getting this information into Moodle then out of Moodle seem somewhat redundant. After all, I could just parse the text files so why bother with a whole learning management system. Directly parsing the text files is indeed what the game currently does. Moodle integration will have to wait for another day.

Once I had the parsing happening, which only required a small amount of massaging the files to fix inconsistencies, I suddenly had a large set of data available. All six HSK levels are available (what is HSK?) in both simplified and traditional characters. The user/player can choose whatever levels they want to review as well as their simplified Vs traditional preference.

Now, I’m certainly not claiming that this is a brilliant game. It is thoroughly repetitive and distinctly lacking in any sense of progress. It just endlessly feeds you English to Chinese character questions. Right now, it doesn’t even tell you what the correct answer was when you get a question wrong (although I may have fixed this by the time you read this). The game also has no ability to phrase questions the other way around, from Chinese character to English. It is however marginally more fun than grinding through characters in Memrise or Anki. At least it offers a bit of a break in the routine of revision.

There is a link to Chinese Character Challenge below. I am currently mulling ways to build a more complete game around character learning and revision.

Note that I have updated the game since writing this post and have now moved it to its own domain

Mandarin Mojo

The original prototype code is still available from See the on github for links to the sources of all of the assets that I have used.

An Attempt At Postgres Support In Moodle Elis 2.6

ELIS doesn’t currently support Postgres, which is kind of annoying. As well as annoying its a little concerning. So I decided to use a little of my spare time to see what is going on.

A big part of the reason why applications often run into problems with Postgres is because its so much more strict than other databases. MySql essentially says “yeah, that’s probably fine” and lets your slightly malformed queries slide. Not Postgres though. If your query isn’t completely correct it throws an error and you’re done.

That means that errors in Postgres aren’t just a case of an unsupported database, they can indicate undetected problems with your queries. Something is wrong and you just haven’t noticed it yet. Its a big part of the reason why I do my Moodle development in Postgres these days.

Often these problems occur in large complex queries but here is a simple illustration of a common type of error that Postgres flushes out.

Select columnA, columnB
From tableName
Group By columnA

The problem here is that you are selecting two columns, one grouped, one coming from individual rows. Theoretically you could get several values for columnB squished into a single columnA grouped row so what exactly is the database meant to return you?

Typically there will be a join condition or where condition which, in practice, probably ensures that each grouped columnA only has a single value of columnB but you can’t be entirely sure. The simple solution is this…

Select columnA, columnB
From tableName
Group By columnA, columnB

Postgres forces you to go through your queries and think about whether this solution works for you or whether there is something fundamentally wrong with the query. Large queries, particularly those involving grouping, can easily contain subtle errors that can go undetected for quite some time.

So what did I do to make ELIS work with Postgres? All I’ve done is gone through ELIS attempting to flush out and fix the various errors I encountered by making the simplest fix possible.

Note that I don’t claim to have any real knowledge of the (often complex) queries involved. I have made naive fixes that resolve the error but someone with a deeper knowledge of ELIS needs to review and test these fixes.

Some of the fixes will likely be fine. Some of the queries potentially need to be substantially rewritten. I don’t currently possess sufficient knowledge of ELIS to determine which is which.

Standard caveats apply. Do not apply these fixes to a production site. I cannot offer any kind of guarantee that these changes won’t subtly alter the data retrieved by the various queries or even outright break your site.

Ok, all of that said, here are the changes for consideration by whoever considers such things.…postgres…postgres

How To Install Moodle ELIS 2.6

I recently had to install the shiny new version of ELIS, version, as part of my work with Moodle. For the previous version one of my coworkers kindly produced a single git repository that included both Moodle itself and ELIS. This time though I was on my own.

ELIS 2.6 sees the ELIS code converted into a set of plugins to make them easier to install. Sounds good. The only issue is that there doesn’t seem to be any documentation telling me exactly what plugins I require¬†out of the large set of repositories available on the Remote Learner github account.

I will very likely have to install ELIS again at some point so, for the sake of saving myself some time in the future, here is the process.

#If you don’t have an existing Moodle installation
git clone elis
cd elis

#From within the Moodle directory
git clone local/eliscore
git clone local/elisprogram
git clone local/elisreports
git clone local/datahub

git clone blocks/elisadmin
git clone blocks/courserequest
git clone blocks/enrolsurvey

git clone enrol/elis

I’m not actually sure if all of these are actually required. I’m suspicious of some of the blocks if nothing else. I got the list of components from the Remote Learner forums and figured that I was better of having extra components rather than missing something I needed, getting mysterious errors and generally wasting time.

Fixing TypeError: Object #<Queue> has no method ‘replace’

While attempting to get Shifter to work on my laptop I ran into the following error. The fix is below.

By day I am a humble¬†Moodle¬†developer. Moodle uses YUI Shifter to bundle up its Javascript. Shifter¬†seems to work happily for everyone else but I am recording this here for when it next doesn’t work for me.

When doing anything Shifter related I was getting the below.

TypeError: Object #<Queue> has no method ‘replace’
at Object.buildJS [as js] (/usr/local/lib/node_modules/shifter/lib/module.js:324:11)
at /usr/local/lib/node_modules/shifter/lib/module.js:690:21
at /usr/local/lib/node_modules/shifter/lib/stack.js:24:38
at CB (/usr/local/lib/node_modules/shifter/node_modules/rimraf/rimraf.js:42:5)
at /usr/local/lib/node_modules/shifter/node_modules/rimraf/rimraf.js:61:16
at Object.oncomplete (fs.js:97:15)

Googling that error led me to¬† That explains the problem but how exactly do I fix it… Just making that file change on its own doesn’t do anything… Making the change then re-installing Shifter just resets that file… After some trial and error I fixed it like this.

  1. Find Shifter’s package.json. For me its at¬†/usr/local/lib/node_modules/shifter. If you aren’t sure where it is, note that the path is in the error message ūüėČ
  2. Change the required gear version as shown in the commit of that github pull
  3. In the Shifter directory run npm update
  4. Get on with the actual work that you are meant to be doing.