Tuesday, December 11, 2007

Lies, Damn Lies, and ... Economics?

Today I'm going to venture out of any field that I have the slightest expertise in and flounder about in the field of basic macro-economics.

But before I demonstrate my utter lack of knowledge, I'm going to touch on a subject that I at least have some familiarity with -- mathematics. I'm going to share with you a math problem that I cannot solve. It looks something like this:

Given:

A A'
--- = 111 = ----
B B'

and

B = B' * 1.41

What is the ratio between A and A'?
Elementary algebra would seem to imply the answer should be 1.41:

A A'
--- = ----
B B'

A * B' = A' * B

A * B' = A' * B' * 1.41 ==> A = A' * 1.41

By itself, I would have expected this problem would be trivial.
However, what perplexes me is that the observed value for the ratio between A and A' is nowhere near 1.41, but rather approximately 1.0.

And here is where I demonstrate my lack of understanding in the field of economics...

The thing that has been puzzling me for years (even before the recent foreign exchange craze) is that the U.S. dollar has experienced fairly consistent inflation for these 13 years while the Japanese Yen has experienced almost none, yet the exchange rate remains the same.

You see, A' / B' is the average value of the Japanese Yen in U.S. dollars for November 2007. And A / B is the average value of the Japanese Yen in U.S. dollars for April 1994. Both ratios just happen to be approximately 111. (Source: Board of Governors of the Federal Reserve System)

The ratio B' / B is the purchasing power of the U.S. dollar in 2007 relative to dollars in 1994. That is, one 1994 dollar (B) is worth 1.41 2007 dollars (B'). (Source: Bureau of Labor Statistics)

The ratio A' / A is the purchasing power of the Japanese Yen in 2007 relative to yen in 1994. It so happens that one Japanese yen buys the same amount in 2007 that it did in 1994. (Source: Japanese Ministry of Internal Affairs and Communications)

How can this be?
How can two currencies can have different inflation rates, but yet maintain the same conversion rate?

I'm no economist, but I cannot help but wonder if the answer lies outside of math and in the realm of human irrationality. Or that the CPI values uses to calculate the purchasing power of a currency are inconsistent and/or flawed. Actually, I know that CPI calculation methods differ amongst countries, but for some reason I expected Japan to have used to the calculation method that U.S. does. I admit I haven't investigated that explanation yet.

Does anyone have a better explanation (preferably one that does not violate basic math principles)? I would love to put this puzzle to rest.

Monday, December 3, 2007

Python: asserting code runs in specific thread

My buddy JJ's post to the BayPiggies mailing list reminded me of a little snippet I wrote a while back that others might find useful as well. Personally, I avoid threads like the plague, but if you are forced to use them it is generally handy to keep accurate tabs on how you use them. In particular, as JJ suggested in his post, it is a good idea to assert that code is called in the thread context you expect it to be called in. This can go a long way toward avoiding one of many classes of hard-to-find logic bugs multi-threading invites. Anyway, on to the code...
def assertThread(*threads):
"""Decorator that asserts the wrapped function is only
run in a given thread
"""
# If no thread list was supplied, assume the wrapped
# function should be run in the current thread.
if not threads:
threads = (threading.currentThread(), )

def decorator(func):
def wrapper(*args, **kw):
currentThread = threading.currentThread()
name = currentThread.getName()
assert currentThread in threads or name in threads, \
"%s erroniously called in %s thread " \
context" % (func.__name__, name)
return func(*args, **kw)

if __debug__:
return wrapper
else:
return func
return decorator

You can restrict execution to one or more threads, each specified by either the thread object or thread name.

Note the trick at the end to make the decorator effectively a no-op in production. Using this decorator around your functions and methods helps you spot logic errors during development without impacting the performance of your production code. Of course, if you are of the school that assertions should never be disabled, feel free to replace the final if __debug__:/else block with an unconditional return of wrapper.

Thursday, November 22, 2007

My first OpenSearch plugin

Well, yesterday I crawed out of my cave and discovered OpenSearch, the XML-based description format for search engines. Both Firefox 2 and IE 7 can import search engine settings from OpenSearch description files and add the search engine to their respective search bars. In fact, there are already description files for just about every search engine you can think of.

There is a great guide to writing your own OpenSearch description and how to link to the description file such that Firefox or IE automatically discover it. The specification is relatively straightforward so, excited, I decided to whip up an OpenSearch plugin for Kelly & Cristin's Wine Reviews.

