« | » Main « | »

Mandelbox

Sunday 27 June 2010

In the last year, people have been experimenting with 3D variations of the Mandelbrot fractal. The first to get a lot of attention was the Mandelbulb, but I didn't like it, it just looks blobby to me, with no apparent self-similarity.

Then in February, a new formula appeared, called Mandelbox. It's a clever two-step formula using folding, first with squares, then with circles. The combination provides a very rich generative source.

Being a 3D structure, you can fly through it:

There's an amazing variety of textures and structures here, reminiscent of many other fractals. Some of the vistas seem like science-fiction sets, but generated by a formula rather than drawn by hand. Fascinating.

Mandelbox is a rich world to explore, and it's really new, so we can expect to see lots more innovation and exploration.

Missing words

Saturday 26 June 2010

It is said that English has about a quarter million words. So it surprises me when I can't find a word I want.

For example, we have a bunch of words that mean, "tastes good": delicious, scrumptious, delectable, appetizing, yummy, toothsome, and mouthwatering. So why is there no word that means just, "tastes bad"? We have disgusting, unpleasant, gross, and disagreeable, but none of those apply only to eating. Even the literal distasteful or unsavory are almost quaint when applied to food.

And if scary means "fills me with fear", as do terrifying, frightening, horrifying, and hair-raising, where is the word that means "fills me with anxiety"? Unnerving or nerve-racking seem to be the closest I can find, but even those seem closer to fear than to anxiety.

Time for some new words?

Chrome's email fields

Sunday 20 June 2010

In a comment on my last post, drozzy wrote:

PS: Whenever I try to post a comment on your blog, my email always gets @ and . replaced by (at) and (dot) symbols, so that I have to retype it before clicking on "add it" button. This is a bug methinks. Fyi I am using chrome.

I tried it, and sure enough, Chrome would not let a comment be submitted.

Somewhere in the reptilian brain of my comment code, I was cloaking email addresses by changing "." to "(dot)" and "@" to "(at)". This meant that when previewing a comment, the valid email that you had entered now is not a valid email address.

This is fine, except in Chrome. A couple of months ago, I changed the comment form's field to use an HTML5 type="email" field. I figured it wouldn't hurt anything, and would give iPhone users a nicer email-specific keyboard to use.

But it turns out Chrome is being even more "helpful": it won't let a form submit if an email field has an invalid email address in it. And "ned(at)nedbatchelder(dot)com" is not a valid email address, no matter how obvious it is to us humans what is meant.

I couldn't remember why I wanted to cloak email addresses like that in the first place, since they aren't displayed on the site anyway, and even if they were, it should be output like that, not input like that. So I removed the cloaking, and Chrome is working again.

Playing with Chrome a bit, it seems that they're using the same ultra-liberal validation I recommended in Humane email validation: stuff, at, stuff, dot, stuff, where stuff can't have at-signs or spaces in it, although they don't trim the string first, so a leading or trailing space will prevent the form submission. I'm a bit surprised that they unilaterally perform this validation, since there's no UI to let the user know what's going on: the field is given focus, but there's no other indication as to why the form didn't work.

It seems browser incompatibilities are inevitable. This is a big difference between the way the browsers work. And one of the key theories of HTML5 email fields is that they don't break anything, just make it nicer. Mark Pilgrim closes his exhortation on HTML5 email fields with:

To sum up: there’s no downside to converting all your email address form fields to type="email" immediately. Virtually no one will even notice, except iPhone users, who probably won’t notice either. But the ones who do notice will smile quietly and thank you for making their web experience just a little easier.

Seems to me like someone noticed...

One more thing: I considered digging into the Chromium source to find the validation to see what the real rule was, and whether it could be disabled or controlled in some way, but the Chrome project uses all custom tools, and even just pulling the source from svn indicates the use of gclient, whatever that is. Too much trouble.

Fragmented biscuit making

Saturday 19 June 2010

A quote from Alain de Botton which spoke to me:

The real issue is not whether baking biscuits is meaningful, but the extent to which the activity can seem so after it has been continuously stretched and subdivided across five thousand lives and half a dozen different manufacturing sites. An endeavor endowed with meaning may appear meaningful only when it proceeds briskly in the hands of a restricted number of actors and therefore where particular workers can make an imaginative connection between what they have done with their working days and their impact upon others.

(found on a working library.)

I'm 30

Wednesday 16 June 2010

Today's my birthday, I'm now 30. Well, 0x30, that is, 48.

Aging, whether it be biological or psychological, seems to be about two things: accretion and flexibility. The older we get, the more we have: experiences, skills, opinions, debts, possessions, and on and on. Some are positive, and some are negative. The trick is to find ways to keep the good and shed the bad, to use your accumulated stuff to make you happier and more able.

Flexibility seems to be a big part of it. Some things you carry along with you help you react well to new situations: you have experience to draw on, you have people who can help you. Some can prevent you from adapting: old habits, strongly held beliefs that no longer hold. People have a natural tendency to try to replicate past successes, to cling to what has worked. You can try to stay inside your comfort zone, but it may keep you from finding new successes. Your comfort zone can shrink over time to box you into a very narrow set of choices.

So stay nimble, keep the good, junk the bad, learn new things, shift from your center.

Or maybe another year isn't to be taken too seriously:

Recent tweets

Sunday 13 June 2010

I used to write many more short posts on this blog pointing to stuff I'd seen and liked on the web, in the spirit of the original weblogs. Now, those "go look at this" posts go onto Twitter instead. But I've missed having them here, so I'm going to occasionally pull some of my tweets into blog posts like this one.

