Friday, August 17, 2007

Bought a Mac

My wife and I have been considering buying a new computer for a couple of months now; yesterday we bought a new 24" iMac. The odd thing is, even though my wife was comfortable on a Mac and I was drawn to the BSD underpinnings, we had decided against getting a Mac largely on the grounds of the expense (and the inability to easily uninstall software). Instead, we had settled on a small form-factor Dell. That is, until we visited the Apple Store on University Ave. Sunday afternoon.

We were in the neighborhood to pick up some prints at Wolf Camera and I wanted to stick my head in the Apple Store to check out the new Aluminum iMacs. They are gorgeous. I've never seen a screen quite like it. But the kicker was when my wife asked whether the $1799 price on the card next to the computer was for the computer we were looking at.

It wasn't. We were gawking at the 20" iMac; the placard was for the 24" iMac next to us. Now that was an impressive machine. And what was more amazing was that the $1799 price tag was on-par, if not cheaper, than the equivalent Dell desktop we had been considering! That's right, we could get the gorgeous iMac for the same price as the bland Dell we were planning to buy.

I have read claims in the past the recent-model Macs were cheaper than equivalent PCs, but there it was staring me in the face. Just to prove I'm not making this up, I just re-spec'ed the Dell machine we were going to buy to compare it to the Apple machine we did buy. As of 2007/08/17:

ComponentDell Optiplex 745 Small Form FactorApple iMac 24"
CPUIntel Core 2 Duo Processor E6600 (2.40GHz, 4M, 1066MHz FSB)Intel Core 2 Duo Processor T7700 (2.40GHz, 4M, 800MHz FSB)
OSWindows Vista Ultimate, with media, 32 Edition, EnglishMac OS X v10.4.10 Tiger
Memory1.0GB DDR2 Non-ECC SDRAM, 667MHz, (1DIMM)1.0GB DDR2 Non-ECC PC2-5300 SDRAM, 667MHz, (1SO-DIMM)
Hard Disk250GB SATA 3.0Gb/s320GB SATA 7200-rpm
Removable Disc8X Slimline DVD+/-RWSlot-loading 8x SuperDrive (DVD±R DL/DVD±RW/CD-RW)
Video Card256MB ATI Radeon X1300PRO256MB (GDDR3) ATI Radeon HD 2600 PRO
SpeakersDell™ A225 SpeakersBuilt-in stereo speakers
WiFiLinksys WUSB54GC Wireless-G USB AdapterAirPort Extreme wireless networking (802.11n)
Price w/o Monitor$1,198N/A
DisplayUltraSharp 2407WFP-HC 24-inch Widescreen Flat Panel LCD
24-inch widescreen TFT active-matrix LCD

Anyway, we left the Apple Store to head over to Fry's to do some shopping. But while we were at Fry's, my wife looked over at me and "we should get the Mac". She didn't have to say that twice. In my 15 years or so in the computer industry, I have never before seen a machine that I really wanted to buy. So we bought of copy of Parallels Desktop at Fry's and headed back over to the Apple Store.

Unfortunately, we were too late. They close at 6:00pm on Sundays. We tried again Monday night but both the University Ave. and Stanford Shopping Center stores were sold out of the 24" iMacs. We went ahead and ordered on on-line, but we were going to have to wait two weeks for it to even be shipped. So yesterday morning we made it up to the University Ave. store at 10:15am (they open at 10:00am) and bought the last 24" model in that day's shipment. That's right: sold out in 15 minutes. Needless to say, we cancelled our on-line order.

I was up to 4:00am last night setting up Parallels to run Win2k for some of our old software (namely, Microsoft Money and our favorite game: Settlers 3), installing Firefox and Thunderbird, importing our photos into iPhoto, etc. That screen is simply awesome. I don't think I've had this much fun since I was a kid. Certainly not with a computer.

Thursday, August 16, 2007

License for code posted on my blog

It occurred to me that while many people post code on their blogs, they seldom grant anyone else license to use their code. Google encourages their BlogSpot users to mark their posts with the Creative Commons License, but does not enforce users to do so nor do many blogs I've seen follow this recommendation. Now, the poster may know they have no intent to sue anyone over the use of their snippet, but how can the reader be sure?

To address the problem, I'm hereby declaring that all code posted on my blog ( is covered by the license below unless otherwise indicated in the body of the post itself:
Copyright (c) 2007, Kelly Yancey

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.


I hope that others will follow suite and clarify the license terms of use for content posted on their blogs too. Use a different license if you like (it is your code after all), but don't be fooled into thinking that simply posting code on your blog makes it open source.

And before someone writes that I should just declare the code to be public domain, I should point out that you can't do that (at least it probably won't become public domain until I'm so long dead that the idea of using the code I posted at the turn of the century seems quaint).

Wednesday, August 15, 2007

Python: Reconstructing timedeltas from strings

For some reason, the date/time objects implemented by the datetime module have no methods to construct them from their own string representations (as returned by calling str() or unicode() on the objects). It so happens that reconstructing a timedelta from its string representation can be implemented using a relatively simple regular expression:
import re
from datetime import timedelta

