<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"><channel><atom:link rel="hub" href="http://tumblr.superfeedr.com/" xmlns:atom="http://www.w3.org/2005/Atom"/><description>www: brianbeck.com
email: brian.beck@gmail.com
twitter: @ua6oxa</description><title>Brian Beck’s Text Adventure</title><generator>Tumblr (3.0; @exogen)</generator><link>http://blog.brianbeck.com/</link><item><title>Days 1-4: Cleveland to Ann Arbor</title><description>&lt;p&gt;Friends and family met us at Lakewood Park on Sunday to send us off—two days later than we originally planned.&lt;/p&gt;

&lt;p&gt;&lt;img src="http://media.tumblr.com/tumblr_l7d7yu3Vw41qz7sas.jpg" alt=""/&gt;&lt;/p&gt;

&lt;p&gt;We finally hit the road a little after 3pm, but stopped at &lt;a href="http://centurycycles.com/about/rocky-river-pg286.htm"&gt;Century Cycles&lt;/a&gt; in Rocky River for some last minute supplies.&lt;/p&gt;

&lt;p&gt;&lt;img src="http://media.tumblr.com/tumblr_l7d80kE6j41qz7sas.jpg" alt=""/&gt;&lt;/p&gt;

&lt;p&gt;The ride to Oberlin was slow, but we made it. It took us quite a few miles to get used to the weight of the bikes—each carrying about 50 pounds.&lt;/p&gt;

&lt;p&gt;There weren’t many people on campus at the time, so we just picked up some Chinese food and started scouting out a good spot to set up for the night. We settled on a hidden clearing next to a chapel and unloaded our gear.&lt;/p&gt;

&lt;p&gt;That turned out to be a terrible idea. For one thing, the bells tolled every hour—even at 2am. And the benches around the corner turned out to be a popular late-night hangout for students looking to drink on the down-low. After the second rowdy group left, I gave in and looked up the closest motel. At 3am, we quickly packed it up and rode to the motel in the dark of the night. This turned out to be my favorite few miles of riding so far. The air was cool, there was absolutely nobody on the road, and we could only see as far as the reach of our headlights.&lt;/p&gt;

&lt;p&gt;After showers and breakfast at the motel on Monday, we left for Fremont, Ohio.&lt;/p&gt;

&lt;p&gt;&lt;img src="http://media.tumblr.com/tumblr_l7dka8i4KN1qz7sas.jpg" alt=""/&gt;&lt;/p&gt;

&lt;p&gt;Unfortunately, we didn’t discover the &lt;a href="http://www.metroparks.cc/reservation-north-coast-inland-trail.php"&gt;North Coast Inland Trail&lt;/a&gt; until we arrived in Fremont, so the ride could have been faster and easier than it was. While looking for a place to camp, we found the trail and met a new friend: John, a 26-year-old mechanical engineer contracting on a project in Fremont. After sending us off with suggested camping locations, he caught up to us and offered his place for the night. We gladly accepted and ended up having a great time.&lt;/p&gt;

&lt;p&gt;The next morning we hopped on the trail and enjoyed another day of perfect weather. We ran into &lt;a href="http://fremontcycleandfitness.com/storelocator/elmore-cycle-fitness-2.htm"&gt;Elmore Cycle &amp; Fitness&lt;/a&gt; along the trail and stopped in for some tune-ups on Erin’s bike. The head mechanic, Mike, was interested in the gear we chose to pack and eagerly offered some helpful advice (such as picking up 12oz of heat antifreeze at a gas station to replace the 32oz of denatured alcohol we’re carrying for cooking). Mike posts photos of passing tourers and his ultralight setups &lt;a href="http://www.flickr.com/photos/mmeiser2"&gt;on his Flickr stream&lt;/a&gt; (photos of us coming soon).&lt;/p&gt;

&lt;p&gt;We eventually reached and promptly exited Toledo, which had terrible roads for cycling and &lt;em&gt;the worst&lt;/em&gt; drivers. Everyone had some stupid comment for us—none of them demonstrating any knowledge of the actual rules of the road, of course. So we rode until we reached Temperance, Michigan, and found the perfect stealth camping spot behind some trees.&lt;/p&gt;

&lt;p&gt;&lt;img src="http://media.tumblr.com/tumblr_l7d7i48mbc1qz7sas.jpg" alt=""/&gt;&lt;/p&gt;

&lt;p&gt;This morning was the earliest we’ve started yet, waking up at 7:00 to make breakfast and pack up, and hitting the road by 9:00. After 15 miles, we took a short break in Dundee, which was home to every imaginable fast-food chain on just a half-mile stretch, but also a cute and clean downtown area.&lt;/p&gt;

&lt;p&gt;The remainder of the trip was spent riding directly north on some very sparsely populated roads, singing songs and taking pictures along the way to cure our boredom.&lt;/p&gt;

&lt;p&gt;&lt;img src="http://media.tumblr.com/tumblr_l7dkj1DSEk1qz7sas.jpg" alt=""/&gt;&lt;/p&gt;