My son Max helped by hacking together the code to grab the tweets and HTML-ify them, including un-shortening URLs where possible. He also helpfully pointed out that doing this sort of cross-posting would permanently mark me as a clueless dinosaur who didn't understand Twitter!

In any case, some of my recent tweets:

¶  curly-bracketeers vs. the indentationites vs. the parenthesesophiles: http://alarmingdevelopment.org/?p=422 (May 29)

¶  The next phase of telecommuting: http://anybots.com/ Fascinating. (May 19)

¶  How come there aren't cat cafes around here? http://seaofshoes.typepad.com/sea_of_shoes/2010/05/cat-cafes.html (May 08)

¶  Computer graphics incunabula: http://translab.burundi.sk/code/vzx/index.htm (Apr 22)

¶  RT @catherinedevlin: It's frankly impossible to imagine any security failure disrupting operations as much as our sec policies do every day. (Apr 06)

¶  Web dev's lament: http://www.youtube.com/watch?v=_DvEpWR66_8 (Apr 02)

¶  vim + soothing speaker = great! RT @tsmarsh: Great vim lessons, almost relaxing http://vimcasts.org/ (Mar 31)

¶  More stuff made purely with CSS: an entire typeface: http://desandro.com/resources/curtis-css-typeface/ (Mar 29)

¶  At last, I can properly categorize my social circles: http://matthewwmason.wordpress.com/2009/09/22/dweeb-dork-geek-or-nerd/ (Mar 27)

¶  RT @tsmarsh: This made my inner math geek very happy http://www.youtube.com/watch?v=kkGeOWYOFoA (Mar 23)

¶  Auto-generated editor themes. Why waste time picking colors when you can waste time watching code do it? http://inspiration.sweyla.com/code (Mar 23)

¶  The hazards of merely dabbling in social media: Chocolate Meltdown: http://www.ericfoster.org/?p=221 (Mar 19)

¶  Engaging tweet enticing you to watch this funny spoof of movie trailers: http://www.youtube.com/watch?v=nFicqklGuB0 (Mar 16)

¶  Nice alternative docs for jQuery: http://www.jqapi.com/ (Mar 09)

Graduated Max

Sunday 6 June 2010

My middle son Max graduated from high school today:

Max with diploma

I'm proud of his accomplishment, not because I thought there was a chance that he wouldn't graduate from high school, but because he managed it with his typical calm graceful style.

The ceremony was indoors due to the threat of bad weather which didn't materialize until an hour after we were done. Graduation ceremonies have an unfortunate sameness, but it's very cool to see your kid go through them with the costume and the speeches and so on.

Caps in the air!

Of course, we had to mark the occasion with a baked treat. In this case, it was cupcakes decorated to look like mortarboard hats:

Graduation cupcakes

We just turned the cupcakes upside down, pasted a half a chocolate bar on with a dab of frosting, made a tassel from fringed Fruit By The Foot, and attached it to an M&M button with a bit more frosting. Simple, yet effective!

Congratulations, Max! I'm looking forward to what the next phase brings...

Localization is a bitch

Sunday 6 June 2010

The latest product release at work seems to mostly have been about localization: the site is available in 26 languages. Django provides good tools to manage the translations, but there's still an awful lot of detail to attend to.

  • All the different country and language codes are easy to get wrong. Did you know that Slovenia's country code is SI, but Slovenian's language code is sl?
  • Language codes get more complicated when dealing with Chinese, which comes in both traditional and simplified forms. Do we use zh-tw, or zh_TW, or zh-hant for traditional?
  • Every visible string has to be marked with a {% trans %} tag, and you have to do it in a way that the translators can make use of. Sentences can't be broken into fragments, if you have data to plug in to a sentence, the slot has to be part of a single string to translate, with code to plug in the value:
    {% trans "There are" %} {{n_things}} {% trans "things here." %} {# BAD #}
    {% trans "There are <span>10</span> things here." %}  {# GOOD, needs code #}

On top of these sorts of technical issues, there are huge coordination problems to be solved. You have to add an extra step to your march toward shipping, which is waiting for the translations to come in.

And typically, there are last-minute copy tweaks that "have to" go live, and there's no time left to get them localized. We ended up sprinkling conditionals into the site, so that English-speaking users would see updated copy, and others would see the older, translated copy:

{% ifequal LANGUAGE_CODE "en" %}
    {# We think this is a better way to put it.. #}
    {% trans "The product is awesome!" %}
{% else %}
    {% trans "The product may be satisfactory." %}
{% endifequal %}

The plan was that at the next translation pass, all the new text would be translated, and we could remove all these conditionals (about a dozen).

Of course, once we had those tweaks in place, it turns out there were ultra-high-priority text changes that had to happen as soon as possible, and that had to be translated into all 26 languages in some expensive expedited way. Once we made those emergency changes, and ran "messages make" to pull out all the strings, we of course also pulled in all the low-priority conditionalized tweak strings. We didn't want to clog up the double-secret-probabtion translation pass with anything extra, so we hacked some more.

We added a simple no-op template tag called english_trans:

@register.simple_tag
def english_trans(s):
    return s

and then could change our English-only tweak to:

{% ifequal LANGUAGE_CODE "en" %}
    {# We think this is a better way to put it.. #}
    {% english_trans "The product is awesome!" %}
{% else %}
    {% trans "The product may be satisfactory." %}
{% endifequal %}

Now when we extract the strings from the source, only the emergency changes need to be translated, because the string extractor doesn't recognize english_trans as an indicator of a translatable string. When we next do a full translation pass, we can remove the English customization and change english_trans back to trans, and hopefully be out of the craziness for a while...

And we haven't even attempted the right-to-left languages...

« | » Main « | »