Welcome ! This is the personal site / blog of Graham King. Most people come for the credit card generator, but I think the Categories (top right) are more interesting.

June 16, 2009

Django dynamic forms and formsets

Posted in Software at 02:08 by Graham King

A couple of great posts which explain Django dynamic forms and advanced formset usage very clearly:

June 11, 2009

How and Why to extend Firefox in Javascript

Posted in Software at 04:29 by Graham King

I will be giving this talk on Friday 12th June, at Open Web Vancouver 2009.

June 10, 2009

Unix shared directory permissions: GUID and umask

Posted in Software at 20:11 by Graham King

I setup my Mercurial repository in the same way we used to do CVS, then SVN: A directory owned by a group, with the GUID bit, and all users who need to commit are in that group.

The steps are, create the group and add relevant users to it:


    sudo groupadd topsecretgroup
    sudo usermod -a -G topsecretgroup graham

Change the project directory to be owned by that group, and accessible by no-one else:


    cd topsecretproject/
    sudo chown graham:topsecretgroup -R .
    sudo chmod g=u,o= -R .  

Set the GUID bit on all the directories, so that new files and directories are created owned by the group:


    find . -type d | sudo xargs chmod g+s

Change the umask for everyone, so that new files are created with read and write permissions for the group:


    sudo vi /etc/profile
    change 'umask 022' to 'umask 002'

The last part, changing the umask, isn’t ideal. It works on Debian and Ubuntu, because every user has their own group. I would rather a more focused solution, just for that directory - suggestions welcome.

References:

Mercurial and permissions
Multiple Committers
Change Ubuntu global umask
Collaboration models

May 27, 2009

Legal 1 Usability 0

Posted in Misc at 19:55 by Graham King

The cooking instructions for my Tandoori Chicken Breast microwave lunch, are to cook…

…until internal temperature reaches 74C (165F).

How many office kitchens have a cook’s thermometer? Score nothing for usability.

Should you for any reason attempt to sue the manufacturer, it will rapidly become apparent that you didn’t follow the cooking instructions. Score one for legal.

May 21, 2009

OpenTTD: Trains and signals for beginners - a tutorial

Posted in Misc at 08:22 by Graham King

I have been playing Open Transport Tycoon Deluxe, or OpenTTD on and off for a while, but I confess I only understood train signals very recently. The game gets a lot more fun once you can have complex track layouts, so here’s a tutorial on train track layout and signaling for complete beginners.

Building tracks the wrong way

If you’re anything like I was, all your train layouts probably look like this:

one-to-one

You can only run one train on that track, but say you’re happy with that. When you need to connect another station, you might, unsuccessfully, try this:

two-stations-naive

Notice the three two-way signals. A signal locks an entire section of track from that signal until the next signal or the end of the line. These signals define four locks, color coded on this screenshot. If the train from Lundinghattan Ridge is in the Mardingbury station, it will have a lock on the yellow section, but not on the green section. The signal nearest Mardingbury will be red, but the other two signals will be green. The train from Marbourne will be able to acquire a lock on the green section, and stop at the signal nearest Mardingbury. We have a train stand-off. Not good.

To make that layout work, you’d need to remove the signal nearest Mardingbury, thereby merging the green and yellow sections. You remove that, and you have two trains sharing a station. OK, so now you add a third station to your network. Now things really start to break down.

blocked

The blue section is shared between the Lundinghattan train and the Chenningpool train. The Lundinghattan train is top left, just leaving Mardingbury station. It has the lock on the yellow section. Notice the two signals nearest it are red (actually all the signals in this picture are red, but focus on just those two). The train from Chenningpool acquired the lock on the blue section, but and this is the first important concept of this tutorial, once it got level with the depot it had a choice of two paths: Mardingbury, which is blocked by a red signal, and the depot, which isn’t. A train faced with a red two-way signal will always avoid that signal, even if that means going away from it’s destination. If instead of the depot we had a track running to the other side of the map, our Chenningpool would of happily headed down it, to avoid the red signal.

In practice this means our Chenningpool train will head into the depot, turn around, and head back to Chenningpool. It will never make it to Mardingbury. There is something very wrong with our approach, and the short answer is that we were using two-way tracks and two-way signals. We need to think one-way. Let’s start again.

The basic loading loop

Every shared station should have a one-way loading loop.

loading-loop

Notice the signals around the loop are all one-way. To place a one-way signal place a signal as normal, then click the signal again, once or twice depending on the orientation you want for your signal.