&lt;p&gt;We rolled into Ann Arbor a little after 1pm and met up with our friends, Erin and Bryan (funny, right?) at their apartment. We’re about to leave for the bar to see their band &lt;a href="http://www.lakefolkband.com/home.html"&gt;Lake Folk&lt;/a&gt; perform. We’ll be taking advantage of these comfy couches tonight and leaving for Kalamazoo after lunch tomorrow!&lt;/p&gt;</description><link>http://blog.brianbeck.com/post/974724333</link><guid>http://blog.brianbeck.com/post/974724333</guid><pubDate>Wed, 18 Aug 2010 21:24:00 -0400</pubDate></item><item><title>Bike Adventure Gear, Part 1: Camping</title><description>&lt;p&gt;Over the next few days, I’ll be posting all the gear Erin and I are bringing on our bike trip to Seattle. I’m a determined comparison shopper and bargain hunter, so every last item here was meticulously researched, and we got great deals on almost everything. Maybe these posts will save you some time if you’re planning a similar adventure!&lt;/p&gt;

&lt;p&gt;Today’s post: our camping gear.&lt;/p&gt;

&lt;p&gt;We’ll be spending our nights in &lt;a href="http://www.rei.com/product/779039"&gt;The North Face’s Big Fat Frog 2-person tent&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;&lt;img src="http://media.tumblr.com/tumblr_l6ptd0b69J1qz7sas.jpg" alt=""/&gt;&lt;/p&gt;

&lt;p&gt;One of the highest rated tents on &lt;a href="http://www.rei.com"&gt;REI&lt;/a&gt;, I bought it there during their big sale earlier this summer, and saved some money by purchasing the footprint from &lt;a href="http://www.rockcreek.com"&gt;Rock/Creek&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Since our bodies will likely be aching after riding for hours every day, we each have our own &lt;a href="http://www.rei.com/product/778147"&gt;REI Trekker 1.75 self-inflating sleeping pad&lt;/a&gt;. To save on weight and space, we’re only bringing one sleeping bag, replacing the other with a &lt;a href="http://www.rei.com/product/735819"&gt;Cocooon ripstop silk liner&lt;/a&gt;. We can always share the sleeping bag if necessary, so I’m betting that this tradeoff is going to be worthwhile.&lt;/p&gt;

&lt;p&gt;We’ll be cooking our meals on the road with the &lt;a href="http://www.rei.com/product/657906"&gt;Mini Trianga 28-T backpacking stove&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;&lt;img src="http://media.tumblr.com/tumblr_l6pu3zJwOR1qz7sas.jpg" alt=""/&gt;&lt;/p&gt;

&lt;p&gt;This tiny stove burns denatured alcohol and comes with a pot and pan. While we’ll mostly be using this just to boil water, I’m looking forward to learning how to cook meals as quickly and efficiently as possible with this limited equipment. &lt;a href="http://www.campsaver.com"&gt;CampSaver.com&lt;/a&gt; had the best deal on this stove.&lt;/p&gt;

&lt;p&gt;And why bring along some normal household utensils when we can use the &lt;a href="http://www.rei.com/product/765204"&gt;Guyot Designs MicroBites&lt;/a&gt; and the &lt;a href="http://www.rei.com/product/660002"&gt;Snow Peak titanium spork&lt;/a&gt;? If there’s an everyday item that has a fancy backpacking equivalent, I had to have it. :)&lt;/p&gt;

&lt;p&gt;For campsite lighting we have the &lt;a href="http://www.rei.com/product/777554"&gt;Black Diamond Orbit lantern&lt;/a&gt; and the &lt;a href="http://www.rei.com/product/799383"&gt;Mammut TR1 headlamp&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;&lt;img src="http://media.tumblr.com/tumblr_l6puqkCOxX1qz7sas.jpg" alt=""/&gt;&lt;img src="http://media.tumblr.com/tumblr_l6puqwc0ta1qz7sas.jpg" alt=""/&gt;&lt;/p&gt;

&lt;p&gt;Both are super bright. Unfortunately, Steve’s dog chewed up the lantern, which does in fact resemble a dog toy. It still works fine - a testament to its durability, at least. &lt;a href="http://www.e-omc.com"&gt;Oregon Mountain Community&lt;/a&gt; had the best deal on the headlamp.&lt;/p&gt;

&lt;p&gt;Other miscellanous items…&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A couple &lt;a href="http://www.rei.com/product/783480"&gt;MSR PackTowl&lt;/a&gt; compact and lightweight towels.&lt;/li&gt;
&lt;li&gt;A &lt;a href="http://www.rei.com/product/737335"&gt;firesteel&lt;/a&gt;, so I can struggle to ignite things until Erin gets frustrated and uses her lighter.&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://www.rei.com/product/401139"&gt;This coffee pot&lt;/a&gt; - Erin’s vice, not mine. You’re responsible for carrying this one, Erin!&lt;/li&gt;
&lt;li&gt;Plates, bowls, stove fuel, soap, and a clothesline.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Think I’m missing something? &lt;a href="http://blog.brianbeck.com/post/911431304/bike-adventure-gear-part-1-camping#comments"&gt;Help me out in the comments!&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In my next post, I’ll write about the most important gear - our bikes and accessories.&lt;/p&gt;</description><link>http://blog.brianbeck.com/post/911431304</link><guid>http://blog.brianbeck.com/post/911431304</guid><pubDate>Fri, 06 Aug 2010 02:12:00 -0400</pubDate></item><item><title>The State of the Weblog</title><description>&lt;p&gt;My media server is down, so some content may be missing (pictures, linked documents), and I’m using a temporary theme.&lt;/p&gt;