def parseTimeDelta(s):
"""Create timedelta object representing time delta
expressed in a string

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

Acceptable formats are: "X days, HH:MM:SS" or "HH:MM:SS".
if s is None:
return None
d = re.match(
r'((?P<days>\d+) days, )?(?P<hours>\d+):'
return timedelta(**dict(( (key, int(value))
for key, value in d.items() )))

But the other types are not quite so easy. Next time, I'll post my implementation for reconstructing datetime objects from their string representation.

Tuesday, August 7, 2007

NTTMCL hiring again

I guess it comes as no surprise since it seems like everyone is hiring these days, but NTTMCL is hiring again. Of particular interest (to me at least, since it is replacing my position) is the Unix Kernel Developer. I know, you wouldn't know it from my blog posts, but originally I was hired as a FreeBSD kernel developer. Since I am being transferred to Tokyo in a couple of months, and they don't really have the infrastructure in the office over there for kernel development, NTTMCL is hiring a kernel developer to replace me here in the Bay Area.

I don't know who wrote the job description, but there appear to be some typographical errors in it. For example, "enhanced 3 switch" should probably read "enhanced layer 3 switch" and "stabilize the developed wireless network system" should probably be "stabilize the existing wireless network system". Did I mention that NTTMCL is a subsidiary of a Japanese company? We have lots of non-native speakers.

Anyway, besides the kernel developer position, we also have a position open in our security research group, and two positions in our IP technologies group (formerly the IPv6 group) [1, 2]. If you are really into researching and playing with the latest hardware, we have a position in our Business Development group that will get to check out all of the latest gear that NTT Communications might be interested in.

We're a relatively small research and development subsidiary of NTT; currently we have about 35 people, the majority of which are software engineers of some sort. We have offices in both San Mateo, CA and San Jose, CA. The work environment is kind of a mix of big-company and startup: we're small and work with many cutting-edge technologies, but our income is stable being that we are a wholly-owned subsidiary of one of the largest ISPs in the world. There are no stock options, but there are also no 18-hour work days.

Anyway, I really like it here. In my 5 and half years here, I've worked on everything from FreeBSD kernel programming low-level networking, and implementing high-performance Un*x daemons (all in C, of course), to perl and embedded perl interpreters, to web application development (both with and without AJAX), to developing GUI-based applications on Windows using python. If you really like learning and applying new technologies, this is a great place to do so without having to worry about where your next paycheck is coming from.

If that sounds good to you too, send a copy of your resume to
Update 2007/08/16 07:07pm:
I got most of the errors in the job description for the kernel programmer corrected with H.R.; I haven't checked the others, though. Speaking of which, we're up to seven open positions now. Bring some friends! :)

Monday, August 6, 2007

One-liner to crash IE6

A Japanese fellow going by the name Hamachiya2 has stumbled upon one line of HTML/CSS code that crashes IE6. The magic line is:


You can try it yourself at:

Of course, if you are running IE6 or anything that embeds IE6 as a component, you can expect it to crash. All other browsers appear to render the code just fine.

I think I may have just found a new signature. :)

Update 2007/08/07 01:16pm:
Zeth wrote in that he noticed that IE7 pukes on the same line of HTML; it just waits until you try to visit a different page before it crashes.

Thursday, August 2, 2007

Python: Typed attributes using descriptors

A few weeks a saw a post by David Stanek on Planet Python regarding using python descriptors to implement typed attributes. At the time, I needed something very similar and I've been trying to find something descriptors were good for (besides re-implementing the property builtin) so I decided to give his trick a try. The only problem was, I was coding on CalTrain at the time so I couldn't access his blog to reference the code in his post. The worst part was that I struggled with problems that, as it turns out, were pointed out in the comments to his posting (specifically, attributes implemented via descriptors would erroneously share state between instances of the classes the attributes were assigned to). By the time I got to the office and could consult David's blog post, this is the implementation I had working:
from collections import defaultdict

class TypedAttr(object):
"""Descriptor implementing typed attributes, converting
assigned values to the given type if necessary

Constructed with three parameters: the type of the attribute,
an initial value for the attribute, and an (optional)
function for converting values of other types to the desired

If the converter function is not specified, then the type
factory is called to perform the conversion.
__slots__ = ('__type', '__converter', '__value')
def __init__(self, type, initvalue=None, converter=None):
if converter is None:
converter = type
self.__type = type
self.__converter = converter
initvalue = self.convert(initvalue)
self.__value = defaultdict(lambda: initvalue)

def convert(self, value):
if not isinstance(value, self.__type) \
and value is not None:
value = self.__converter(value)
assert isinstance(value, self.__type) \
or value is None
return value

def __get__(self, instance, owner):
if instance is None:
return self
return self.__value[instance]

def __set__(self, instance, value):
self.__value[instance] = self.convert(value)

With this, I could write my classes like so:
class Example(object):
Name = TypedAttr(str)
Type = TypedAttr(str, "cheezy example")

Mainly I'm using the typed attributes for data validation in objects populated from values supplied by an untrusted source. It would be really nice if I could compose descriptors to build more complex managed attributes (sort of like you can with validators in Ian Bicking's FormEncode package). Then I could make a descriptor, for example, Unsigned or NotNone and compose them with TypedAttr like so:
class CompositionExample(object):
Name = TypedAttr(NotNone(str))
Age = Unsigned(TypedAttr(int))

I'll admit I haven't put a whole lot of thought into it yet, but at first glance it appears that it would be impossible to compose descriptors in python. I would love to be proven wrong.