Tuesday, October 9, 2007

Python: A better wx.ListCtrl

I'm not going to repeat the entire post here, but I would like to direct your attention to my friend and former coworker Zach's recent blog post regarding implementing a better ListCtrl via wxWidgets' virtual ListCtrl.

For those familiar with wxPython, what Zach has done is combine wx.ListCtrl and wx.lib.mixins.listctrl.ColumnSorterMixin into a single easy-to-use class. Except, rather than implement it as an entirely new class, he implements a function that transmutes a generic ListCtrl into his new & improved ListCtrl. That advantage here, as he points out, is that you don't need to modify any XRC files to gain the new functionality.

The post is on NTT MCL's recently-introduced company blog which, unfortunately, doesn't appear to accept comments (and says "Japan Window" for some strange reason). As such, I'll point out that Zach also occasionally posts to his own personal blog, which is also worth checking out.

Sold my car

We sold my car today. It was a 1996 Ford Escort.

I realize this isn't particularly interesting to anyone else, but since it was the first car I ever bought on my own -- heck, I even moved it with me from Virginia -- it is kind of significant to me.

Anyway, I bought it for $9800 back in 1995 and it is still running well at 154,000 miles. I sold it today for $700 (thanks to craigslist!). That means, excepting gas and maintenance costs, the depreciation was $9100 over 12 years or approximately $760/year. Given that the car got 32 miles to the gallon new and has lately been averaging around 29, it even got good gas mileage (by today's low standards, anyways).

In fact, if I assume an average of 30 MPG over the life of the car, and an average of $2.00/gallon, that comes to about $10,300 in fuel costs. You may think $2.00 a gallon seems low, but a good number of those miles were driven in Virginia, where the price of gas fluctuated between $0.85 and $1.35 before we moved to California. The price of gas has certainly been higher here in California, but I've been riding CalTrain and/or walking to work since long before the recent surge in gas prices, so I think $2.00 a gallon may be pretty close to our average per-gallon price.

Ignoring maintenance costs, which weren't extraordinary, that is $19,500 to own and fuel my Ford Escort for just over 12 years. I'd say it was all around a good purchase. I certainly won't badmouth Ford cars anymore. A hybrid will cost you more than that just to own, not to mention fuel costs.

It certainly didn't turn any heads, but then again, I never once worried about anyone stealing it, dinging it, or hitting it. In fact, I would say that having a dumpy car has its own value -- in peace of mind.

Tuesday, October 2, 2007

The price of spam

Like anyone, I get lots of spam. Having kept the same e-mail address since 1995 and having that e-mail address posted all over the web may contribute to absolutely inordinate amount of spam I receive. I get over 1000 pieces of spam mail a day.

To make matters worse, I run my own mail server on a Soekris 4801 at home. I use postfix running on FreeBSD 6.2 with SpamAssassin to identify spam. My spam situation is desperate, so anything that looks remotely like spam gets immediately sent to the bit bucket. Still, over 50 spam mail a day make it to my Inbox.

My Soekris box is my mail server, file server, firewall, and PPPoE tunnel end-point (for my DSL connection). I also run a low-traffic web site off the box. That said, between pppd, the postfix and spamd processes, receiving and processing spam consumes almost 100% of the CPU all day, every day. My load average rarely dips below 1.0 and, at the heaviest times, the inbound mail queue grows to a few hundred messages.

Now, this isn't the fastest machine in the world. But when I started my first ISP back in 1995, we ran dozens of web sites (admittedly, mostly static content) off a single 100Mhz Pentium server with 128MB of RAM. Our entire 27000+ newgroup Usenet feed was hosted on another 100MHz Pentium server, also with 128MB of RAM. But in 2007, I'm here to tell you that it takes a 266Mhz Pentium-class machine (with the same 128MB of RAM) running 24/7 just to deliver mail for two e-mail accounts.

So I can tell you personally that the price of spam in 2007 is roughly one Soekris 4801 plus disk space. It may not seem like much in comparison to today's top-of-the-line computers, but it is enough to make me sick just thinking about.

Friday, September 21, 2007

Moving to Tokyo

If anyone reads my blog, they would have noticed that I haven't posted any good programming tidbits here in a while. The reason is that I've been busy making arrangements for my move to Japan.

Next month (October 16th to be exact), my wife and I are moving to Tokyo where I will start my new job at NTT Communications' headquarters in Hibiya. My last day here at NTT MCL will be October 5th.

I've worked at NTT MCL for over 5 and half years, making it the longest I have ever worked at a single company. I've really enjoyed working at NTT MCL, so I'm a bit sad to leave. Luckily, my job at NTT Communications will entail further development and maintenance of the servers we developed at NTT MCL for the HOTSPOT wireless network, so it looks like I'll keep in regular contact with my current co-workers. By the way, if you find yourself in Tokyo, or just about any major city in Japan, you should purchase a 1-day pass for HOTSPOT. You get wireless Internet access at a huge number of locations for just 500 yen (about 4 dollars). Having worked on HOTSPOT for over 5 years, I was shocked when I discovered T-Mobile charges $10/day for a similar service in the U.S.

Also, I can't stress enough how nice of a place NTT MCL is to work at. There are lots of positions open, the work environment is relaxed and relatively low-stress, and you'll get to work on a variety of different projects. I know I am going to miss working here, but I simply cannot pass up this opportunity to work abroad for a few years. Hopefully, they'll take me back when I return to the U.S.

Monday, September 17, 2007

Sony getting out of Cell production

According to Asahi Shinbun, Sony will be selling their semiconductor production facilities, including those for the production of their Cell processor, to Toshiba for approximately 100 billion yen (~870 million dollars). The sale is expected to happen next spring. There is speculation that Sony does not foresee new applications for their Cell processor and is seeking to reclaim a large amount of their investment capital.

Sony's semiconductor subsidiary, Sony Semiconductor, is selling the LSI (Large Scale Integration) facilities in their Nagasaki Technology Center on the island of Kyushu. Besides being the production facilities for the Cell processor, the plant also makes image processing chips for game devices.

Sony will continue to develop the Cell processor, but they are reconsidering producing the chips themselves. Instead, the will be putting their effort into next generation audio/video devices. In particularly, they intend to put emphasis on the production of CMOS sensors like those used to record images in digital cameras.

Monday, September 3, 2007

Keepon

I saw this last night on a Japanese TV show. Apparently, a U.S. and Japanese researcher have been working on a little robot called "keepon", experimenting with human interaction. Here is a short movie demonstrating some basic emotive interaction:


The American researcher filmed a demo video of the little robot responding to a song by a L.A. band called "Spoon" and uploaded it to YouTube:


Apparently, the video was so popular that the band caught notice and contacted the researchers about using the robot in one of their official music videos. The Japanese researcher appears in the video with the robot (the video was filmed in Tokyo):


Like probably just about everyone else who has seen the video, I checked to see if I could buy one. You can't.

Update 2007/09/04 1:30am (JST):
As with everything else you can think of, Wikipedia already has an entry about Keepon. Sometimes I wonder why I bother writing anything. You could replace my entire blog with nothing but links to Wikipedia articles. :)