&lt;p&gt;My last day of work in Cleveland is one week from today. The week after that I’ll be riding my bicycle to Seattle with my girlfriend, camping and couchsurfing on the way. It’ll take us about five weeks, and I’ll be posting frequent updates here. Hopefully our cycling adventures capture your interest as much as code and Cleveland musings.&lt;/p&gt;

&lt;p&gt;Follow if it is adventure that you seek…&lt;/p&gt;

&lt;p&gt;&lt;img src="http://media.tumblr.com/tumblr_l6e6pt2nxv1qz7sas.png" alt="bicycle"/&gt;&lt;/p&gt;</description><link>http://blog.brianbeck.com/post/881516268</link><guid>http://blog.brianbeck.com/post/881516268</guid><pubDate>Fri, 30 Jul 2010 18:37:48 -0400</pubDate></item><item><title>Serious Games talk at Case</title><description>&lt;p&gt;&lt;a href="http://media.brianbeck.com/images/Serious_Games.pdf"&gt;&lt;img src="http://media.tumblr.com/tumblr_l0skrohHIE1qz7sas.png" alt="Serious Games flyer"/&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I’ll be giving a talk on serious games at the next meeting of the CWRU Hacker Society on Wednesday, April 14th, 8pm in Glennan 313.&lt;/p&gt;

&lt;p&gt;The scope will be much wider than my previous talks on Unit Testing Achievements. A rough outline:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What are serious games?&lt;/li&gt;
&lt;li&gt;How can they be applied to software?&lt;/li&gt;
&lt;li&gt;How do they affect behavior?&lt;/li&gt;
&lt;li&gt;What’s out there now?&lt;/li&gt;
&lt;li&gt;What’s left to be explored?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;See you there!&lt;/p&gt;</description><link>http://blog.brianbeck.com/post/517068133</link><guid>http://blog.brianbeck.com/post/517068133</guid><pubDate>Mon, 12 Apr 2010 21:49:00 -0400</pubDate></item><item><title>Achievement Unlocked</title><description>&lt;p&gt;[This post is adapted from a lightning talk I gave at the &lt;a href="http://lists.idyll.org/listinfo/testing-in-python"&gt;Testing in Python&lt;/a&gt; Birds-of-a-Feather session at PyCon 2010.]&lt;/p&gt;

&lt;p&gt;One of those most fun advancements in video games in recent years is not about the improved graphics, or playing with hundreds of people at once. It’s that &lt;strong&gt;games have evolved beyond points&lt;/strong&gt;. While a good point system may be a good indicator of a player’s abilities, it doesn’t tell the whole story. Many modern games, even if they don’t involve points, have introduced the concept of &lt;strong&gt;achievements&lt;/strong&gt;. Achievements are awarded for completing game-specific challenges—essentially, they are merit badges.&lt;/p&gt;

&lt;h4&gt;Examples&lt;/h4&gt;

&lt;p&gt;From &lt;a href="http://www.teamfortress.com/"&gt;Team Fortress 2&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;&lt;img src="http://media.tumblr.com/tumblr_kycus6P6MJ1qz7sas.png" alt=""/&gt;&lt;/p&gt;

&lt;p&gt;From &lt;a href="http://www.thebeatlesrockband.com/"&gt;The Beatles: Rock Band&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;&lt;img src="http://media.tumblr.com/tumblr_kycusnZi3e1qz7sas.png" alt=""/&gt;&lt;/p&gt;

&lt;p&gt;From &lt;a href="http://foursquare.com/"&gt;foursquare&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;&lt;img src="http://media.tumblr.com/tumblr_kycusztzdZ1qz7sas.png" alt=""/&gt;&lt;/p&gt;

&lt;p&gt;These add another level of fun to the games in question. &lt;strong&gt;I think it’s about time we stole this idea for software testing.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Testing Achievements&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src="http://media.tumblr.com/tumblr_kycuz53wtJ1qz7sas.png" alt=""/&gt;&lt;/p&gt;

&lt;p&gt;To make this happen, I announced an &lt;a href="http://github.com/exogen/nose-achievements"&gt;Achievements plugin for nose&lt;/a&gt;, the Python test runner. Here are a few highlights:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Night Shift&lt;/strong&gt;&lt;br/&gt;
Make a failing test suite pass between midnight and 5am.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Punctuality&lt;/strong&gt;&lt;br/&gt;
Make a failing test suite pass at 9am.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Coffee Break&lt;/strong&gt;&lt;br/&gt;
The test suite takes between 5 and 15 minutes to run.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Happy Ending&lt;/strong&gt;&lt;br/&gt;
All tests in the suite fail…except the last.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;My God, It’s Full of Dots&lt;/strong&gt;&lt;br/&gt;
The suite has at least 2,001 passing tests.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sausage Fingers&lt;/strong&gt;&lt;br/&gt;
At least two distinct syntax errors are raised by the test suite.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Are You Mocking Me?&lt;/strong&gt;&lt;br/&gt;
Import a mocking library.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;100% Code Coverage, Level x&lt;/strong&gt;&lt;br/&gt;
100% of at least 2&lt;sup&gt;(x+7)&lt;/sup&gt; statements are executed.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://exogen.github.com/nose-achievements/"&gt;You can view the full list of achievements here&lt;/a&gt;. Many of these are working right now.&lt;/p&gt;

&lt;h4&gt;Next Steps&lt;/h4&gt;

&lt;p&gt;Announcing unlocked achievements on Twitter or IRC, global or project-specific leaderboards, pluggable achievement expansion packs…&lt;/p&gt;

