May 082012
 

Every few months the same complaints about social networking sites appear in the press. Lack of privacy and control over who sees what is a common point of point of editorial hand-wringing. While these concerns are valid, directing them at social networking sites is misplaced, and shows a lack of understanding of the relationship these sites have with the public.

This post is an attempt to state clearly the realities of the situation. I am using Facebook as an example, not because Facebook is particularly bad, it is merely the most popular. Google Plus, MySpace, and even services like LinkedIn all share the same properties.

Reality 1: You Do Not Have a Facebook Page

No really, you don’t.

Facebook has a page on you. You occasionally log on and add more information to Facebook’s page about you, but neither the page nor the data is yours. You gave the data to Facebook when you posted it.

This is not a necessarily a bad deal. In return for maintaining Facebook’s page about yourself, you get a platform to broadcast your doings and to see Facebook’s pages about your friends and family. I don’t know about you but I enjoy both these activities and participate willingly.

Reality 2: You Are Not a Customer of Facebook

No you aren’t.

Facebook’s customers are the advertisers that buy advertising on the site, and the marketers that pay to access to the fantastic demographic data we have all provided. They are paying Facebook for this service, you are not paying anyone for anything.

I know you enjoy using the site as it is, but don’t get upset when Facebook decides to improve things for itself or its customers. The customer is always right, and you are not a customer. You are the product. Facebook gets paid providing access to you.

Reality 3: Facebook Owes You Nothing

They certainly do not.

You may have been a loyal Facebook user, diligently posting photos of your cat and that batch of cupcakes you made last month, but that doesn’t mean anything to Facebook.

You have, in fact, cost Facebook money. Server farms don’t grow on trees.

Each time you view a page or update your status, Facebook wears the cost in electricity and CPU time. But don’t worry, Facebook is willing to bear the burden to provide a better product to its customers.

Reality 4: Your Privacy is Not Facebook’s Problem

If you have uploaded something to Facebook then it is public. That is the whole point of Facebook. Sure there are privacy settings, but they just mean that Facebook makes a small effort not to show things you have marked private to random people. Nothing stops other people from re-posting the photo of you at the Christmas party, or even just printing it out and sticking to your car. If you had wanted it to be private then you wouldn’t have put it on the Internet.

Likewise, if one of your friends tagged you in a photo that you don’t want to be associated with (a common source of privacy issues), that is not really Facebook’s problem either. You have a problem with your friend.

Reality 5: Nothing is Really Removed From Facebook

You can check out any time you want, but you can never leave. Removing stuff from Facebook does not guarantee that it will not be accessible. Your data will still exists in uncounted backups, caches, redundant servers and log files. That is not even taking into account the memories of the hundreds of people who might have seen it before you “deleted” it.

If you didn’t want it seen, you shouldn’t have uploaded it.

Reality 6: Facebook Is Not Picky About Who It Deals With

Despite what I have written here, Facebook does at least pay lip service to the illusion of privacy but the same can not be said of the many developers that piggyback on its service to provide apps and games. When Facebook tells you that installing a particular App gives the developer access to your profile, they mean it. You have even less of a relationship with these developers than you do with Facebook. Your trust is a commodity to them, spend it wisely.

Reality 7: Facebook is Not (Especially) Evil

A terrible cartoon of the Facebook logo stealing your dataFacebook is just a simple company trying to make its way in the universe. By all means, use and enjoy Facebook without concern (perhaps even “like” this page). But Facebook is not your friend, and they have their own interests to look after. And besides, they take nothing that you don’t give them.

Your relationship with social networking sites will be better if you remember that.

May 012012
 

I have decided to try out social media integration on my blog for a while, because I am curious to see which posts people enjoy the most. My previous attempts failed, so now I am keeping it simple. From now on you will see both a Facebook “like” button and a Google+ “+1″ at the foot of each of my musings.

A logo made by mashing together the facebook and google+ logoThe Google button is a lot less intrusive than the Facebook solution, hitting +1 is just a small nod of approval. I think the only place it shows up is if you specifically look at your likes on Google+ itself and I am not even sure if other people get to see the things you have +1′d. The total number of +1s is all anyone sees.

