Lion's glaring Cantonese bug

I was delighted to learn that Lion supports text-to-speech with a bunch of new voices that include not only non-American English accents (like Irish, South African, and to my surprise, Indian); not only non-English languages (like French as it sounds in both Canada and France); and not only two Mandarin accents (China and Taiwan); but also Cantonese.

I'm in a situation where it occasionally helps to know the Cantonese pronunciation for a phrase where I only have the written Chinese characters. Google Translate does a great job with Mandarin but has no Cantonese support. The Chinese University of Hong Kong has a site that does Cantonese text-to-speech, but the sound quality isn't great. A company called PiTL has an app that looks pretty good, but it only runs on Windows Mobile or Android, and I don't use either of those at the moment. It sure would be nice to have an iOS version.

The good news is that now, with Lion, all I have to do is select the "Sin-Ji" voice in my System Preferences. Now I can select Chinese text in any application and use the "Start Speaking" contextual menu item to hear it in Cantonese. For further convenience I've mapped "Start Speaking" to a keyboard shortcut in my System Preferences.

Here's an example of how I used this feature. A few weeks ago I got an email from a young woman named Kim who teaches an informal Cantonese class at a cafe in Chinatown. (They happened to be at the next table from me one day, and I'd gone over and talked to her.) In her email, Kim encouraged me to "guy jook hawk daw dee", which she explained means "continue to learn more".

I knew how to pronounce the "hawk daw dee". But I didn't know what the correct tones are for "guy jook", and that's not something I'd know how to find out from Kim over email. Besides, I'm a geek and wanted to figure it out myself. All I needed was the Chinese characters.

A Google search for "guy jook" turned up nothing useful. I tried "gai jook" and found that it occurs in the lyrics for a song called "Hou Sum Fan Sau" ("Break-Up With Good Intentions"). I searched for other sites with lyrics to that song and found an alternate spelling: "gai juk". Ah, I should have thought of that. Googling for "gai juk" easily found the Chinese characters I wanted:

繼續

Simplified version:

继续

Definition: "to continue; to persist".

For those of you who don't have the Sin-Ji voice installed, here's how it sounds:


Now I can pronounce Kim's whole phrase: "guy jook hawk daw dee" — "continue to learn more".

By the way, this "gai juk" should not be confused with the words for chicken congee — 鸡粥 — which sounds like this:

Can you hear the difference in tone? I ate chicken congee growing up, and it's delicious, but not what I was looking for.

Now the bad news: there's a glaring flaw in the Sin-Ji voice.

If you know any Cantonese at all, it's probably the traditional greeting "Nay ho ma?" — 你好吗? — which literally means "Are you good?" (Also often pronounced "Lay ho ma?") Naturally this is the first thing I tried when I learned about Lion's Cantonese support.

Here's how the Sin-Ji voice pronounces it:


The problem is that the "ma" is glaringly wrong. Since Cantonese is a tonal language, like all Chinese dialects, you're supposed to sort of sing each word with the correct intonation. Here's how it's supposed to sound:

I've submitted a bug report to Apple, with Radar number 9949661. I flagged it as a serious bug, because that "ma" at the end of a sentence turns it into a question. It is used a lot.