&lt;p&gt;Share your ideas in the comments!&lt;/p&gt;</description><link>http://blog.brianbeck.com/post/409316644</link><guid>http://blog.brianbeck.com/post/409316644</guid><pubDate>Wed, 24 Feb 2010 12:08:00 -0500</pubDate></item><item><title>Phaeton by Kevin Cornell &amp; Randy Jones. This typeface really...</title><description>&lt;img src="http://25.media.tumblr.com/tumblr_kwnolnWhiI1qz7r2ao1_500.gif"/&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;&lt;a href="http://www.veer.com/partner/link.aspx?i=1380&amp;p=view/UMT0000447"&gt;Phaeton&lt;/a&gt; by Kevin Cornell &amp; Randy Jones. This typeface really stood out in &lt;a href="http://ilovetypography.com/2010/01/21/my-favourite-fonts-of-2009"&gt;ILT’s favorites of 2009&lt;/a&gt;. Love it!&lt;/p&gt;</description><link>http://blog.brianbeck.com/post/347528906</link><guid>http://blog.brianbeck.com/post/347528906</guid><pubDate>Fri, 22 Jan 2010 11:03:23 -0500</pubDate></item><item><title>Emergency party at my place</title><description>&lt;p&gt;Dear Reader,&lt;/p&gt;

&lt;p&gt;You knew keeping this blog in your RSS reader would pay off one day, didn’t you? You did, right?&lt;/p&gt;

&lt;p&gt;Well now you can reap the rewards, my friend. There comes a time.&lt;/p&gt;

&lt;p&gt;You are invited over to my house on Friday, November 13 for a party and performances by several talented musicians.&lt;/p&gt;

&lt;p&gt;There will be a full bar. Also an actual, physical bar. Celebrated Clevelander Marta “Martender” Lapczynski will be bartending.&lt;/p&gt;

&lt;p&gt;We’re getting started at 10 PM; music at 11. Everything is free.&lt;/p&gt;

&lt;p&gt;Here’s your invitation with the details:
&lt;img src="http://media.tumblr.com/tumblr_ksxjqmjY5M1qz7sas.jpg" alt=""/&gt;&lt;/p&gt;

&lt;p&gt;See you there, Internet lovelies!&lt;/p&gt;</description><link>http://blog.brianbeck.com/post/239979785</link><guid>http://blog.brianbeck.com/post/239979785</guid><pubDate>Wed, 11 Nov 2009 00:56:00 -0500</pubDate></item><item><title>
  “The Cleveland Tourism Board gave me 14 million dollars...</title><description>&lt;object width="400" height="336"&gt;&lt;param name="movie" value="http://www.youtube.com/v/ysmLA5TqbIY&amp;rel=0&amp;egm=0&amp;showinfo=0&amp;fs=1"&gt;&lt;/param&gt;&lt;param name="wmode" value="transparent"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/ysmLA5TqbIY&amp;rel=0&amp;egm=0&amp;showinfo=0&amp;fs=1" type="application/x-shockwave-flash" width="400" height="336" allowFullScreen="true" wmode="transparent"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br/&gt;&lt;br/&gt;&lt;blockquote&gt;
  &lt;p&gt;“The Cleveland Tourism Board gave me 14 million dollars about 8 months ago to make a promotional video to bring people to Cleveland. As usual, I waited till the last minute and I ended up having to shoot and edit it in about an hour yesterday afternoon.” — &lt;a href="http://www.youtube.com/user/bishopvids"&gt;bishopvids&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;</description><link>http://blog.brianbeck.com/post/97196132</link><guid>http://blog.brianbeck.com/post/97196132</guid><pubDate>Fri, 17 Apr 2009 10:55:19 -0400</pubDate></item><item><title>Cleveland Code Co-op meeting on Sunday</title><description>&lt;p&gt;The fifth meeting of the &lt;a href="http://nooss.org/wiki/Cleveland_Code_Co-op"&gt;Cleveland Code Co-op&lt;/a&gt; will commence this
Sunday, February 22, from 13:00 till 19:00.  We’re expecting more
participants than usual, and likely projects so far include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="http://github.com/jleedev/redit/"&gt;redit&lt;/a&gt;, a text editor in Ruby&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://code.google.com/p/cwru-hackers/"&gt;80sheep&lt;/a&gt;, an ADC (peer-to-peer) client in Python&lt;/li&gt;
&lt;li&gt;a Python tutorial for beginners&lt;/li&gt;
&lt;li&gt;your wildest software fantasies&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This month’s meeting will take place in the EECS student lounge at
Case Western Reserve University, which is located in the Glennan
Building.  &lt;a href="http://www.nooss.org/wiki/Cleveland_Code_Co-op/CWRU_Location"&gt;Directions are located on the wiki&lt;/a&gt;.  You can also join us on IRC in &lt;a href="irc://irc.freenode.net#c3"&gt;#C3 on irc.freenode.net&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Food and drinks will be provided!  Hope to see you there.&lt;/p&gt;</description><link>http://blog.brianbeck.com/post/79756939</link><guid>http://blog.brianbeck.com/post/79756939</guid><pubDate>Thu, 19 Feb 2009 15:55:53 -0500</pubDate></item><item><title>Python instance descriptors: when class descriptors aren't dynamic enough</title><description>&lt;p&gt;&lt;a href="http://users.rcn.com/python/download/Descriptor.htm"&gt;Python descriptors&lt;/a&gt; are great for customizing access to attributes on a class or instance.  They are a big win for tasks like mapping Python objects to data from non-Python sources (such as SQL), since mapped attributes will need to be encoded/decoded and connected to other attributes in some way.&lt;/p&gt;

