Older blog entries for jtauber (starting at number 187)

Blogging Every Day in November

For perhaps the third time, I'm going to try to blog every day for a month, starting tomorrow. I thought I'd make this meta post today as making it my post for tomorrow seems like it would be cheating.

See you back here regularly!

Syndicated 2008-10-31 11:51:35 (Updated 2008-10-31 11:51:36) from James Tauber

Pinax 0.5.0 Released

Well, I don't need to go into the history as you've all seen the video, but five months ago a project that had been brewing in my mind for a while started taking form and now I'm thrilled to announce the first official release of Pinax.

Thanks to Brian Rosner, Greg Newman, Jannis Leidel and Eric Florenzano—the core team—as well as the authors of additional third party apps we used and people who provided translations, bug reports, etc.

There'll hopefully be a number of big Pinax news items here over the next couple of months, but for now, you can join in the fun and download 0.5.0 from the Pinax Download Page.

Syndicated 2008-10-28 17:55:05 (Updated 2008-10-28 18:00:31) from James Tauber

Guinea Pigs, Karaoke Machines and Minimum Sample Size

Yesterday I read a very strange quote:

2.86% of guinea pigs admitted to veterinary hospitals in the survey had been injured by karaoke machines

from Charlie Stross talking about an article in The Register.

It got me wondering what the minimum sample size would be to get 2.86%. It turns out, to the right number of significant digits, 1 in 35 gives 2.86% so it's possible it was only 1 case out of only 35 in the survey.

Here's some Python code for working out the minimum sample size that will result in a given decimal. Note that decimal is to be given as a string so significant trailing zeroes can be used. e.g. min_sample("0.1") == 7 whereas min_sample("0.10") == 10 as you would expect.

def min_sample(decimal):
    fl = float(decimal)
    assert 0 < fl < 1
    sig_digits = len(decimal) - 2
    for sample_size in range(1, (10 ** sig_digits) + 1):
        if round(round(fl * sample_size) / sample_size, sig_digits) == fl:
            return sample_size

So the next time you read 22% of X or 24% or Y or 2.86% of Z you can quickly work out the sample size could be as low as 9, 17 or 35 respectively.

P.S. I leave it as an exercise to the reader to rewrite using the decimal module and decide whether it's worth it.

Syndicated 2008-10-18 19:57:11 (Updated 2008-10-18 19:57:12) from James Tauber

18 Oct 2008 (updated 18 Oct 2008 at 17:04 UTC) »

HSL Gradients

A few months ago, I wrote a post about Creating Gradients Programmatically in Python. The main use was to generate gradients for things like web site nav bars:

You might try to achieve the glassy look of the default nav button in the first example with a simple linear gradient from #516c7a to #7291a1 and then from #5f7f8f to #87a2af. The problem with dealing with RGB is that it's very difficult to know how to do a variation that differs in hue but has the same saturation and lightness. Or how to have more saturation but keep the hue constant.

So using the formulae from the Wikipedia page on HSL and HSV I implemented a version of gradient.py that takes HSL values instead of RGB.

Instead of specifying #516c7a to #7291a1 and #5f7f8f to #87a2af, this:

is achieved by specifying HSL (200°, 0.2, 0.40) to (200°, 0.2, 0.54) then (200°, 0.2, 0.47) to (200°, 0.2, 0.61). Note that this is much cleaner as the hue stays constant as does the saturation. Only the lightness varies to give the shiny look.

Just by increasing the saturation to 0.5 and keeping everything else the same, we get:

We can then change the hue from 200° to 0°:

With a little bit of experimentation, I found the button looked nicer if it had a slight glow, achieved by increasing the saturation by about 50% at the top and bottom. Here are the same three buttons with saturation 0.3 → 0.2 → 03 (instead of constant 0.2) and 0.7 → 0.5 → 0.7 (instead of constant 0.5):

In every case the lightness gradient was the same from one button to the next.

I found, though, that to get the shiny black, the original lightness didn't work:

Not even varying the lightness by a constant really worked, so the following is achieved with (0, 0.0, 0.40 - 0.25) to (0, 0.0, 0.54 - 0.20) and then from (0, 0.0, 0.47 - 0.25) (0, 0.0, 0.61 - 0.25):

Here is my HSL2RGB function and the reverse RGB2HSL:

[a commenter below has pointed out Python includes functions for this in the standard library already — oh well]

def RGB2HSL(R, G, B):
    fR = float(R / 255.0)
    fG = float(G / 255.0)
    fB = float(B / 255.0)
    ma = max(fR, fG, fB)
    mi = min(fR, fG, fB)
    if ma == mi:
        H = 0
    elif ma == fR:
        H = (60 * ((fG - fB)/(ma - mi))) % 360
    elif ma == fG:
        H = 120 + 60 * ((fB - fR)/(ma - mi))
    elif ma == fB:
        H = 240 + 60 * ((fR - fG)/(ma - mi))
    L = (ma + mi) / 2
    if ma == mi:
        S = 0
    elif L  0.5:
        S = (ma - mi) / (2 - 2 * L)
    return H, S, L