Clicking the Facebook “like” button actually posts an item to your Facebook timeline. This is great for me, since your friends see that you like this link and may visit themselves, but you might not like your “friends” knowing what you like. It depends on how much you value your privacy.

Incidentally, unless I am your friend on Facebook I don’t get any special information about who clicked that button. On the G+ side, I don’t know if you +1′d me even if I am following you.

So if you like a post, click away. If you don’t like a post, leave a comment. If you don’t care, watch some cats playing on YouTube. Everybody wins.

Nov 272011
 

A few months ago I came across the following puzzle in a video game I was playing:

The starting position for the siz frogs puzzleThree frogs are happily hopping along a narrow board together when they meet another group of three frogs traveling in the opposite direction. These frogs can only move in the direction they are facing, and only if there is a space directly in front of them. Additionally, a frog can jump over the frog in front but only if there is clear space on the other side to land in.

How can the frogs (moving one at a time) pass each other and continue on their way?

Of course, this is a hoary old puzzle that most people come across and solve as children. It should be only a couple of minutes work with a pen and paper to confirm that it is possible to exchange both sets of frogs but I wouldn’t be much of a programmer if I used a piece of paper where hundreds of dollars of computer equipment would do just as well.

To solve a puzzle like this programatically requires three things: a representation of the current state of the problem, a way of generating every possibly legal move from a given position, and a way of figuring out when is a good time to stop.

Firstly, the representation of the board is a simple python list:

1
start = [1, 1, 1, 0, -1, -1, -1]

Frogs traveling right or left are represented by “1″ and “-1″ respectively. Empty spaces that frog can move into are represented by “0″. The advantage of this representation is that you can calculate the new position of a frog by:

1
newPos = pos + (representation * distance)

where pos is the current index in the array, distance is the size of the hop (either 1 or 2) and representation is either 1 or -1.

Next, we need a way of generating legal moves for a given position:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
def legalMoves(board):
	moves = []
	for pos, piece in enumerate( board ):
		jumpmove = pos + (piece * 2)
		move = pos + (piece)
		if ( piece == 0 ):
			continue
		if (not (( jumpmove < 0 ) or ( jumpmove >= len(board)))):
			if (board[jumpmove] == 0):
				t = list(board)
				t[pos] = 0
				t[jumpmove] = piece
				moves.append(t)
		if (not ((move < 0) or ( move >= len(board)))):
			if ( board[move] == 0):
				t = list(board)
				t[pos] = 0
				t[move] = piece
				moves.append(t)
	return moves

Now we need a way of keeping track of all board positions we have seen, so once we find the target we can print the states that led to the solution:

1
2
3
4
5
6
7
8
9
10
11
def evalAll( current, target ):
	next = []
	for a in current:
		n = legalMoves(a[-1])
		for q in n:
			t = list(a)
			t.append(q)
			if ( q == target ):
				return t
			next.append(t)
	return next

This code keeps a list of lists, each sublist being it’s own list of the sequence of moves investigated so far. For each sequence of moves, the next legal moves are discovered and new sequences are added to be investigated the next time this function is called. Technically this is called a breadth-first search because at all of the current legal moves are investigated before moving on the next stage. This is a very simplistic way of doing the job, but in this case the puzzle is small enough that it works well enough.

Finally, a simple wrapper that we can use to set things up and return the final result.

1
2
3
4
5
6
7
def solve(start):
	temp=[[start]]
	end = list(start)
	end.reverse()
	while(temp[-1] != end):
		temp = evalAll(temp, end)
	return temp

So now we can do this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
print solve([1, 1, 1, 0, -1, -1, -1])
 
[[1, 1, 1, 0, -1, -1, -1],
 [1, 1, 0, 1, -1, -1, -1],
 [1, 1, -1, 1, 0, -1, -1],
 [1, 1, -1, 1, -1, 0, -1],
 [1, 1, -1, 0, -1, 1, -1],
 [1, 0, -1, 1, -1, 1, -1],
 [0, 1, -1, 1, -1, 1, -1],
 [-1, 1, 0, 1, -1, 1, -1],
 [-1, 1, -1, 1, 0, 1, -1],
 [-1, 1, -1, 1, -1, 1, 0],
 [-1, 1, -1, 1, -1, 0, 1],
 [-1, 1, -1, 0, -1, 1, 1],
 [-1, 0, -1, 1, -1, 1, 1],
 [-1, -1, 0, 1, -1, 1, 1],
 [-1, -1, -1, 1, 0, 1, 1],
 [-1, -1, -1, 0, 1, 1, 1]]