&lt;p&gt;Below is a very simple descriptor; as you can see, accessing it from &lt;em&gt;both the class and the instance&lt;/em&gt; invoke the descriptor protocol:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class Test(object):
    pass

class Descriptor(object):
    def __get__(self, instance, owner):
        return "Hello, world."

&gt;&gt;&gt; Test.x = Descriptor()
&gt;&gt;&gt; Test.x
'Hello, world.'
&gt;&gt;&gt; test = Test()
&gt;&gt;&gt; test.x
'Hello, world.'
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;However, in order to add descriptors to an object, they must be added to the object’s class.  Descriptors added to an instance do not invoke the descriptor protocol:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&gt;&gt;&gt; test.y = Descriptor()
&gt;&gt;&gt; test.y
&lt;__main__.Descriptor object at 0x16fe810&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This means that creating an instance with dynamic (determined at runtime) descriptors requires either the heavy-handed approach of generating a class just for that object (since adding descriptors to its class will add them to all other instances of the class), or the ad-hoc approach of redefining &lt;code&gt;getattr&lt;/code&gt;/&lt;code&gt;setattr&lt;/code&gt; behavior (essentially re-implementing your own descriptor protocol).&lt;/p&gt;

&lt;p&gt;It turns out the latter approach is not as messy as it first sounds.  Below is a class that enables “instance descriptors”:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class InstanceDescriptorMixin(object):
    def __getattribute__(self, name):
        value = object.__getattribute__(self, name)
        if hasattr(value, '__get__'):
            value = value.__get__(self, self.__class__)
        return value

    def __setattr__(self, name, value):
        try:
            obj = object.__getattribute__(self, name)
        except AttributeError:
            pass
        else:
            if hasattr(obj, '__set__'):
                return obj.__set__(self, value)
        return object.__setattr__(self, name, value)

class Test(InstanceDescriptorMixin):
    pass

&gt;&gt;&gt; test = Test()
&gt;&gt;&gt; test.z = Descriptor()
&gt;&gt;&gt; test.z
'Hello, world.'
&lt;/code&gt;&lt;/pre&gt;</description><link>http://blog.brianbeck.com/post/74086029</link><guid>http://blog.brianbeck.com/post/74086029</guid><pubDate>Thu, 29 Jan 2009 12:41:00 -0500</pubDate><category>python</category></item><item><title>"The purpose of syntax highlighting is to turn your code into a map, not The Jimi Hendrix Experience."</title><description>“The purpose of syntax highlighting is to turn your code into a map, not The Jimi Hendrix Experience.”</description><link>http://blog.brianbeck.com/post/68776504</link><guid>http://blog.brianbeck.com/post/68776504</guid><pubDate>Tue, 06 Jan 2009 15:29:26 -0500</pubDate></item><item><title>geopy sprint at December C³ meeting</title><description>&lt;p&gt;Today (Sunday) the third meeting of the &lt;a href="http://nooss.org/wiki/Cleveland_Code_Co-op"&gt;Cleveland Code Co-op&lt;/a&gt; will be held from 1pm to 7pm at &lt;a href="http://www.gypsybeans.com/"&gt;Gypsy Beans &amp; Bakery&lt;/a&gt;.  We’ll be focusing on &lt;a href="http://exogen.case.edu/projects/geopy/"&gt;geopy&lt;/a&gt; again, continuing our sprint goals from &lt;a href="http://blog.brianbeck.com/post/57991307/geopy-sprint"&gt;last time&lt;/a&gt;.  All are welcome to attend.  You can join us via IRC in &lt;a href="irc://irc.freenode.net#c3"&gt;#c3 on irc.freenode.net&lt;/a&gt;.&lt;/p&gt;</description><link>http://blog.brianbeck.com/post/64744298</link><guid>http://blog.brianbeck.com/post/64744298</guid><pubDate>Sat, 13 Dec 2008 23:51:15 -0500</pubDate></item><item><title>Christmas tree adventure</title><description>&lt;p&gt;I’ve never taken the time to get a Christmas tree while living on my own before because, honestly, Christmas doesn’t mean much to me.  But having moved into a spacious single-family carriage house with Steve, it sounded a lot more fun to drag a big needly tree into my living room this year.  Today Mandy and I drove all the way out to &lt;a href="http://www.tower-n-pines.com/"&gt;Tower-N-Pines Farm&lt;/a&gt; to cut down our own tree.  We followed this up with dinner at Mary Yoder’s Amish Kitchen, where Mandy told me everything she knows about the Amish (Middlefield has the world’s fourth largest Amish population).&lt;/p&gt;

&lt;p&gt;I was hoping for an axe, but they only provided hacksaws.  I then realized that, despite being cooler and more fun, an axe would have required blindly swinging your arms into the branches:
&lt;img src="http://media.brianbeck.com/images/tree/brian.jpg" alt="Brian holding a hacksaw"/&gt;&lt;/p&gt;

&lt;p&gt;We did a &lt;em&gt;lot&lt;/em&gt; of walking and probably looked at every single tree.  This took a long time:
&lt;img src="http://media.brianbeck.com/images/tree/walking.jpg" alt="Brian walking among the trees"/&gt;&lt;/p&gt;