[UPDATE: For my own future reference, I'm adding this link to a site that translates Chinese characters to Jyutping, which is a Romanization system for Cantonese. I don't know how to read Jyutping -- indeed, I had to use the Sin-Ji voice to find out how to pronounce "Jyutping" -- but it's been handy for confirming that certain words have the same tone as words I know. I know this because the Jyutping for two words may be spelled differently but will have the same tone number at the end.]

Atheistic Community

As occasionally will happen, today's post is not related to technology (well, unless you want to apply it to the Mac/PC wars).

John C. Welch writes about what atheists can learn about community from religious people:

Set aside the (always enjoyable) ridiculing of religion, and ask yourselves: "Do we provide an alternative that is at least as good?"

Regarding the always-enjoyable-ridiculing — I think there are plenty of areas of religion, and plenty of people who profess to be religious, that are highly deserving of scorn and contempt, and I heartily enjoy any smackdown of such areas and people.

At the same time, I agree with Welch that we shouldn't discount the good things people do because they happen to be motivated by religion. I think it would be pretty dickish to look down my nose at a church volunteer who hands me a blanket when a hurricane destroys my home. And I agree that the smugness Welch refers to is not only distasteful but counterproductive, for some definition of "productive".

  • If I want to convince individuals I know and care about, for their own good, to change their beliefs and thus their lifestyles, it behooves me to consider where they are coming from and where I am asking them to go.

  • If I want to work more broadly as an organizer or campaigner to tear down illusions and superstitions that are doing massive harm to society… well, actually I should still consider where people are coming from.

  • If I find religious people plain wrong, sometimes annoyingly so, but don't feel like trying to engage them or change them, that's my prerogative. (This is the category I'm in, at least for now.)

  • If my only interest is in "being right", as Welch puts it — with the implication that I get off on other people being wrong — well, that's my prerogative too. But I feel this is a narrow way of thinking.

I totally understand the urge for atheists to belittle religious people, because I have felt the same urge in other areas, and succumbed too often and with too much regret. I do enjoy my bitter sarcasm; the aftereffects, not so much.

For some reason I don't feel this urge about religion. The issue of my non-belief vs. other people's religious beliefs, however absurd I find them, is not a hot button for me and I'm perfectly happy to let others do the talking. I do think there's a place for hard-hitters like Dawkins and Hitchens, but also a place for what Welch is talking about.

Crazy me

Learned something this morning from Wikipedia:

A truncated version of the "Crazy Ones" text has been reused in Mac OS X Leopard on the high-resolution icon for TextEdit.

Sure enough, here's the icon:

TextEdit icon

I came across this in a roundabout way. In comments on my earlier post about YoruFukurou (the desktop Twitter client I use), someone asked if it provides a way to find and follow people. I tested by searching for the name "Mike Morton", which turned up mentions of Mike's blog posts about WWDC. On Day 1 he writes:

Everyone got a nice "WWDC 11" sweatshirt. I’m giving mine to my friend Andy, who’s crazy enough that he flew all the way from New York to San Francisco despite having no ticket for the conference. (Andy was not crazy enough to wake up and join us for hours in line, though.)

I'm the crazy Andy. I wanted to reply with something about "Here's to the crazy ones…" and wanted to get the quote right. Hence the Wikipedia discovery.

Thanks, Mike, for the great sweatshirt!

MS online store saves password in clear text

I just bought Office for Mac from microsoft.com. To do so, I created an account. A bit later I realized I'd forgotten my password, so I clicked the necessary links to have it sent to me.

I expected to get either a random temporary password or a one-shot URL I could use to reset my password. Either of these approaches is standard practice. Instead I got an email containing my original password, which means Microsoft is remembering it in clear text.

To see how much more they're remembering I started a new purchase. I saw they had saved my credit card info and billing address. I don't know if the purchase would have gone through if I'd chosen to continue. For all I know they would have prompted me for my password before completing the transaction. Still, that password was exposed to employees of Microsoft and to anyone who hacks into their systems.

I would hope Microsoft does not save full credit card numbers. That would be monumentally stupid. On the other hand it appears Sony might have been that stupid, so who knows what to assume about big companies who should know better.

I deleted the credit card from my Microsoft profile. There is a separate option to delete my address, which I also did. I got to my account settings by following this link: http://buy.officeformac.com/store/msmacus/DisplayHelpPage. Microsoft included this link three times — once misspelled — in the confirmation email for my purchase. If I didn't have that email handy, it's not obvious to me how I would have gotten to my account info by navigating Microsoft's web site. But I admit I didn't study the web site very hard.

. . .

UPDATE: I realized I should change my password. I'm keeping the email they sent me so I can show anybody who asks. No point keeping my real password around in clear text after complaining that's a bad idea.

Here is that email. It begins, "Thank you for contacting us on Microsoft Office for Mac US Store." What kind of sentence is that? Between this sentence, the misspelled URL in the confirmation email, and the officeformac.com domain name, I wondered for a moment if I'd carelessly made my purchase through a hacker site. But no, microsoft.com links to officeformac.com.

Clear text password

keyPathsForValuesAffectingValueForKey: — doing it wrong

I just noticed this in the docs for the keyPathsForValuesAffectingValueForKey: method:

Your override should typically invoke super and return a set that includes any members in the set that result from doing that (so as not to interfere with overrides of this method in superclasses).

I've been doing it wrong. I've been doing it like this:

+ (NSSet *)keyPathsForValuesAffectingValueForKey:(NSString *)key
{
    if ([key isEqualToString:@"fullName"])
    {
        return [NSSet setWithObjects:@"firstName",
                                     @"lastName",
                                     nil];
    }
    else
    {
        return [super keyPathsForValuesAffectingValueForKey:key];
    }
}

It didn't occur to me that a superclass might also want to specify key paths that affect the fullName key. A correct implementation would have been:

+ (NSSet *)keyPathsForValuesAffectingValueForKey:(NSString *)key
{
    NSSet *keyPaths = [super keyPathsForValuesAffectingValueForKey:key];
    NSArray *moreKeyPaths = nil;
 
    if ([key isEqualToString:@"fullName"])
    {
        moreKeyPaths = [NSArray arrayWithObjects:@"firstName",
                                                 @"lastName",
                                                 nil];
    }
 
    if (moreKeyPaths)
    {
        keyPaths = [keyPaths setByAddingObjectsFromArray:moreKeyPaths];
    }
 
    return keyPaths;
}

Serves me right for not reading the docs carefully. For pride's sake I was hoping this was a common mistake, but from a Google search it seems almost everybody else in the world does it right.

I must have been thinking of observeValueForKeyPath:ofObject:change:context:, where typically you check the given key path against various possible values and fall through to super if it doesn't match any of them.

In any case, I more often use the keyPathsForValuesAffecting<Key> approach anyway.

[UPDATE: Thanks to Christiaan Hofman for pointing out that my description of observeValueForKeyPath:ofObject:change:context: is also Doing It Wrong. So never mind that and pretend I wrote this instead.]