Success!

You might say this is a waste of time since you figured out the problem in your head. Good for you, but try this on for size:

1
[1, 1, 1, 1, 1, 1, 1, 1, 0, -1, -1, -1, -1, -1, -1, -1, -1]
Nov 102011
 

I don’t usually keep a lot of files around. When I get a new computer I don’t tend to copy all my documents across – anything I haven’t looked at for a couple of months is probably not worth the fraction of a millimetre it takes up on the platter. On the other hand, some things I can never bring myself to delete. Here is something I rediscovered the other day:

This is one of the first MODs I wrote back on the Amiga. I never had a sampler or a very large collection of instruments, but I loved mucking around with MED trying to get a pleasant sound out of the 4 channel 8-bit sound. It is often said that there is a lot of crossover between programming and music, and the soundtracker clones of the 90s made that explicit which is possibly why I enjoyed it so much. Now days I can fire up GarageBand any time I want with any number of sampled instruments. I could say that I regret not having the time to produce music as an adult but the truth is that the inspiration isn’t there any more – my interests have moved in other directions.

Although none of my MODs ever sounded anything like as good as the music from the games and demos of the time, I am still pretty pleased with this one. It must date from form 6 (I was 16) which makes it vintage 1991. Listen to the sound of 20 years ago…

Jungle Drums MP3
Jungle Drums OGG

Sep 272011
 

Blog writers want feedback. For ages now I have been running a plugin on this blog that allows readers to quickly post things I have written to Twitter, Reddit, Facebook, etc in the hope that some of my wittier and more insightful musings might be widely distributed. The icons were there for years and, as far as I can tell, the icons were clicked exactly none times. None.

So I have removed that plugin and am trying something else.

Google+ is Google’s attempt at social media (previously) and I am liking a lot of what they are doing. It is sort of like a mixture of Twitter and Facebook, you can follow people without them reciprocating and anything you post can be shared with only a subset of people. +1 is Google’s equivalent of Facebook’s Like button.

If you are logged into G+ you can click on the +1 button to show you approve of the content and want to see more like it. You can go back through the archives and +1 as many articles as you want – go ahead, I’ll wait.

In addition, I have added my Google Plus feed to the sidebar on the right. I am not sure if I will keep this, I post very few updates, but we will see. I quite like having my long form blog posts and my short for G+ updates visible in one place.

Sep 262011
 

Jeff Minter, with his alter-ego/software company, Llamasoft, has been creating ungulate related games for as long as I can remember. On the Amiga games like Llamatron and Attack of the Mutant Camels were ridiculously over the top arcade perfection, with retro (even then) graphics, lofi sound, and pixel perfect controls. GoatUp is a fine addition to Minter’s metaphorical stable (as opposed to the real stable he probably owns.)

20110927-002135.jpg

In GoatUp, you control an incredibly nimble and fertile nanny goat who must jump from platform to platform to climb an impossibly tall tower into the sky, picking up bonus items and powerups along the way. Every so often you will meet a billy goat, kissing billy goats gives you more points and also causes you to get pregnant. After a while you instantaneously give birth to a kid that follows you around, if you survive long enough you can get a long chain of offspring trailing behind you. This is useful for defeating enemies, but disturbing if you stop to think about it. Luckily, there is no time to think – you must always be climbing and the game is hard, hard, hard.

The old games lived by their control schemes and GoatUp provides several. The only one that really works well is moving via tilting left or right, and jumping with a touch. You can tell that some thought has been put into the controls, and they work much better than the tilt controls in other games. Speaking of old games, GoatUp’s graphics are deliberately designed to look like various games from the 80′s, some pretty obscure. Part of the fun is trying to remember the particular game that is being invoked.

Recommended if you like this sort of thing.

Aug 092011
 