Now let’s connect our loop up to a town, and run two trains betweens those two towns.

shared-track1

We connected the shared track from Marbourne to our loading loop, with two short one-way sections. We can see the back of a one-way signal in the red circle, and the front of a one-way signal just to the right of the blue circle.

Let’s look at what’s going on in this picture. The train circled in red has the lock on the red section of track, and is held at the signal circled in red. It is waiting for a lock on the blue section of track. Notice that it could of kept going around the loop, instead of branching off and stopping at the red signal. Faced with a red one-way signal and a clear track going the wrong way, the train will stop at the signal, which is nearly always what we want. This is exactly the opposite to what would of happened with two-way signals.

The train circled in blue has the lock on the blue section of track, and is about to acquire the lock on the yellow section. As soon as it does, it will release the lock on the blue section, and the train circled in red will move forward. This is a layout that works.

Prefer one way tracks

Let’s connect up the other two towns, and not get blocked this time. The trick is to make all shared sections of track one-way.

one-way

The only two-way signals in this picture are circled in blue. All the others are one-way. The two-way signals are there to prevent a train on the two-way track from locking part of the one-way loop. If the left-hand two-way signal was not there, a train in Lundinghattan station would hold a lock on it’s two-way section of track, and the bottom part of the one-way section, up to the next signals. Remember, a lock is between two signals or the end of the track. Incidentally, stations don’t end a lock. If you had a station half-way along a track, the lock would run right through it until the next signal.

Pre-signals, the pro-layout

Mardingbury is getting quite busy now, we’d like to have two tracks in the station. Stop all the trains (or be quick!), bulldoze the station, and build a new, two track one. I moved mine back a square to allow space for the tracks to merge. and made the loading loop a little bigger. To control access to a multi-track station, you need pre-signals.

Pre-signals come in two types, entrance and exit. An entrance pre-signal will be red if all the exit pre-signals behind it are also red. The motivation for pre-signals is nicely illustrated here: Pre-signals on the OpenTTD wiki.

pro1

The entrance pre-signal is circled in blue. Notice that it has a horizontal white-bar, to show it is different. The exit pre-signals are circled in purple, and have vertical white bars. There is currently a train in the station, so one of the exit pre-signals is red. Because one of the tracks is free (green signal), the entrance pre-signal is green. The next arriving train will correctly go to the empty track. Even though they are pre-signals, we are still using one-way signals

What you can’t see on the picture, but which are very important, are the two normal one-way signals circled in black. They control station exit, by forcing a train wanting to leave the station to acquire a lock on the yellow section. This prevents two train leaving at the same time crashing into each other.

When a train is in the station, it still holds a lock on it’s section of track. The lock runs from the exit -pre-signal at the entrance to the station, to the regular one-way signal at the exit of the station.

Scaling it up

You now know all the key concepts, the rest is just more of the same. Here for example is what you would do if Lundinghattan got busy.

two-loading-loops

You give it a loading loop, and a multi-bay station. Pre-signals control station entrance, and regular one-ways control the exit. You can see the one-way’s at the exit much better on this station.

There’s one final change we need to make to allow lots of trains - we need to replace the two-way section highlighted in blue with two one-way sections.

pro-final

We don’t have any more two-way signals. Each station has a loading loop, and one-way tracks connect the stations. In our first tries we had one track connecting the stations, and could only run one train between them. Now we have two tracks connection the stations, and in this picture alone there are eight trains, all serving Mardingbury. Now that’s more like it!

The stations are quite close together, so it might not be clear what is loading-loop and what is the tracks that connect them, so here’s an example with stations further apart.

pro-big

Other stations would have their own loading loops, and as long as the one way tracks connect, you end up with a network spanning the world. Trains can run from anywhere to anywhere, and new stations just need plugging in to the network.

I have one final tip: Playing with virtual toy trains can be quite addictive, so remember to get some sleep :-)

May 20, 2009

Quote of the day: Why racists have bad graphic design

Posted in Society at 17:34 by Graham King

Charlie Brooker on a television advert by the British National Party, England’s (very small) right-wing political party:


Extremist material of any kind always looks gaudy and cheap, like a bad pizza menu. Not because they can’t afford decent computers – these days you can knock up a professional CD cover on a pay-as-you-go mobile – but because anyone who’s good at graphic design is likely to be a thoughtful, inquisitive sort by nature. And thoughtful, inquisitive sorts tend to think fascism is a bit shit, to be honest. If the BNP really were the greatest British party, they’d have the greatest British designer working for them – Jonathan Ive, perhaps, the man who designed the iPod. But they don’t. They’ve got someone who tries to stab your eyes out with primary colours.

Read the article: Charlie Brooker on the BNP and their political broadcast.

May 17, 2009

Speaking at Open Web Vancouver 2009 in June

Posted in Future of Web Apps, Software at 22:30 by Graham King

I will be speaking at Open Web Vancouver on Thursday, June 11, 2009 and Friday, June 12, 2009.
That’s in Vancouver, B.C., Canada. There’s a very interesting speaker lineup, and the whole conference is reasonably priced, so come along, learn, interact, and enjoy Vancouver in the summertime.

My talk will be entitled How and Why to Extend Firefox in Javascript (and Thunderbird, Komodo, and Songbird). I will post the slides here in June.

See you there!

May 10, 2009

Micro-Zooids: A story

Posted in Ideas, Misc, Software, Strategy at 23:23 by Graham King

When I was 16, I wrote a computer game, called Micro Zooides. It was called that partly because on Windows .EXE files all start with the two characters MZ, and partly because it was about small creatures. Micro-Zooides was going to be about humanity’s progress, it was going to be Civilization, which didn’t exist yet.

The game had a splash screen of a Far Side comic, then a short video of me tromping through the woods like a Neanderthal, which my Dad filmed and which I digitized with a very early video capture card.

In Borland’s Turbo C++ 3.0 I wrote a basic graphics engine to display the tiles of the world, and an event loop so I could move the main character around the world. I drew sprites for a proto-human (the micro zooid), dirt, rocks and sticks. He could walk around the world, and pick up and put down rocks or sticks.

Then I took a break to plan. I have a proto-human, rocks, and sticks. How do I get to civilization?

May 8, 2009

Turn on debug output in SVN

Posted in Software at 00:02 by Graham King

After a desktop and server upgrade, my subversion client stopped working. I am using Digest authentication, and it kept asking me for the username and password. Wireshark showed me that the SVN client wasn’t sending the Authentication header. To find out more, I turned on Subversion’s debug output. Here’s how you do it:

Edit /etc/subversion/servers
Add this line at the end: neon-debug-mask = 511

That showed me this error: auth: '/' is inside auth domain: 0.

This means that the path I was requesting (the root of the repo) was not considered inside the AuthDigestDomain I had set in Apache.

It turns out that at some point in the upgrade of Apache, Subversion, or a library, the AuthDigestDomain requires a scheme. I had
AuthDigestDomain svn.myserver.com
whereas it should of been
AuthDigestDomain http://svn.gkgk.org.

So now you know.

May 6, 2009

Migrating from Picasa to GIMP

Posted in Misc at 06:07 by Graham King

I’ve been using Picasa to edit my pictures for a long time, and it’s an excellent program. Recently however I’ve started shooting RAW, and I’d like control, so I’ve started using GIMP. It’s more powerful and more complicated than Picasa, so to start myself off I went through all the features of Picasa and made notes on how to duplicate that operation in GIMP. Here are those notes.

Most of what Picasa does can be replicated with the Colors / Levels or Colors / Curves tool. It’s well worth spending a little time experimenting with both of those (the documentation is very good too).

Crop

In the Toolbox, click the Rectangle select tool
In its options (beneath the tools), tick ‘Fixed: Aspect Ratio’
Enter 6:4 ratio (for 1.6 sensor, most DSLRs)
Tick Highlight. Draw a rectangle on the image that you want to crop to.
Image menu / Crop to Selection

Straighten

Click one of the rulers above or to the left of the image, and drag a guideline onto your picture
In the Toolbox, select the rotate tool
Select ‘Clipping: Crop to result’. Maybe ‘Interpolation: Sinc (Lanczos3)’, although that doesn’t seem to matter
Rotate until your picture is straight, using your guideline
Click Rotate
Image / Fit Canvas to Layers or Image / Autocrop Image
Image / Guides / Remove all guides

Redeye

Filters / Enhance / Red-Eye Removal (I have never used this)

I’m feeling lucky

Colors / Levels / Auto

Auto Contrast / Auto Color

Colors / Auto / something

Fill light

Colors / Levels
Drag the middle triangle (grey) to the left

Highlights