I only encountered two obstacles:
  1. Getting an icon for my search plugin. I didn't already have a shortcut icon for my site that I could simply re-use, so I had to first make an icon.
  2. I typed the XML document by hand; I left out the final slash in the OpenSearch XML namespace declaration. Firefox will not recognize the file as an OpenSearch document unless the namespace is exactly right. This should have been quick to diagnose except that Firefox gives you no error message to aid in debugging - it simply refuses to load the file.

The text of my OpenSearch description is here. But if you visit the web site using Firefox 2.0 or later, you'll notice that icon next to your search bar gets a blue highlight; if you click on the icon, you'll see an option to add my Wine Review search to your search bar.

Anyway, without the half hour it took to figure out why Firefox wouldn't recognize my OpenSearch plugin, it would have only taken a few minutes to add a search plugin and plugin auto-detection code (one link tag in the HTML head) to my web site. I don't seriously expect anyone to want to be able to search my silly wine review site from their browser search bar, but certainly was neat to be able to add it.

Tuesday, November 20, 2007

Back on-line

This is just a quick note to mention that I finally got my Internet access hooked up this past weekend. After picking up a 100V power supply in Akihabara, my little Soekris 4801 is back up and serving the posi.net domain again.

I'm still getting settled into my new routine at work, but I hope to have time to start regularly writing posts again soon...

Wednesday, November 7, 2007

Unix storage solution

I've been lax in updating my blog lately, mainly due to lack of Internet access at my apartment since we've moved to Tokyo. It is nice and all that I have a variety of high-speed Internet service providers to choose from, but it would be really great if any of them could actually hook up my service is less than a month. :(

Anyway, until I get my own Internet service, I've been "borrowing" access via an open AP with a signal just strong enough that I can associate if I stand right next to my window. Sitting is no good; I have to have the laptop pretty high in the air to get a signal. As you can imagine, I've been reluctant to get on the Internet any more than I have to.

That said, I couldn't pass up the opportunity to share a surprising Unix storage solution I discovered today. Actually, my wife picked it up unintentionally while shopping at the Don Quixote across the street...


I kid you not, these are cheap little plastic refrigerator storage boxes. I couldn't believe my eyes when she showed them to me. Now if I could only find ones that said "FreeBSD" and "Linux" I'd be set on souvenirs the next time I go back to the U.S.

Monday, October 15, 2007

posi.net going offline

My personal domain, posi.net, will be going offline for the next few days while I move. This means that any mail sent to the domain will bounce (I'm not setting up a backup MX on purpose, since 99.99% of my mail is spam). It also means the Cristin and Kelly's absolutely fabulous wine reviews, my 地球ラジオ archive, and other miscellaneous amusements will be temporarily offline too.

Friday, October 12, 2007

My last BayPiggies

Well, last night was my last BayPiggies meeting for a few years. The speakers were Mikeal Rogers & Adam Christian from the Open Source Applications Foundation, presenting their new automated web U.I. testing framework, Windmill.

It was a pretty neat demo; if I actually did any serious web development, I would consider using it (or the preexisting Selenium tool) for testing. Being that it was a python user's group rather than a product show-and-tell, I would have liked more details about how Windmill worked, especially from the python side, but I am assured it is "really really really really cool". ;) I guess I'll have to find time to read the code myself.

Anyway, afterwards I got to hang out with my buddies JJ and Zach for a while and chat over a burger. I'm afraid mine was not particularly stimulating conversation, but I'm really looking forward to finding out what exactly it is JJ has been coding up over at MultiCosmic. He assures me it will go live in a few days, and that I'll have to wait to learn what it is when everyone else does. :) I just know it involves FaceBook.

I've only been going to BayPiggies for the past couple of months, but I'm going to miss the monthly chance to learn about some new tool or technology utilizing python. More importantly, I'm going to miss the opportunity to hang out and hear the state-of-web-development address from JJ (he admitted he loves Rails, by the way :) ). Hopefully, I'll still see Zach from time to time in Tokyo.

Speaking of which, I have yet to find a web page for a Python user's group in Tokyo; pyJug doesn't appear to actually hold casual group meetings just weekend retreats and workshop-style meetings. That sounds like fun, but not quite the casual get-together I've gotten used to with BAFUG and BayPiggies meetings.