About fifteen hundred years ago I wrote WordApp, a Java applet tachistoscope that reads a text file from either the local filesystem or the Internet and displays it one word at a time. The idea is that it trains your brain to recognise words quickly, increasing your reading speed. I thought it was a little silly, but according to me web host’s logs WordUp still sees a bit of use even though I haven’t touched it for years.

I was hunting around for something to do with my Arduino while I waited for some other parts to arrive when I had the idea of making a physical tachistoscope that reads its data off an SD card and displays the text using an LCD display I have lying around.

The SD card contains the text to be shown. One of the potentiometers is used to vary the contrast on the LCD. The other is sampled by the CPU and converted into a delay to vary the speed at which the words appear.

Unfortunately the refresh rate of the LCD is very poor, so the text becomes almost impossible to read at even modest speeds. A better display might help, but I am not going to spend any more time and money on something so simple. Fortunately, the other parts I ordered arrived yesterday so I have other things to play with.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
/*
An Arduino implementation of a Tachistoscope.
This uses both the LiquidCrystal and SD libraries (and repective devices). The 
words are read one at a time from a file on the SD card. A simple variable resistor
is used to control the speed.
In practice this does not work terribly well since the LCD display has a poor
refresh rate.
 
Pins: 
The LCD is connected via pins 2-8. Technically I could get away without the RW pin.
The SD card reader is connected via pins 10-13 (the standard SPI pins)
The variable resistor is connected via analog A0
 
Author: Andrew Stephens http://sandfly.net.nz/
*/
 
#include <LiquidCrystal.h>
#include <SD.h>
 
LiquidCrystal lcd(8, 7, 6, 5, 4, 3, 2);
File file;
 
void setup()
{
  lcd.begin( 16, 2 );
  lcd.clear();
  lcd.setCursor(0, 0);
 
  pinMode(10, OUTPUT);  // required if I ever change the CS pin from 10
  pinMode(A0, INPUT);
 
  SD.begin(10);
  file = SD.open("test.txt");
}
 
// Skip over whitespace, positions the file position at the start of the next
// word
bool findNextWord( File& file )
{
  int r;
  while ((r = file.peek()) != -1 )
  {
    if ( !isSpace(r) )
    {
      return true;
    }
    file.read();
  }
  return false;  
}
 
// Reads a single word (anything up to the next whitespace character) into
// the given buffer
bool getNextWord( File& file, char* buffer, int bufferSize )
{
  int r;
  while ((r = file.read()) != -1 )
  {
    if ( isSpace( r ) )
    {
      *buffer = '\0';
      return true;
    }
    if (bufferSize > 1 )
    {
      *buffer = r;
      ++buffer;
      bufferSize--;
    }
  }
 
  *buffer = '\0';
  return false;
}
 
 
// originally this function did more
int readResistor()
{
  return analogRead(A0);
}
 
 
void loop()
{
  char buffer[17];
 
  if (findNextWord( file ) )
  {
    getNextWord( file, buffer, sizeof(buffer) );
    lcd.clear();
    lcd.print( buffer );
  }
  else
  {
    lcd.clear();
    lcd.print("--end--");
  }
  int v = readResistor();
  lcd.setCursor(0, 1);
  lcd.print( v );
  delay(v);  
}
Jul 182011
 

Last week I wrote about starting with digital electronics with the Arduino prototyping platform. Getting something working was easy enough but I was dissatisfied with ugly result, especially when my friend Lloyd showed up with his extremely tidy version of the same idea. The piece of cardboard had to go!

My first version used a breadboard and uncut LED leads because I thought that I would want to dismantle the components for reuse. However I have since realised that I am a grown man with a career and can easily afford the $4.50 material cost. Behold POV version 2:



I won’t be entering this in any soldering competitions but it works OK.

The code has also changed. Compiling in what amounts to a 2D bitmap was a quick way to get something up and running but it wasn’t very flexible, especially since in the future I want to display long strings of text. This means storing glyphs (letter shapes) for every letter of the alphabet (plus digits and symbols) – what I needed was a proper font; what I got was this:

I then turned to Python to generate the program data to embed in the new Arduino code. This script slices the image vertically, generating one byte (actually only 7 bits) for each slice of pixels. What comes out is a long list of byte values that can be output directly to the Arduino’s IO pins to display each section of the text, along with a set of indexes that map letters to the start and end positions of individual glyphs in the array.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
import sys
 
def GetSlice(i, pos):
	t = 0
	for q in range( pos, len(i), len(i) / 7 ):
		t = t * 2
		if ( i[q] != '\x00' ):
			t = t + 1
	return t
 
def GetGlyph( i, pos ):
	end = pos
	start = pos
	data = []
	while (end < len(i) ):
		t = GetSlice( i, end )
		if ( t == 0 ):
			break;
		data.append( t )
		end = end + 1
	return (start, end, data)
 
def GetFont( d ):
    result = []
    i = 0
    currentIndex = 0
    indices = []
    while ( i < len(d) / 7 ):
	(start, end, data) = GetGlyph( d, i )
	if ( len(data) == 0 ):
		break
	i = end + 1
	indices.append( currentIndex )
	currentIndex = currentIndex + len(data)
	result.extend( data )
    return ( result, indices )
 
if __name__ == '__main__':
    if ( len(sys.argv ) != 3 ):
        print "USAGE: program <input> <output>"
        exit()
    data = []
    i = file( sys.argv[1], "rb" )
    data = i.read()
    i.close()
    ( d, indices ) = GetFont( data )
    o = file( sys.argv[2], "w" )
    o.write( "static const int indices[] = { " + ",".join(map(str, indices ) ) + " }; ")
    o.write("\n")
    o.write( "static const unsigned char fontdata[] = { " + ",".join(map(str, d)) + "};")
    o.write("\n")
    o.close()

This scheme is more complex that the original bitmap but allows arbitrary text to be display without lots of editing. The modified Arduino code now looks like this. The first two lines contain the new font data, and you can see that the text to display is simply declared on line 5.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
static const int indices[] = { 0,4,8,12,16,19,22,26,30,33,37,42,45,52,59,63,67,71,75,79,82,86,91,96,101,106,111,116,121,126,131,136,141,146,151,156,161,163,165,167 }; 
static const unsigned char fontdata[] = { 63,72,72,63,127,73,73,54,62,65,65,34,127,65,65,62,127,73,65,127,72,64,62,65,69,39,127,8,8,127,65,127,65,2,1,1,126,127,8,20,34,65,127,1,1,63,64,64,60,64,64,63,127,32,16,8,4,2,127,127,65,65,127,127,72,72,48,62,65,71,62,127,72,76,51,50,73,73,38,64,127,64,126,1,1,126,112,12,3,12,112,126,1,15,1,126,65,54,8,54,65,96,16,15,16,96,67,69,73,81,97,62,69,73,81,62,17,33,127,1,1,71,73,73,73,49,65,65,73,73,54,24,40,72,127,8,121,73,73,73,6,62,73,73,73,6,65,66,68,72,112,54,73,73,73,54,48,73,73,73,62,3,3,123,123,27,27,127};
 
static int outputPins[] = { 12, 11, 10, 9, 8, 7, 6 };
static char text[] = "ANDREW";
 
void setup()
{
  for (int i = 6; i<=12; ++i)
  {
    pinMode(i, OUTPUT);     
    digitalWrite(i, HIGH);
  }
  pinMode(13, OUTPUT);
  digitalWrite(13, LOW);
  delay(2000);
}
 
void loop()
{
  byte row = 0;
  byte endRow = 0;
  char* currentChar = text;
 
  while (1)
  {
    if (*currentChar == 0)
      currentChar = text;
    if ( row == endRow )
    {
        char t = *currentChar;
        currentChar++;
        t = t - 'A';
        row = indices[t];
        endRow = indices[t+1];
    }
    while (row != endRow)
    {
      byte mask = 64;
      for (byte pin = 0; pin < (sizeof( outputPins) / sizeof(outputPins[0])); ++pin )
      {
        digitalWrite( outputPins[pin], (fontdata[row]&mask)? HIGH : LOW  );
        mask = mask / 2; // divide mask by two, moving it down one bit
      }
      row++;
      delay(1);
    }
    for (byte pin = 0; pin < (sizeof( outputPins) / sizeof(outputPins[0])); ++pin )
    {
      digitalWrite( outputPins[pin], LOW);
    }
 
    delay(1);
  }
}

