Efectos Especiales

Ramblings, rants, musings, ideas and observations. Topics include (but are not limited to): programming (especially Python), books, games (especially CCGs and board games), astrology, design, writing, painting, etc.

icon:nl3 #619 (old comments) Dutch and English

The English language is not easily pronounced by foreigners, and pronunciation rules (if any) can be quite arcane, as exemplified by the infamous Dearest creature in creation poem. Rather than picking on English, however, I would like to talk about specific problems that Dutch speakers encounter when trying to pronounce English.

In Dutch, a d at the end of a word sounds /t/. Similarly, b becomes /p/, z becomes /s/ and v becomes /f/. (The last two are quite rare; they sometimes occur in borrowed words like quiz and fez.) Many Dutch don't realize that other languages don't have this property. So, they happily pronounce English bed as /bet/, and Bob as /Bop/, not realizing that these letters are not transformed to /t/ and /p/.

But wait, it gets better. In English, pan and pen are pronounced differently, but Dutch doesn't really have the exact sounds of their vowels. It does have a sound that sits somewhere in between, like in Dutch pen, so they use this pronunciation for both words, even though it's not really correct. This means that when a Dutch person says something that sounds like /bet/, he could mean bet, bed, bat or bad. Similarly, something that sounds like /kit/ could mean both kid and kit. Also non-obvious to Dutch are differences like sun and son, which can lead to confusing mispronunciations (e.g. Eng. slot).

Most European languages don't have the /th/ sound. Dutch is no exception, but English does have it, causing all kinds of problems for non-native speakers, who try to find substitutes in /s/, /z/, /d/, /t/ and /f/ (zis or zat, brodders, sunder, dey). To make matters worse, English th comes in two flavors (the th in this is different from the one in thunder).

On top of that, English speakers apparently think that the w as pronounced in German, and possibly Dutch, sounds like a /v/. Hence fake accents like "Ze vairvoolf is dead." I never thought of it that way; I think they're basically similar sounds in both languages, but English w is stronger than the Dutch one, while English v is weaker. Dutch v tends to become f, especially if you're from the north or west of the Netherlands.

English r, of course, is quite different from most (all?) other European languages. Dutch speakers generally don't have much trouble with it, though.

/* Posted by Hans Nowak at 2004-08-20 17:55 */

icon:cats2 #618 (old comments) What will they think of next?

"Hot Or Not" for cats.

Update: Also see Rate My Kitten.

/* Posted by Hans Nowak at 2004-08-18 22:24 */

icon:default #617 (old comments) Google sponsored links

Google usually does a decent job of pairing a search with appropriate ads, but sometimes it doesn't make sense. ^_^

/* Posted by Hans "they have them in bulk, or what?" Nowak at 2004-08-18 02:09 */

icon:wax #616 (old comments) De mutatis sizerium

wxPython 2.5.2.7 introduces quite a nasty sizer change, that messed up several of my programs. Fortunately, the Recent Changes page describes what happens clearly, so I could fix it quickly:

"wx.ADJUST_MINSIZE is now the default behaviour for window items in sizers. This means that the item's GetMinSize and/or GetBestSize will be called when calculating layout and the return value from that will be used for the minimum size used by the sizer. The wx.FIXED_MINSIZE flag was added that will cause the sizer to use the old behaviour in that it will not call the window's methods to determine the new best size, instead the minsize that the window had when added to the sizer (or the size the window was created with) will always be used. Please see the Sizers section in the Migration Guide for more details."

Wax will *not* have this new behavior, at least not by default. Maybe I'll add a parameter adjust or something, that allows it. But it simply won't be the default, not only because it breaks too much (of my :-) code, but also because the old situation allows code like:

b = Button(parent, ...)
b.SetSizeX(40) # make it a rather small button
parent.AddComponent(b)

# ...later...
parent.Pack()

In the new situation, setting the size like this has no effect, nor does setting it after AddComponent(); the button retains it default size. Setting it after Pack() gives the right size, but messes up the intended layout, which is based on the button's default size, not on the new size.

I probably only have a marginal understanding of what's going on emoticon:smile, but I definitely want to keep the old behavior. It makes more sense to me.

Aside from this, not too much breaks. Well, some methods on wx.DC, but that really isn't something that Wax can help or should fix. emoticon:nosmile

Anyway, I will release the new Wax after some more testing.

/* Posted by Hans Nowak at 2004-08-17 23:53 */

icon:science #615 (old comments) The Museum of Unnatural Mystery

An online museum that explores the fringe edges of science.

/* Posted by Hans Nowak at 2004-08-16 23:28 */

icon:wax #614 (old comments) Public service announcement

In spite of wxPython 2.5.x being "unstable", I will continue to build Wax on top of the latest version.

I have to make a choice. Wax will either not work (well) with the stable release 2.4.2.4, or it won't work with the latest version. I expect that most people will download and use the latest wxPython version. 2.4.2.4 is not that new (almost a year old), and significant new features have been added since. I choose to work with the latest version, and feel that this is the lesser of the two evils.