Colors / Levels
Drag the right side (white) triangle

Shadows

Colors / Levels
Drag the left side (black) triangle

Color Temperature

Tools / GEGL Operation / color-temperature
Adjust Intended Temperature

Neutral Color Picker

Colors / Levels
There are three color pickers near the bottom right
Use the left one to select black, the middle one neutral gray, and the right one white

Sharpen

Filters / Enhance / Unsharp mask
Try these values: Radius: 1 - 5 Amount: 0.5 - 1
OR
Colors / Components / Decompose.
HSV, Decompose to layers
Switch off the hue and saturation layer
Apply the Unsharp mask, as detailed above
Colors / Components / Recompose

Sepia

Filters / Decor / Old Photo

B & W

Image / Mode / Grayscale
OR
Colors / Desaturate

Warmify

Colors / Curves
Select Blue - pull the center-right of the curve down most of a grid box
Select Red - pull the center-right of the curve up most of a grid box
OR Tools / GEGL Operation / color-temperature / Increase intended temperature by 10k or 20k

Saturation

Colors / Hue-Saturation / Pull the Saturation slider to the right

Soft Focus

Duplicate layer (right click / Duplicate or use the icon bottom of layers pane)
Filters / Blur / Gaussian Blur.. Set to 60
Reduce Opacity to ~60%
Right click on blur layer, Add Layer Mask, White (full opacity)
Click the foreground color, set S to 0 and V to 50 (or 60, 70)
Select a brush, the Paintbrush tool, paint over the parts you don’t want fuzzy
To replicate Picasa this would be a big circle somewhere in the middle of the picture

Graduated tint

Duplicate layer
Switch off Background by clicking the eye
Edit that layer with Levels and Curves to expose sky correctly
Right click on new layer / Add Layer Mask/ White (full opacity)
Select Blend tool
Draw a line on the image to make a gradient. Try again.
Click the Background eye back on
Right click on the edited layer, and Apply Layer Mask
Merge the layers

April 14, 2009

What is the point of LinkedIn?

Posted in Behaviour at 21:23 by Graham King

I’m on LinkedIn, I’m connected to 48 people. I go there, I declare to the world that I know these people. And then what?

If that sounds familiar, you’re not alone. There’s:

If it takes a blog post, a book, and a community project, to find a point to your web application, I think there may not be one.

LinkedIn tries to explain itself

Take the blog post for example. It says that LinkedIn is, and I quote, “a great way for professionals to strengthen their online brand reputation and leverage their professional network”. Huh?

How about the front page. I bet they have a super-succinct value proposition. It’ll be obvious once I get to the front page:

  • Stay informed about your contacts and industry
  • Find the people & knowledge you need to achieve your goals
  • Control your professional identity online

Let’s be honest, the reason you are ‘connected’ to these people on LinkedIn, as opposed to Facebook, Bebo, Orkut, or Friendster, is because you don’t want to “stay informed” about them. You don’t want to know what movie they watched last night.

What about the second bullet point, finding people? That’s about recruitment, and the trouble is, recruitment has gone niche.

LinkedIn seems to be built around a 1940’s model where you hire someone because they went to the same college as you: “Cambridge lad eh? Jolly good. Welcome to the company. Scotch?”

Maybe it’s all about that last bullet point, your “professional online identity”? LinkedIn is your home on the web, a virtual calling card, MySpace without the teenage exuberance? Well, if you’re in tech and your only online presence is LinkedIn, that’s less than impressive. A bit like a graphic designer printing his business cards on that machine at the mall.

LinkedIn prevents people from contacting you

If you are trying to get in touch with someone, whom we’ll call Chris, you probably start with your favorite search engine. You type in his name. Chris’ LinkedIn profile comes up. You click on it. You now have three options:

  • You can pay LinkedIn $25, and they’ll let you send Chris an email (an ‘InMail’).
  • You ask your friend Alice to ask her friend Bob to introduce you to Chris.
  • You do what I do. You hit Back. Click on the next search result, which is Chris’ blog, select the Contact or About page, and email him directly. LinkedIn just wasted your time.

I may of mentioned this before, but this is not the 1940’s. We Internet types are comfortable talking to strangers. All I want is an email address, and that’s what LinkedIn doesn’t give me.

Let’s recap

You go to LinkedIn. You declare all your connections. You complete your profile, recommend people, answer questions, and so on. You give them a lot. And what does LinkedIn do for you? They prevent people contacting you. So, what, exactly, is the point of LinkedIn?