Still to do: This code is not very efficient. It uses digitalWrite() in a loop to turn on the LEDs. digitalWrite() is very easy to use but if you look at the source code you will see it does all sorts of unnecessary stuff for this job. I plan to replace it with direct writes to the required Arduino IO registers.

I also want to make the whole thing interrupt driven to free up the CPU. Why would I want the extra CPU time? I have plans for that as well…

Jul 142011
 

I have a new hobby – digital electronics! Last week I bought an Arduino Uno on a whim from JayCar. Being a typical programmer, I have very little idea how computers actually work on the physical level so this gives me an easy introduction to lower-level coding and electronics in general.

The Arduino is a small board with a fairly capable 8 bit microprocessor (an ATmega328 to be precise) with the IO pins hooked up to convenient headers ready for attaching external devices. The CPU has its own RAM and programmable flash memory, and it comes with a bootloader that can reprogram the flash via the handy USB connection (which can also power the whole board). It is hard to imagine a more plug-n-play device.

I decided that I would follow the well-worn path and create a persistence of vision device for my first project. Mine consists of 7 LEDs hooked up to IO 7 pins (via appropriate resistors), the idea is to make the LEDs blink in such a way that recognisable shapes appear as the LEDs are waved quickly in front of your eyes.

My prototype is a little rough, but works fine in a darkened room (I was too cheap to spring for super bright LEDs and the darkness hides my shoddy soldering job.) The breadboard is too fragile to wave around so the LEDs are mounted on cardboard and connected using a couple of metres of CAT5, which conveniently has 8 internal wires to supply the 7 LEDs with a common ground. The total cost is less than $10, excluding the breadboard and the Arduino itself.

The Arduino programming environment is pretty nifty. The language used is a limited form of C++ (no standard library or runtime support for much of anything) with some extra libraries for managing the CPU’s features. Compiling and flashing the CPU is as simple as pushing a button. Here is the code that generated the above picture:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
// Array holding the graphic to display
static char* text[] = {
" XX   X     X  XX     XXXX   XXXX  X     X     ",
"X  X  XX    X  X  X   X   X  X     X     X     ",
"X  X  X X   X  X   X  X   X  X     X     X     ",
"XXXX  X  X  X  X   X  XXXX   XXX   X  X  X     ",
"X  X  X   X X  X   X  X X    X     X  X  X     ",
"X  X  X    XX  X  X   X  X   X     X  X  X     ",
"X  X  X     X  XXX    X   X  XXXX   XX XX      " };
 
static int outputPins[] = { 12, 11, 10, 9, 8, 7, 6 };
static int graphicLength;
 
 
void setup()
{
	// setup the initial state of the pins
  for (int i = 6; i<=12; ++i)
  {
    pinMode(i, OUTPUT);     
  }
	// pin 13 is hardwired to the onboard LED, turn it off
  pinMode(13, OUTPUT);
  digitalWrite(13, LOW);
 
  graphicLength = 0;
  for (char* t = text[0]; *t!=0; ++t)
  {
    ++graphicLength;
  }  
}
 
void loop()
{
  while (1)
  {
    for (int i = 0; i < graphicLength; ++i )
    {
		// find out if the pin is supposed to be on (HIGH) or off (LOW)
      for (int pin = 0; pin < (sizeof( outputPins) / sizeof(outputPins[0])); ++pin )
      {
        if (text[pin][i] == ' ')
        {
          digitalWrite( outputPins[pin], LOW );
        }
        else
        {
          digitalWrite( outputPins[pin], HIGH );
        }
      }
      delay( 1 );
    }
  }
}

Not very efficient but simple enough to get going. I am already working on a more functional version which will have its own font and interrupt driven display.

Jul 072011
 

Why yes, I do have a Google+ account. Why do you ask?

Actually, it is no big thing any more. Google are slowly allowing more people on as they ramp up their Facebook-beating service. I have been using it for a day now, and I like a lot of what I see. Unfortunately, the rest of what I see sort of mystifies me instead.