Sunday, September 2, 2007

Python: Reconstructing datetimes from strings

Previously, I posted a small snippet for converting the str() representation of a python timedelta object back to its equivalent object. This time I'm going to address doing the same for datetime objects:

def parseDateTime(s):
"""Create datetime object representing date/time
expressed in a string

Takes a string in the format produced by calling str()
on a python datetime object and returns a datetime
instance that would produce that string.

Acceptable formats are: "YYYY-MM-DD HH:MM:SS.ssssss+HH:MM",
"YYYY-MM-DD HH:MM:SS.ssssss",
"YYYY-MM-DD HH:MM:SS+HH:MM",
"YYYY-MM-DD HH:MM:SS"
Where ssssss represents fractional seconds. The timezone
is optional and may be either positive or negative
hours/minutes east of UTC.
"""
if s is None:
return None
# Split string in the form 2007-06-18 19:39:25.3300-07:00
# into its constituent date/time, microseconds, and
# timezone fields where microseconds and timezone are
# optional.
m = re.match(r'(.*?)(?:\.(\d+))?(([-+]\d{1,2}):(\d{2}))?$',
str(s))
datestr, fractional, tzname, tzhour, tzmin = m.groups()

# Create tzinfo object representing the timezone
# expressed in the input string. The names we give
# for the timezones are lame: they are just the offset
# from UTC (as it appeared in the input string). We
# handle UTC specially since it is a very common case
# and we know its name.
if tzname is None:
tz = None
else:
tzhour, tzmin = int(tzhour), int(tzmin)
if tzhour == tzmin == 0:
tzname = 'UTC'
tz = FixedOffset(timedelta(hours=tzhour,
minutes=tzmin), tzname)

# Convert the date/time field into a python datetime
# object.
x = datetime.strptime(datestr, "%Y-%m-%d %H:%M:%S")

# Convert the fractional second portion into a count
# of microseconds.
if fractional is None:
fractional = '0'
fracpower = 6 - len(fractional)
fractional = float(fractional) * (10 ** fracpower)

# Return updated datetime object with microseconds and
# timezone information.
return x.replace(microsecond=int(fractional), tzinfo=tz)

Last time Lawrence Oluyede was kind enough to point out that the dateutil module can likely do this and a lot more. However, I'm trying to stick to modules in the base library. Of course, it wouldn't be a bad thing if dateutil were to make it into the base library....

Speaking of which, the snipped above relies on the FixedOffset tzinfo object described in the documentation for the datetime.tzinfo module. Being that the documentation is part of the standard python distribution, I guess you could call that code part of the base library, even if you can't import it. :|

Update 2007/09/03 1:39pm (JST):
Fix example format examples in doc-string per comment from David Goodger.