&lt;p&gt;We settled on this one:
&lt;img src="http://media.brianbeck.com/images/tree/precut.jpg" alt="Brian crawling under the tree"/&gt;&lt;/p&gt;

&lt;p&gt;Finally, the moment I had been waiting for:
&lt;img src="http://media.brianbeck.com/images/tree/moment.jpg" alt="Brian cheerily cutting the tree"/&gt;&lt;/p&gt;

&lt;p&gt;Mandy even got her chance to make this face:
&lt;img src="http://media.brianbeck.com/images/tree/fierce.jpg" alt="Mandy making a fierce face with hacksaw"/&gt;&lt;/p&gt;

&lt;p&gt;It worked:
&lt;img src="http://media.brianbeck.com/images/tree/fell.jpg" alt="Brian felling the tree"/&gt;&lt;/p&gt;

&lt;p&gt;Note all the inferior trees in the background:
&lt;img src="http://media.brianbeck.com/images/tree/mandy.jpg" alt="Mandy holding the felled tree"/&gt;&lt;/p&gt;

&lt;p&gt;Then there was dragging:
&lt;img src="http://media.brianbeck.com/images/tree/drag.jpg" alt="Brian dragging the tree"/&gt;&lt;/p&gt;

&lt;p&gt;We tied it to the roof of Mandy’s car using the rope from my grappling hook (farm’s ropes? $11).  It arrived safely:
&lt;img src="http://media.brianbeck.com/images/tree/unwrap.jpg" alt="Brian preparing the tree"/&gt;&lt;/p&gt;

&lt;p&gt;Steve made up for his non-participation by helping “unfell” the tree:
&lt;img src="http://media.brianbeck.com/images/tree/steve.jpg" alt="Steve holding the tree at home"/&gt;&lt;/p&gt;

&lt;p&gt;Real mature, Steve:
&lt;img src="http://media.brianbeck.com/images/tree/adjusting.jpg" alt="Steve pretending to hit Brian with a hammer"/&gt;&lt;/p&gt;

&lt;p&gt;Steve guesstimates that the tree is “almost 10 feet” tall.
&lt;img src="http://media.brianbeck.com/images/tree/done.jpg" alt="Steve and Brian admiring their tree"/&gt;&lt;/p&gt;</description><link>http://blog.brianbeck.com/post/64738729</link><guid>http://blog.brianbeck.com/post/64738729</guid><pubDate>Sat, 13 Dec 2008 22:59:00 -0500</pubDate></item><item><title>Roomba decided to take its docking station — originally...</title><description>&lt;img src="http://25.media.tumblr.com/MzaUlGORah0mgz1tg4PWBjtDo1_500.jpg"/&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;Roomba decided to take its docking station — originally placed in a much more sensible location — for a walk.&lt;/p&gt;</description><link>http://blog.brianbeck.com/post/62683797</link><guid>http://blog.brianbeck.com/post/62683797</guid><pubDate>Tue, 02 Dec 2008 16:44:03 -0500</pubDate></item><item><title>geopy sprint at November C³ meeting</title><description>&lt;p&gt;After suffering from over a year of poor maintenance, &lt;a href="http://exogen.case.edu/projects/geopy/"&gt;geopy&lt;/a&gt; is finally
getting some love this month.  A few other developers and I will be
focusing on geopy at this month’s &lt;a href="http://nooss.org/wiki/Cleveland_Code_Co-op"&gt;Cleveland Code Co-op&lt;/a&gt; meeting.
We’ve come up with an ambitious todo list, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Merging pending patches (bug fixes, Python 2.3 support, accuracy
support)&lt;/li&gt;
&lt;li&gt;Adding unit tests&lt;/li&gt;
&lt;li&gt;Reverse geocoding support (finding locations near a point)&lt;/li&gt;
&lt;li&gt;Higher level Points and Locations (instead of tuples and strings)&lt;/li&gt;
&lt;li&gt;Keeping up with third-party geocoder APIs (and hacks)&lt;/li&gt;
&lt;li&gt;A “compound” geocoder for querying multiple geocoders (as
fallbacks or for averaging results)&lt;/li&gt;
&lt;li&gt;A parser module with support for geotagged documents (including the
Geo microformat), ISO 6709, GPX files, etc.&lt;/li&gt;
&lt;li&gt;Geohash encoding/decoding&lt;/li&gt;
&lt;li&gt;A formatter module for pretty-printing coordinates, distances, and
ordinal directions (think “south by southwest”)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;setuptools&lt;/code&gt; entry points to support geocoder plugins and discovery&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I think these features are in line with the “geocoding toolbox” goal
of the project.  While there are a lot of features there, I think
geopy will still feel like a nice compact library.&lt;/p&gt;

&lt;p&gt;Why does geopy deserve some developer attention?  Because it’s being
used in numerous interesting ways, including: directing robots at Carnegie Mellon
University, calculating stream lengths for the U.S. Geological
Survey, and updating address data for the Barack Obama presidential campaign.&lt;/p&gt;