def HSL2RGB(H, S, L):
    if L = 0.5:
        q = L + S - (L * S)
    p = 2 * L - q
    hk = H / 360.0
    tR = hk + 0.333333
    tG = hk
    tB = hk - 0.333333

    def color(t):
        if t  1:
            t -= 1
        if t 

Syndicated 2008-10-18 02:40:44 (Updated 2008-10-18 17:48:59) from James Tauber

London Python Meetup and FOWA

I'm in London this week and next for personal reasons but I'm taking the opportunity to attend FOWA tomorrow and Friday.

I'm also delighted to have a last minute gig talking about Pinax at the London Python Meetup tonight.

If you're going to be at the Python Meetup and/or FOWA, I look forward to catching up with you!

Syndicated 2008-10-08 10:25:36 (Updated 2008-10-08 10:25:38) from James Tauber

Photo Meme

I'm late to this meme because I haven't been on my laptop (with camera) for ages. But now that I'm traveling, here I am:

This is at Logan airport on my way to London.

Syndicated 2008-10-05 15:45:32 (Updated 2008-10-05 15:45:31) from James Tauber

28 Sep 2008 (updated 29 Sep 2008 at 13:12 UTC) »

Programming Languages I've Learned In Order

  • BASIC (TRS-80 Model I)
  • BASIC (TRS-80 Color Computer)
  • 6809 Assembly
  • AppleSoft BASIC
  • 6502 Assembly
  • BASIC (BBC Micro)
  • Prolog
  • Pascal
  • Turbo Pascal (with OO extensions)
  • C++
  • C (yes, I did C++ before straight C)
  • LISP
  • Perl 4 (dabbled in 5)
  • QBasic
  • Scheme
  • Java
  • VisualBasic
  • Python
  • x86 Assembly
  • Javascript

Those in bold are the ones I've worked with recently.

(note I haven't included XSLT or TeX although they are Turing complete. Nor things like dBase II and SQL)

(idea via Dougal Matthews)

UPDATE: I'm not quite sure what to make of this, but I forgot javascript the first time around :-)

UPDATE: Added a couple more BASIC dialects and made current languages bold. You're wondering what I'm using Pascal for, right?

Syndicated 2008-09-28 11:52:55 (Updated 2008-09-29 08:52:40) from James Tauber

A Man's Gotta Do

For those of you who've been asking for A Man's Gotta Do (What A Man's Gotta Do) from Dr Horrible:

Previous songs available at More Dr Horrible.

Syndicated 2008-09-27 16:54:06 (Updated 2008-09-27 16:54:07) from James Tauber

Why 13th Chords

As the background to my music theory is more classical in nature, it used to puzzle me when I saw jazz chords like C9, Bb11 or F13. I mean, I knew what a 9th, 11th and 13th note were but I wondered why you'd call a note a 9th rather than a 2nd, or a 13th rather than a 6th and so on.

After all, when you talk about chord, you're normally talking about notes independent of octave. If you describe something as a C7 chord, you're not saying anything about whether the E and Bb are in the same octave or not.

I can't remember when, but the breakthrough came when I realised that a 9th chord isn't just a major triad with the 2nd added, but one with the 2nd and 7th added, an 11th chord is one with the 4th and 7th added.

(just as an aside: the fact 2+7=9 and 4+7=11 here is an unrelated coincidence. An 11th is 4th+octave but due to the 1-based indexing used, you add 7 not 8)

Now yes, I've seen the theory books where they show a C9 as C+E+G+Bb+D and a C11 as C+E+G+Bb+D+F and a C13 as C+E+G+Bb+D+F+A but that really didn't help emphasize that it's the existence of the 7th that makes the the chord sound like (and be described as) a C9, C11 or C13 respectively instead of, say a Csus2, Csus4 or C6.

The 3rd and 7th are really the defining notes of a chord in Jazz, particularly comping on piano where you expect the bass to provide the root. So the final light went off when I saw the closing Jazz riff of Ben Folds Five's Underground notated. There were a bunch of triads that were marked as 13th chords. So, for example, the voicing Eb+A+D was marked as F13.

Note that that voicing has just the 3rd, 7th and 13th. The 13th is also a 6th but by calling the chord F13, it's making it clear the 7th is there as well which gives the chord a very different direction it wants to go. The 7th makes the whole chord want to resolve to a C, which gives the 13th/6th (the D) more of a suspended feel it doesn't have in an F6 chord.

I find not only the 13th chord a great substitute for a 7th now, especially when it's the dominant resolving to the tonic, but I also love the 7th+3rd+13th/6th way of voicing it too.

I know this is Jazz 101 but it was a breakthrough moment for me, anyway :-)

Syndicated 2008-09-23 06:45:58 (Updated 2008-09-23 06:46:00) from James Tauber

My Talk on Pinax at DjangoCon

Including the famous Cloud27 live launch and what James Bennett described as the worst pun ever.

Syndicated 2008-09-16 10:18:26 (Updated 2008-09-16 10:18:29) from James Tauber

178 older entries...

New Advogato Features

New HTML Parser: The long-awaited libxml2 based HTML parser code is live. It needs further work but already handles most markup better than the original parser.

Keep up with the latest Advogato features by reading the Advogato status blog.

If you're a C programmer with some spare time, take a look at the mod_virgule project page and help us with one of the tasks on the ToDo list!