Thursday, February 13, 2014

Top 10 most commonly used NZ road names


This is actually a top 11. It just so happens to be that Victoria and Grey Street tied for 10th place.

The NZ Government has a lot of data available on roads in http://data.linz.govt.nz. Quite interesting, I'm going to try to post more visualisations in the future.


Sunday, February 9, 2014

If you write code, turn off your editor's scroll bars and line numbers now

I like using Gvim for writing code. These are my favorite settings:

set number! " Remove line numbers
set guioptions! " Remove scrollbar, tool bar, and menu bar

This results in an editor window without scrollbars and line numbers.


You don't need line numbers. This is why:

Line numbers are not future proof. If someone refactors a source file, the line number to code association you're brain subconsciously created is now irrelevant. What it the point in creating a line-number-to-code-association when it's going to become irrelevant information in the future?

Aren't line numbers useful for communicating between programmers? No. Function definitions should be smaller rather than large. You shouldn't need line numbers to orientate yourself within a function that is 10 lines long. If it's small, you should be able to get the gist of an entire function's purpose by glancing at it. Small functions make line number orientation irrelevant.

Aren't line numbers useful for jumping to compiler errors/stack traces/assertions? No. Use your editors/IDE's "Go To Line..." feature, or better yet use your editors/IDE's quickfix feature.

Have you tried editing a +10k source file? It looks intimidating:

You don't need scroll bars either:

Once you break the line-number-to-code-association, you'll end up jumping to functions rather than scrolling to line numbers.

The scrollbar doesn't help you get over how intimidating a +10k source file looks:


Parting thoughts

Think about it. If you've ever used an editors/IDE's default settings, you would have grown up with a code-to-line-number-association! Is this the right way to think about code?

Getting rid of this code-to-line-number-association mentality by removing line numbers and scrollbars will change your life in many ways, including:
  • It's more important to think of a source file as a collection of code rather than lines of code
  • Your brain won't be subconsciously remembering line numbers which become irrelevant
  • You don't get intimidated by large source files anymore
What do you like most: Code, scroll bars, and line numbers, or just code?

Monday, January 6, 2014

Māori bird names

I wanted to understand the distribution of the first letter of Māori bird names against the Māori alphabet better. So I made this plot:


Looks like K is the clear winner.

Happy 2014!

Sources:
http://www.doc.govt.nz/conservation/native-animals/birds/birds-a-z/
http://www.kcc.org.nz/maori-bird-names

Monday, May 13, 2013

You can catch more flies with honey than with vinegar - Being accused of of taking a break

I couldn't help myself but modify this screen:



Thought the new versions were worded better.

Monday, December 26, 2011

YABTorrent


I have just released YABTorrent. Here's the blurb from the readme:
YABTorrent is yet another Bittorrent client. This client/library is written in C with a BSD license. The client has been intended to be used as a lightweight drop-in bittorrent library. The client is in ALPHA and currently has 130+ unit tests covering the code base. For the moment the client is GUI-less. 


Why another Bitorrent Client?
There are two reasons for the existence of YABTorrent:

  1. There are no Bittorrent clients written in C that are licensed under non-copyleft licenses
  2. There are not enough Bittorrent libraries available. There is definitely space for a light-weight torrent library. YABTorrent's goal is to be used for adding bittorrent-like download capability to applications such as games.

Saturday, September 10, 2011

mmap(): Now you're coding with portals

I decided to write a circular buffer (CB) because my bittorrent client was responding to a peer's requests faster than what it could write. The poll function of my API threw me completely. My first two efforts were superseded by the third!

Effort #1: Reading straight from the CB

/**
* Get pointer of data to be read.
* @return pointer to data, null if we can't poll this much data
* */

unsigned char *cbuf_poll(
cbuf_t * cb,
const int size
);

Looks great, and would be an easy to use function. Unfortunately, boundary cases are the killer. For example, say as if you want to poll 10 bytes, but the head of the CB is currently at byte 9. This means that the caller of cbuf_poll has to know that we've hit a boundary case. In fact, the API just can't work this way, and it'd be easier on the user if the function was instead:

Effort #2: Writing from the CB to a buffer

/**
* Write data to be read to buffer "out".
* */

void cbuf_poll(
cbuf_t * cb,
const int size,
char* out
);


I'd just use a for loop for writing each byte and check the indices for the boundary conditions. Easy. But, this feels kind of slow because of the extra memory writing you wouldn't need to do if the original function worked.

Effort #3: Reading straight from the CB, using a contiguous memory space via mmap()

/**
* Get pointer of data to be read.
* @return pointer to data, null if we can't poll this much data
* */

unsigned char *cbuf_poll(
cbuf_t * cb,
const int size
);

Exactly the same as #1, but we use some mmap() magic to:
1. Create an underlying buffer of size N with mktempfs()
2. Create a memory space of size N * 2 with mmap()
3. Create a memory space that points to the beginning of the memory space in ref 2, of size N using mmap(). This space maps the underlying buffer.
4. Create a memory space that points to the middle of memory space in ref 2, of size N using mmap(). This space also maps the underlying buffer.

Wikipedia for more details: http://en.wikipedia.org/wiki/Circular_buffer

Maybe I'm thinking aloud, but this is how I visualise it:



Great for two reasons:
1. The user doesn't have to worry about boundary conditions.
2. The implementation is easier (ignoring the mmap() setup code)



Pretty cool huh? Code and SVG diagram are on Github. And if I'm allowed to stretch this to another analogy:



Thursday, August 4, 2011

CC = colorgcc

If you write fantastic code that ends up with a terminal window of errors that drives you crazy...


...then nothing beats: CC = colorgcc