&lt;p&gt;We’ll be sprinting on Sunday, November 16th.  If anyone would like
to join us in person or on IRC, please get in touch!&lt;/p&gt;</description><link>http://blog.brianbeck.com/post/57991307</link><guid>http://blog.brianbeck.com/post/57991307</guid><pubDate>Tue, 04 Nov 2008 17:39:00 -0500</pubDate><category>geopy</category><category>c3</category><category>python</category></item><item><title>Unstoppable Rocket pumpkin.</title><description>&lt;img src="http://29.media.tumblr.com/MzaUlGORafpodu7eS1qVJIU5o1_r1_500.jpg"/&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;&lt;a href="http://www.unstoppablerocket.com"&gt;Unstoppable Rocket&lt;/a&gt; pumpkin.&lt;/p&gt;</description><link>http://blog.brianbeck.com/post/57198645</link><guid>http://blog.brianbeck.com/post/57198645</guid><pubDate>Thu, 30 Oct 2008 21:12:00 -0400</pubDate><category>unstoppable rocket</category><category>halloween</category></item><item><title>Henry the degu. ♥</title><description>&lt;img src="http://28.media.tumblr.com/MzaUlGORafmt7tgq8L6fk7G4o1_500.jpg"/&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;Henry the &lt;a href="http://en.wikipedia.org/wiki/Degu"&gt;degu&lt;/a&gt;. ♥&lt;/p&gt;</description><link>http://blog.brianbeck.com/post/56843710</link><guid>http://blog.brianbeck.com/post/56843710</guid><pubDate>Tue, 28 Oct 2008 21:04:24 -0400</pubDate></item><item><title>Simple scheduled message queue (with threads)</title><description>&lt;p&gt;Here’s a more flexible version of the message queue in &lt;a href="http://blog.brianbeck.com/post/55070874/message-queue"&gt;my last post&lt;/a&gt;.  This version uses the &lt;a href="http://docs.python.org/library/threading.html"&gt;threading&lt;/a&gt; module instead of &lt;a href="http://pypi.python.org/pypi/processing"&gt;processing&lt;/a&gt;, so it has no dependencies.  See the new example after the code.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;"""
Simple message queue.

Messages are scheduled and processed in a single worker thread spawned
from the main process.  Thus, events are enqueued asynchronously, but
processed in a linear fashion.

"""
import time
import sched
from Queue import Queue, Empty
from threading import Thread


def delay_put(duration, queue, message):
    time.sleep(duration)
    queue.put(message)

def run_scheduler(scheduler):
    scheduler.run()

class Scheduler(sched.scheduler):
    def __init__(self, queue, handler, timeout):
        self.message_queue = queue
        self.handler = handler
        self.timeout = timeout
        sched.scheduler.__init__(self, time.time, self.delay)

    def delay(self, duration):
        queue = self.message_queue
        if duration &gt; 0:
            # Spawn a process that will sleep, enqueue None, and exit.
            Thread(target=delay_put, args=(duration, queue, None)).start()
        try:
            message = queue.get(True, duration + self.timeout) # Block!
        except Empty:
            self.timed_out()
        else:
            if message is not None:
               # A message was enqueued during the delay.
                timestamp = message.get('timestamp', self.timefunc())
                priority = message.get('priority', 1)
                self.enterabs(timestamp, priority, self.handler, (message,))

    def timed_out(self):
        print "Timed out."

    def startup(self):
        print "Starting scheduler!"

    def shutdown(self):
        print "Scheduler done."

    def run(self):
        # Schedule the `startup` event to trigger `delayfunc`.
        self.enter(0, 0, self.startup, ())
        sched.scheduler.run(self)
        self.shutdown()

class MessageQueue(object):
    def __init__(self, handler, timeout=10, scheduler_class=Scheduler):
        self.queue = Queue()
        self.scheduler = scheduler_class(self.queue, handler, timeout)
        self.worker = None

    def enqueue(self, message):
        self.queue.put(message)
        if not self.working():
            self.start_worker()

    def start_worker(self):
        self.worker = Thread(target=run_scheduler, args=(self.scheduler,))
        self.worker.start()

    def working(self):
        return self.worker is not None and self.worker.isAlive()
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;input type="hidden" name="language" value="python"&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&gt;&gt;&gt; import time
&gt;&gt;&gt; def my_handler(message):
...     print time.time(), message

&gt;&gt;&gt; mq = MessageQueue(my_handler)
&gt;&gt;&gt; for i in range(1, 10):
...     now = time.time()
...     mq.enqueue({'data': i, 'timestamp': now + i})

Starting scheduler!
1224341361.32 {'timestamp': 1224341361.2808199, 'data': 1}
1224341362.3 {'timestamp': 1224341362.2912149, 'data': 2}
1224341363.31 {'timestamp': 1224341363.2913051, 'data': 3}
1224341364.32 {'timestamp': 1224341364.2913489, 'data': 4}
1224341365.32 {'timestamp': 1224341365.291404, 'data': 5}
1224341366.3 {'timestamp': 1224341366.291467, 'data': 6}
1224341367.32 {'timestamp': 1224341367.291549, 'data': 7}
1224341368.34 {'timestamp': 1224341368.291626, 'data': 8}
1224341369.34 {'timestamp': 1224341369.2921841, 'data': 9}
Timed out.
Scheduler done.
&lt;/code&gt;&lt;/pre&gt;</description><link>http://blog.brianbeck.com/post/55165808</link><guid>http://blog.brianbeck.com/post/55165808</guid><pubDate>Sat, 18 Oct 2008 10:53:06 -0400</pubDate><category>python</category><category>threading</category></item><item><title>Simple scheduled message queue in Python</title><description>&lt;p&gt;Here’s a very simple message queue using Python’s &lt;a href="http://docs.python.org/library/sched.html"&gt;sched&lt;/a&gt; module and &lt;a href="http://pyprocessing.berlios.de/doc/"&gt;processing&lt;/a&gt; (available as &lt;a href="http://docs.python.org/library/multiprocessing.html"&gt;multiprocessing&lt;/a&gt; in Python 2.6).  This lets you asynchronously schedule events to occur at a specific time.  It would be very easy to modify this to process messages with a pool of workers, or use &lt;code&gt;threading&lt;/code&gt; instead of &lt;code&gt;processing&lt;/code&gt;.  There is one thing I could use lazyweb’s help with: find places in the code where I need to use a lock or where I am ignoring &lt;a href="http://docs.python.org/library/multiprocessing.html#programming-guidelines"&gt;these guidelines&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Update: &lt;a href="http://blog.brianbeck.com/post/55165808/message-queue-2"&gt;Here’s a cleaned up version using threads&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;"""
Simple message queue.