Google+ is a Facebook-like service, where people publish Facebook-like status updates to Facebook-like lists of friends, maybe attaching a link or a photo kind of like you do in another social media website whose name has temporarily slipped my mind. Basically, it’s Facebook with a slightly more up-to-date look.

Google+’s main UI difference is the concept of circles. These allow you to easily group your contacts (friends, workmates, family, etc) with a snazzy drag-and-drop interface. Then you can pick which circles get to see each thing you post. It is a lot easier to use than Facebook’s group concept and more offers more granularity without being to complex.

It is early days yet, but there are things that Facebook still does better. Posting a link is nowhere near is easy – Facebook allows you to easily customise the summary it displays where Google+ only allows you to delete the summary, not replace it with your own. Notifications are also slow to arrive, but Google+ does display notifications in the other Google apps (gmail, reader) which is very handy.

One thing I was disappointed not to see what any way to link content from other sites into my Google+ stream. For instance, there is no way to automatically post links to new articles on this blog to my Google+ stream. Facebook sort of allows this with its Notes feature. I don’t use Twitter, but that doesn’t seem to be included either. Google has Friend Connect for following blogs, but that doesn’t seem to be integrated into Google+ at all. It is all very strange.

I haven’t tried the Hangout feature since I don’t have a webcam on my main computer, but it looks like it could be useful if it works as advertised. The Sparks feature (similar to Google news but not limited to current events) seem great, but doesn’t really need to be part of Google+. It would be better as a widget on the homepage.

Social Media only gets it’s usefulness from the number of people who use it regularly. Even if Google+ was as good as Facebook (which it may be soon), there is very little point in anyone maintaining two accounts across different services. Facebook got big because it was a grown-up MySpace, Google+ may be trying for a grown-up Facebook, but Facebook hasn’t annoyed its users like MySpace did (yet). I can’t see a mass migration from Facebook to Google+ happening soon unless Google has a few more cards up its sleeve.

Mar 302011
 

My friend Aaron has been working on an iPhone game for ages, and now it has finally been released. It is well worth the NZ$1.29 being charged (there is no demo version available).

TrapIt Title Page

You can see more about the game at the TrapIt official site, or jump straight to the App Store page.

I must say I am a little envious. I have been an Apple Registered iPhone developer for 3 years and haven’t managed to produce anything.

Dec 162010
 

Modern cell phones are ridiculously powerful little devices. Now that we are all carrying around general purpose computers with sophisticated sensors and ubiquitous connectivity in our pockets, a whole new world of human/machine interaction has opened up.

Apparently the iPhone has already made a bit of a splash with the partially-sighted community due to its ability to speak useful information about its location, and now somebody has taken it a step further: Augmented Reality For Colour Blindness.

I belong to the 10% of (especially masculine) men who suffer from colour blindness. I say suffer from, but most of the time it makes very little difference that certain shades of light green are indistinguishable from yellow except for one area – video games. I find games that ask you to match things based on colours very difficult, and occasionally other software uses colours in a way that people more colour-blind than myself must find very frustrating.

Using a cell phone to shift the colours in whatever the camera is looking at is a brilliant idea. I would go further and suggest that video card makers start adding similar functionality into the software they supply with the cards. A “colour-blind” mode for desktop computers (not just a high-contrast colour scheme, but some type of shader applied to the whole screen) would make life easier for many people.

Sep 152010
 

The Whale Oil court case, where blogger Cameron Slater was charged with breaching suppression orders preventing the publication of identifying details of various people, has come to its inevitable conclusion. Judge Harvey convicted Slater on 8 of the 9 charges and fined him nearly $8000. The whole judgement has been posted on Kiwiblog, and it is an interesting read.

Mr. Slater has strong opinions on name suppression, some of which sound reasonable to me. Celebrities have been known to get permanent suppression when perhaps an unknown person would not. There are arguments for and against such occurrences, but I think the courts should err on the side of the public’s right to know what is going on. Certainly the vast majority of celebrity suppression orders should be lifted if the defendant is actually convicted.

On the other hand, Whale Oil has constantly railed against suppression in cases involving sexual abuse. It seems to me that in these cases, suppression quite sensibly protects the complainants as well as the accused. At least one of the cases involved sexual abuse of minors, a non-publication order around the facts of the case allows the police to do their job without unhelpful hysteria.