Inevitably, this means that parts of Wax will be "unstable" as well. After all, many Wax classes are transparently based on wxPython classes, and any API changes to those classes will mean API changes for Wax as well. I can't do anything about that right now. I could try to route around the incompatible changes, but that would only mess up an otherwise clean design.

I don't expect the changes will be all that great, except for code depending on wx.DC.

/* Posted by Hans Nowak at 2004-08-15 23:57 */

icon:astronomy2 #613 (old comments) Astronomy picture of the day: Hoag's Object

"Is this one galaxy or two? This question came to light in 1950 when astronomer Art Hoag chanced upon this unusual extragalactic object. On the outside is a ring dominated by bright blue stars, while near the center lies a ball of much redder stars that are likely much older."
[more...]

Hoag's Object

/* Posted by Hans Nowak at 2004-08-15 15:40 */

icon:food #612 (old comments) Chocolatl

Lots of chocolate recipes can be found here. A bit old-fashioned, but still quite usable. emoticon:kwijl

/* Posted by Hans Nowak at 2004-08-14 20:59 */

icon:default #611 (old comments) wxPython 2.5.2.7

Ah, wxPython 2.5.2.7 is available. If you're a Wax user, please bear in mind that Wax 0.2.x only works with wxPython 2.5.1.5. I plan to release a version that works with the new wxPython soon.

The wxPython download page says: "NOTE: The links below are for the binaries and source for wxPython 2.5.2.7. The 2.5.x versions are considered unstable development snapshots, meaning that the API is allowed to change from version to version, not that it is any more buggy than satable versions, (although it sometimes is.) Prior versions are at SourceForge. The latest version from the stable (mostly frozen API) branch is 2.4.2.4."

Hmm, maybe I should just fall back on the stable 2.4.2.4 until there is a newer stable release. Well, let's see what 2.5.2.7 has in store. I sure hope that RegisterHotKey works... :-)

/* Posted by Hans Nowak at 2004-08-14 12:55 */

icon:python #610 (old comments) Decorate this

So I decided to take Python 2.4a2 for a spin. The most interesting new features are generator expressions and those blasted decorators. emoticon:smile

*The* thing to keep in mind when working with decorators is, that

@decorator
def f(...):
    ...

is syntactic sugar for:

def f(...):
    ...
f = decorator(f)

What a decorator *is* exactly is not so easy to define. You could say that it's a function that takes another function, does something with it, and returns it. Except that you can replace "function" with "any callable" (functions, methods, classes, instances), and it may return any callable as well.

The new @ operator (assuming it stays, not sure) does not accept any old expression. Currently it accepts callables, and calls returning callables. If that sounds too vague: @decorator is allowed, and decorator can be a function, a method, a class, or an instance. Calls are also allowed: @foo(this, that) is valid, as long as the call foo(this, that) returns a decorator. This is how the following code works (taken from the PEP; it took me a minute or two to wrap my mind around it):

def attrs(**kwds):
    def decorate(f):
        for k in kwds:
            setattr(f, k, kwds[k])
        return f
    return decorate

@attrs(versionadded="2.2",
       author="Guido van Rossum")
def mymethod(f):
    ...

This is sugar for

def mymethod(...):
    ...
mymethod = attrs(versionadded="2.2", 
           author="Guido van Rossum")(mymethod)

Yeah, try explaining that to a newbie. emoticon:nosmile

In this context, it's not so hard to end up with a function that returns a function that returns a functions:

>>> def wrapwith(obj):
...     def decorator(f):
...         def _wrapper(*args, **kwargs):
...             print "##", obj
...             return f(*args, **kwargs)
...         return _wrapper
...     return decorator
...
>>> @wrapwith(42)
... def f(x): return x*2
...
# print something when calling this function.
>>> f(4)
## 42
8

John Roth suggested that decorators could be used for easy adding of methods to an instance. This is useful for prototype-based OO, like the Selfish mini-framework. Sure enough, it can be done:

>>> class Foo:
...     def __init__(self):
...         self.x = 42
...
>>> foo = Foo()
>>>
>>> def addto(instance):
...     def decorator(f):
...         import new
...         f = new.instancemethod(f, instance, instance.__class__)
...         setattr(instance, f.func_name, f)
...         return f
...     return decorator
...
>>> @addto(foo)
... def print_x(self):
...     print self.x
...
>>> foo.print_x()
42

I suppose it's a bit nicer than

def print_x(self):
    print self.x
foo.print_x = print_x
# note: "Selfish" has some magic built in to make this work

...but not much. It doesn't even save a line. I think the magic that is now in __setattr__, can be moved to the decorator, though, which is a small boon.

All in all, I have yet to see a really convincing use case for this new feature.

/* Posted by Hans "+0.1" Nowak at 2004-08-13 20:09 */