Messages are scheduled and processed in a single worker process spawned
from the main process.  Thus, events are enqueued asynchronously, but
processed in a linear fashion.

"""
import sched
import time
from processing import Queue, Process
from processing.queue import Empty


def delay_put(duration, queue, message):
    time.sleep(duration)
    queue.put(message)
    queue.close()

class Scheduler(sched.scheduler):
    def __init__(self, queue, handler):
        delayfunc = self.make_delay_func(queue, handler)
        sched.scheduler.__init__(self, time.time, delayfunc)

    def make_delay_func(self, queue, handler):
        def delay(duration):
            if duration &gt; 0:
                # Spawn a process that will sleep, enqueue None, and exit.
                Process(target=delay_put, args=(duration, queue, None)).start()
            try:
                message = queue.get(True, duration + TIMEOUT) # Block!
            except Empty:
                print "Timed out."
            else:
                if message is not None:
                    # A message was enqueued during the delay.
                    timestamp = message.get('timestamp', time.time())
                    priority = message.get('priority', 1)
                    self.enterabs(timestamp, priority, handler, (message,))
        return delay

    def startup(self):
        print "Starting scheduler!"

    def run(self):
        # Schedule the `startup` event to trigger `delayfunc`.
        self.enter(0, 0, self.startup, ())
        sched.scheduler.run(self)

def handle(message):
    print "[%s] MESSAGE: %s" % (time.time(), message)

def run_scheduler(scheduler):
    scheduler.run()
    print "Scheduler done."

QUEUE = Queue() # Message queue.  Use `enqueue` to add messages.
TIMEOUT = 10 # Seconds for scheduler to wait for items in queue.
SCHEDULER = Scheduler(QUEUE, handle) # Message handler scheduler.
PROCESS = None # Process running the scheduler.

def enqueue(message):
    global PROCESS
    QUEUE.put(message)
    if PROCESS is None or PROCESS.getExitCode() is not None:
        # There is no scheduler process running; start one.
        PROCESS = Process(target=run_scheduler, args=(SCHEDULER,))
        PROCESS.start()
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Here’s a usage example:
&lt;input type="hidden" name="language" value="python"&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&gt;&gt;&gt; import time
&gt;&gt;&gt; enqueue({'data': 1})
Starting scheduler!
[2008-10-17 14:33:56.212] MESSAGE: {'data': 1}

&gt;&gt;&gt; enqueue({'data': 3, 'timestamp': time.time() + 10})
&gt;&gt;&gt; enqueue({'data': 2, 'timestamp': time.time() + 7})
&gt;&gt;&gt; enqueue({'data': 4, 'timestamp': time.time() + 15})
&gt;&gt;&gt; time.sleep(26)
[2008-10-17 14:34:03.221] MESSAGE: {'timestamp': 1224268443.219, 'data': 2}
[2008-10-17 14:34:06.217] MESSAGE: {'timestamp': 1224268446.215, 'data': 3}
[2008-10-17 14:34:11.225] MESSAGE: {'timestamp': 1224268451.222, 'data': 4}
Timed out.
Scheduler done.

&gt;&gt;&gt; enqueue({'data': 5, 'timestamp': time.time() + 5})
Starting scheduler!
[2008-10-17 14:34:27.233] MESSAGE: {'timestamp': 1224268467.232, 'data': 5}
Timed out.
Scheduler done.
&lt;/code&gt;&lt;/pre&gt;</description><link>http://blog.brianbeck.com/post/55070874</link><guid>http://blog.brianbeck.com/post/55070874</guid><pubDate>Fri, 17 Oct 2008 17:02:00 -0400</pubDate><category>python</category><category>processing</category><category>multiprocessing</category></item><item><title>Cleveland Code Co-op</title><description>&lt;a href="http://nooss.org/wiki/Cleveland_Code_Co-op"&gt;Cleveland Code Co-op&lt;/a&gt;: &lt;p&gt;This Sunday will be the first meeting of the &lt;a href="http://nooss.org/wiki/Cleveland_Code_Co-op"&gt;Cleveland Code Co-op&lt;/a&gt;.  Our goal is to contribute to a different Free Software project at each session, determined by the interests of those present.  This Sunday will be a &lt;a href="http://www.djangoproject.com/"&gt;Django&lt;/a&gt; sprint.  All are welcome to attend.&lt;/p&gt;</description><link>http://blog.brianbeck.com/post/54717230</link><guid>http://blog.brianbeck.com/post/54717230</guid><pubDate>Wed, 15 Oct 2008 14:35:00 -0400</pubDate></item></channel></rss>