My legal experience involves watching a couple of episodes of Ally McBeal, but the judgement touches on a number of points that affect blogs and other websites in this country. As somebody with a website, I have been uncertain about how the law applies – this judgement addresses this clearly.

Paragraph 19 specifically states that posts to the Whale Oil site are bound by NZ law even though the servers are physically located overseas. The description of the website “coming to the user” instead of the “user going to the site” seems sensible, but more interesting is the last sentence which states that Slater performed the act of publication in NZ by uploading the posts from this country (cf [76]). This has implications for everyone with a web site in this country.

Part of Mr Slater’s defence rested on the fact that one of the names was not published in a recognised language of this country, but instead was represented by a pictograph that had to be sounded out phonetically. This is pretty weak, and the Judge thought so too, noting in passing that

[139]…The use of phonetically coded information (which is how the pictogram resolves the name) is not unknown to Mr. Slater. I venture to suggest that the words “Whaleoil Beef Hooked” on the “masthead” of his homepage provides an example.

I can’t believe I didn’t notice that myself – it is a sad day when you need a district judge to explain a joke to you.

Paragraph 82 has Judge Harvey musing on whether merely linking to page containing suppressed details might constitute publication. This point does not come up in Police vs. Slater but, reading between the lines, I think the judge probably thinks the hyperlinks can be considered publication in some circumstances. I think in future this question is going to come down to intent. At a philosophical level publication is the act of getting information into the brains of the audience members. Whether this is done through a pictogram, or wordplay, or a suggestion that you might like to click on a link doesn’t matter. If you intended the information to be imparted, you helped publish it even if you didn’t convey the information yourself.

Judge Harvey goes to considerable length to define what a blog is, what they are typically used for (“[46] …opinion (which may be of considerable strength and sometimes of pungent articulation)…” – lol), and how the mechanisms of the blogging software present the articles to the reader. This is mainly because one of his findings hinges on the fact that Mr. Slater posted hints and clues to the identity of a subject of a suppression order over several blog posts. Although no one post could be said to breach the order, regular readers would be in no doubt what the author was getting at. Judge Harvey specifically mentions that the format of a typical blog sets it apart from a daily newspaper, where previous articles on a subject are not immediately visible down the page.

(As an aside, I enjoyed reading the judge’s explanations of various internet terms:

[30] Facebook is a well known social networking website where individuals or organisations may create a “page” and post information (written, audio or visual) to that page and share that information with “friends”.

- fantastic use of sarcastic-quotes around the word “friends” there.)

The penalty of almost $8000 seems a little high to me, but I guess the courts take a dim view of people violating their explicit orders. I doubt it is enough to stop Mr Slater from continuing his blog, which is as it should be. The internet provides great freedom to publish information on any topic to the benefit of all, but there are limits and the courts do have power over web pages as well as people.

Aug 052010
 

As a follow-up from my last post here are some more visitor statistics courtesy of Google Analytics. These are for sandfly.net.nz as a whole, not just this blog.

A world map showing the cities this site was visited from.
Last year I got nearly 18000 visits from over 4000 cities (not all appear on this map) in 128 countries. The top 5 cities are Auckland (with over 2000 visits), then London, Wellington, New York and Bangalore(!) It seems like the cities with a strong C++ development culture are better represented, but that is somewhat of a guess.

Two pie charts showing the OS and Browsers used to access this site.
These graphs show what browsers and operating systems people are using. Windows is still the most used OS at 58% but MacOSX is doing alright with 29% (Linux does 10%). This probably reflects the techie slant in the subjects I write about.

44% of my visitors use Firefox (which is what I use most of the time), but it is a three horse race for runner up between Safari (19%), IE (18%), and Chrome (13%). Chrome seems to be picking up in recent months so this graph might look quite different next year. A lot of people profess hatred for Safari, but it seems to be holding its market share (only on MacOSX though, hardly anyone uses the Windows version.) The really good news is only 2.6% of visits last year came from IE6 – the sooner that browser dies the better.

I wonder the same graphs would look like for other comparable sites.