April 7, 2009

Foxden - your life on one page

Posted in Software at 01:21 by Graham King

Update: There is now a user group for Foxden: http://groups.google.com/group/foxden-users

Foxden is a Firefox extension that allows you to tile all the web applications you use on one page. Imagine being able to see your email, your calendar, your bug tracker, feeds, twitter, whatever you use, on one page. Take a look at my setup:


Foxden screenshot

As you can see, I have (counter clockwise from top left) my email, calendar, feed reader, todo list and a local text file for taking notes.

It’s free, should work wherever Firefox 3 works, and it could be yours right now.

Download the Foxden Firefox extension

March 21, 2009

Quote of the day: Congressman Mike Honda

Posted in Ideas, Society at 18:49 by Graham King

Congressman Mike Honda, D-San Jose, writing about opening government databases:

Instead of databases becoming available as a result of Freedom Of Information Act requests, government officials should be required to justify why any public data should not be freely available to the taxpayers who paid for its creation.

Wow, what an exciting time to be in North America.

From the O’Reilly Radar.

March 18, 2009

Eddit: Reddit without the Rrrr!

Posted in Software at 17:06 by Graham King

Eddit is a bookmarklet for Reddit, which gives you more signal and less of the noise that makes you go Rrrr! Here’s how it improves reddit:

Read the rest of this entry »

March 17, 2009

Flex internals: Setting a button label

Posted in Software at 00:50 by Graham King

Most ActionScript / Flash applications have a main event loop, triggered by Event.ENTER_FRAME. This is where the animation moves along to the next frame, or the sprites of the game are re-drawn in their new places.

In the Flex framework, you are expected to call invalidateDisplayList on the framework to say you need an update, and actually do the update when the framework calls your updateDisplayList method. This is the invalidation / validation pattern.

I went searching in the Flex code to understand how this invalidation / validation step ties in with Flash’s event model. I ignored properties and sizing, and edited the code down to the bare essentials.

Here is what happens when you change the label of a button:

Read the rest of this entry »

March 15, 2009

Choosing the best Flex book - Flex book reviews

Posted in Software at 23:05 by Graham King

UPDATE March 19th: Added First Steps in Flex, and Learning Flex 3.

You’re an experienced server-side programmer, with a background in C/C++/Java/C# or Python, but no Flash experience. You want to learn Flex. Which book should you buy to learn Flex 3? I have speed-read the following, so that you don’t have to:

Read the rest of this entry »

Math Dodger: A Flash game

Posted in Misc, Software at 02:26 by Graham King

Los Angeles is under attack, by trigonometric functions! OMG! Trigo-what? If I wanted to do maths, I’d go to San Francisco!! You, like, totally gotta save L.A man. Enter your name, then move your tank.

Use the left and right arrow keys to rotate, the forward and back arrow keys to move.
The barrel of the tank is the little black line. That’s the front.

No, your tank can’t fire. Avoid the mathematical blobs. YEAH!
The longer you live, the more points you get. A score above 100 is, like, totally AWESOME! Good luck Bro.
Let me know in the comments how much you score.


Read the rest of this entry »

February 23, 2009

Javascript objects: And what is this?

Posted in Software at 03:06 by Graham King

When writing object-oriented Javascript, there are two occasions when you need to be careful that this is set correctly: In inner functions and in callbacks.

this in inner functions

  1. If you are not in an object, this refers to the global window object.
  2. If you are in an object’s method, this refers to that object,
  3. except in an inner function, when this refers to the global window object again.

Number 3 is what you need to watch for. It is considered a bug in Javascript. Here is an illustration of the three cases:

Read the rest of this entry »

January 23, 2009

Easy object-oriented Javascript the Python way

Posted in Software at 00:47 by Graham King

Javascript is not an opinionated language. At it’s heart it is a hash map. You can layer pretty much any idiom you want on top of it. I’d like to make it look like Python, and it’s pretty easy to do. They both are dynamically typed, have functions as first class objects, and can treat most types as hash maps.

Let's observe this moose

Let’s assume code for a whimsical Moose Observation Project, and translate it from Python to Javascript.

Read the rest of this entry »

January 19, 2009

This is me

Posted in Behaviour, Misc at 06:03 by Graham King

Have I told you that I have never owned a TV, and never watch it? http://www.theonion.com/content/node/28694

« Previous entries