On Alignment Tab Characters

One of my pet peeves is the use of tab characters for alignment. Sure, this might have been acceptable in the early days of computing. But it’s really not a good idea any more.

Tabs display differently depending on the settings, since they do not come built-in with an alignment configuration.

Rather, tabs should be used for delimitation. For instance, separating the values in a table with tabs is often superior to doing so with commas.

Tabs should not be used for indentation. This is true of both code and word processor documents. Spaces are much more portable and flexible. The TAB key, on the other hand, is a perfectly reasonable shortcut for an editor to automatically indent code with spaces, or for a word processor to apply the appropriate indented paragraph style.

Multiple tabs should not be used to make tables look “nicer”. It’s the responsibility of the editor to display TSV files in a sane format; using multiple tabs is simply not portable and semantically wrong.

I realize this is a somewhat contentious topic—some people to this day still prefer tabs to spaces for indenting code, for example. My personal view is that indenting code with tabs is utterly ridiculous. I don’t personally see why this is even a debate.

My Résumé

Today I completed a lot of work on my résumé, which will serve as Write Once’s primary template. The HTML it uses is quite simple and the real formatting is done exclusively with CSS.

In the next days, I’ll continue to revise this résumé and use Write Once to generate a TeX version of it.

Write Once

I am beginning work on a résumé generator that creates beautiful typeset résumés, from HTML.

HTML is quickly becoming the standard format for semantic markup. The purpose of semantic markup is to be understood by computers. The natural step, then, is to convert semantic HTML résumés to TeX for typesetting.

This lets a user have both an expanded, online résumé, as well as a condensed and traditional paper one.

Test to Fail

In most disciplines, tests are important. An untested product is hardly better than no product. Untested products are prone to fail.

But not all tests are built equal. The human tendency is to make tests that test for success. For example, suppose I had a routine that checks if a number is greater than another. And suppose I implemented it as follows:

greater(a, b) = a ≥ b

The error in this code is obvious. There is a greater than or equal sign (“≥”), but I meant to use a greater than sign (“>”). But in practice, in more complex projects, errors will sneak in. Now imagine that my test suite looked like this:

@test greater(2, 1)
@test greater(1, 0)
@test greater(1, -2)
@test greater(100, -100)

What a comprehensive test suite! Unfortunately, this test suite will let my incorrect implementation pass. Why? Because I never once tested for failure.

Each test was written to see if the function returns the correct result when the first argument is actually greater. The test cases were written with passing in mind, not failing. We have a subconscious tendency to test for success, not failure. Tests for success are useful, but tests for failure are necessary too.

Outside of computer science, the same principle applies. Scientists and engineers would benefit from negative results as much as positive ones. In short, give failure a chance.


CS Club Resources

For SJAM CS Club, from 2014 to 2015, Ian Fox and I created a series of lessons to teach introductory computer science to high school students. These resources for CS enthusiasts are now available to the public.

I hope this is useful to other CS clubs around the world that target high school students. I also welcome any suggestions for improvements to the material.

Starting with Setting

My procedural novel generator (see also part one, part two, and part three) has now been augmented with some rudimentary support for settings, both time and place. An example follows:

Here is a tale from the world of Samoa. Samoa is mostly populated by Italians.

I, Giusa Rosi, am a thirty-nine-year-old woman. I have black hair. I have green eyes. I stand 146 centimetres tall. I am somewhat reluctant to accept new ideas. I am easily disturbed or irritated.

Baffaele Bianchiccino is a fifteen-year-old boy. He has black hair. He has green eyes. He stands 184 centimetres tall. He is very open to new ideas and experiences.

I do not know Baffaele Bianchiccino very well. I scorn Baffaele Bianchiccino. I do not trust Baffaele Bianchiccino.

One thousand three hundred sixty-four seconds ago, I walked to Lita.

Seven hundred fifty-four seconds ago, I met Baffaele Bianchiccino. Then, Baffaele Bianchiccino and I walked to Rovo.

Ten seconds ago, Baffaele Bianchiccino kicked me. I kicked Baffaele Bianchiccino.

Clearly, I have been focusing more on the story itself rather than the writing style (no serious author would mark up each line with the exact number of seconds ago the event took place).


Learn to Code

As I mentioned in my post on defence of STEM education, one of the most important skills in today’s world is how to program a computer. It really is a shame how poorly this is taught in schools. An introductory Computer Science course is at least as important as an introductory History or Geography course (and don’t get me wrong, those courses are very important!). It is absurd how many high school students don’t take it.

Liquid — A simple board game

I’m working on a new open-source game: liquid. It’s going to be a simple board game with simple mechanics but strategic gameplay.

The game is played on a 4 by 4 board, with 16 grid cells in total. Each grid cell is separated from neighbouring grid cells by walls of varying strength. The stronger walls are coloured purple, and the weaker walls are coloured red.

A four-by-four grid of cells, each with walls of varying colours.

When you hover over a square, the weakest edge of that square is highlighted in a lighter colour.

The players, blue and green, take turns clicking on squares. When a square is clicked, the player to move adds a third-square of liquid to the square. If Blue is to move, the liquid added will be blue, and if Green is to move, the liquid added will be green. Players can only click on empty squares or squares with their colour of liquid; players cannot put their liquid on opponent’s squares.

When a square is full, the player whose liquid has filled the square can click it again to destroy the weakest wall (think of it as the water pressure building up). This action will merge two squares, and is called an “explosion”. If the other square had liquid in it, it’s converted to the moving player’s colour.

Green's square is full, and the square below it is partially blue.

On Green’s move, he or she can click the full green square to merge it with another region. The weakest wall is the edge below that square.

Note that it takes three clicks to fill a square. The fourth click, which blows up the square, does not actually add any water. Therefore, it takes four clicks to explode a square with another.

One two-by-one square, four sixths of which are filled with green liquid.

Green has now moved to explode the full square. The blue liquid is converted to green liquid, and the liquid volumes are summed. Note that no additional liquid is added with this click.

Now, these two squares are functionally one region. It can be merged with neighbouring squares once it fills up, and indeed a neighbouring square might just merge with it first. Regions can also merge with other regions to form bigger regions. Regions get progressively bigger as the game progresses, until one player no longer has a legal move. That player loses the game.

In liquid, it’s common for vast regions to change hands quickly. The strategy in the game is to claim squares wisely, based off how regions can be attacked or defended. That’s where consideration of edge strengths come in.

If you try this game out, I welcome any and all feedback on any aspect of the game: the gameplay, the UI, the instructions, etc. This game is in active development and I hope to make it great.

Hack the North 2015 CTF

I had the privilege of contributing to Hack the North‘s 2015 capture-the-flag. After just under two days, it was finally solved. In all, this capture-the-flag provided a great learning experience to hundreds of those planning to attend Canada’s biggest hackathon.

The roaring success of this activity can only be described with numbers. So here they are, at least for the portions that I managed:

  • 1290 accesses of the employee panel
  • 988 login attempts on the employee panel
  • 687 attempts on the bank
  • 256 accesses on the admin panel
  • 86 accesses to the keys screen
  • 8 successes on internal node #4 (securehash)
  • 5 unique users completing the challenge

If you’re interested in the contents or solution of this challenge, please check out the in-construction solutions document.

Announcing wafy.me

I have a new website dedicated to open-source projects I contribute to: wafy.me. I will continue to post non-code related topics on my blog here. Anything interesting from wafy.me will also be cross-posted here.

Currently, this website contains literally nothing, and visually is nothing stunning to look at. That will slowly be resolved over time.