2011-03-29

Posting code on blogger

Since I decided that I'd start blogging, I figured I'd better learn how to post code on my blog. The obvious approach is to use pre tags.

class Greeter(object):
    def __init__(self, message):
        self.message = message

    def repr(self):
        return 'Greeter(%s)' % self.message

    def print(self):
        print self.message

if __name__ == '__main__':
    g = Greeter('hello, world')
    g.print()

However, I've been using IDEs for almost a decade now... so the code looks somehow wrong when it hasn't been highlighted. Enter pygmentize, which takes code and spits out html. It does plenty of other clever things, too, but that's what I'm using it for. Setup is pretty simple. Install it however your OS requires / desires. On the command line, run

pygmentize -S default -f html

copy that output. On blogger, go to Design -> Template Designer -> Advanced -> Add CSS. Paste here.

Now, type up most of your new blog post and then flip over to Edit HTML. Take your code and feed it through pygmentize:

pygmentize -f html helloworld.py

Take that raw html and paste it into your post. You now have colorized, highlighted code that might even be readable and awesome.

class Greeter(object):
    def __init__(self, message):
        self.message = message

    def repr(self):
        return 'Greeter(%s)' % self.message

    def print(self):
        print self.message

if __name__ == '__main__':
    g = Greeter('hello, world')
    g.print()

2011-03-15

MacBook Pro Airport is disabled on wakeup

Intermittently, my laptop would wake from snooze and the airport connection would mysteriously be disabled. I'd go up to the toolbar, right click and re-enable it and everything would be fine, but... it was annoying. I finally called Apple about it. They didn't have a root-cause, but they did suggest the following:


sudo rm /Library/Preferences/SystemConfiguration/com.apple.PowerManagement.plist
sudo rm  /Library/Preferences/SystemConfiguration/com.apple.airport.preferences.plist


Which seems to have worked. I didn't have a reliable repro, su I'm not sure this worked, but I haven't had the problem since.

2011-03-14

Please don't #prayforjapan

This post isn't about not caring or not thinking about Japan and the Japanese in the wake of the earthquake and tsunami. It's about not tweeting the #prayforjapan tag. The Japanese are calling it either 東北地方太平洋沖地震 or 東日本大震災. As much as I prefer not mangling names of things across cultures, romaji translations of either of those would make unwieldily tags. The western media have been calling it the Sendai Quake and that seems reasonable. How about tagging with #SendaiQuake? Better still, Noriyuki Shikata is using #hope4japan, which kind of settles it for me.

As far as the praying goes, I have two thoughts. First  of all, I always question the motives of anyone who prays in public. If you really do care about the ongoing tragedy in Japan, then by all means do something to help them. If you want to feel righteous and charitable, try doing something tangible like, say, donating money. Secondly, the vast majority of Japanese are atheists. I've never met an atheist who wasn't at least a little annoyed at being "prayed for".

2011-03-13

Love/hate t-mobile

Tara and I recently got Nexus S phones from t-mobile. The phones are very cool but the voice quality is terrible. I just got off a call to their customer support and I could barely hear the guy. I recognized the Indian accent so I'm pretty sure my call was getting routed to ho-jai-gah land, but still. When you call the phone company's technical support line and you can't hear the guy on the other end, it does not inspire confidence. So, is this a t-mobile fail or is it a problem with the phone?

2011-03-12

Google Voice for the win.

I have a new Nexus S phone. I think it's super cool, and not in the least because it integrates with google voice. In fact, I understand it integrates pretty much perfectly. So... I'm making the switch. I tried porting my number with out success. I also note that Google Voice doesn't have any numbers available in the Santa Barbara area; I suspect the one has something to do with the other. I picked a Ventura number: 805-669-8839. Following lifehacker's advice on switching to google voice, I configured my voice number to only ring through for people I know. Unrecognized numbers go directly to voicemail. But the whole point of GV is that the voicemail is actually useful. The iPhone's "visual voicemail" was a big step in the right direction, but GV's voicemail transcription... awesome. For anyone wondering, this is why I don't mind putting my phone number up there on the web: I'm not exposing myself to having my time or my phone minutes wasted. Unfortunately t-mobile is refusing to allow me to redirect my mobile number's voicemail to GV voicemail. Apparently they won't let anyone on the flexpay contract do it. And they won't switch my contract to post-paid (or whatever it's called) for another 6 months. I even called the tech-support guys and asked them to override it, but no-can-do apparently. I guess they don't like the idea of people using GV, although this certainly doesn't stop it. I have to admit that I'm a little disgusted that t-mobile would sell me a Google branded phone and then try to block me from using a google service with it. I've set my t-mobile voicemail greeting to "I never check this voicemail box. Call my google voice number at 805-669-8839". I am hoping to port my old mobile number at some point, but for the next 6 months I'm not going to worry about it.

2011-03-11

Mocking logging in python

from logging import getLogger, StreamHandler

class DirHandler(object):
    def __init__(self):
        l = getLogger()
        l.addHandler(StreamHandler())
    def process_dir(self):
        l = getLogger()
        l.debug('foo')
        l.info('bar')
        l.warn('baz')

import unittest
from mock import Mock, patch
from logging import RootLogger
target = '%s.getLogger' % __name__
@patch(target)
class TestProcessDir(unittest.TestCase):
 def test_logging(self, mock_getLogger):
  mock_getLogger.return_value = Mock(spec=RootLogger)
  d = DirHandler()
  d.process_dir()
  method_calls = mock_getLogger.return_value.method_calls
  print method_calls
  self.assertEqual(0, len(method_calls))
  self.assertEqual(None, method_calls[0][0])

if __name__ == '__main__':
    unittest.main()
Things to note:
  1. Where you patch is both critical and potentially confusing. I tried patching logging.getLogger, but since it's already imported, that didn't work. If your code under test does from foo import bar, then you need to patch mycode.bar rather than foo.bar.
  2. Giving a spec to Mock proves that your code is at least calling your mock according to it's signature.
  3. mock_logger.method_calls is how to access the method calls. I know it's sad, but it took me a while to figure this one out.

2011-03-10

Password Management

Password management is always a pain. We all know that we should be using unique passwords for every site, and that they should be enormously long, unguessable random strings. But even with a memory palace, that's simply not terribly practical. So, just like everyone else I know, I was cheating. I had about a dozen passwords that I used for, well... everything. I kept one particularly weak one for the really junky stuff. Of course I knew this was a bad idea, but I figured "it can never happen to me". Then I watched it happen to Cory Doctorow, and then a friend who shall remain nameless... and finally the great gawker leak. Now, I couldn't remember if I had an account with gawker or any of it's affiliates or not... but either way, it was clearly time to do something about it.

Back in the day at Afilias, we had a gpg encrypted password file. The file was encrypted to all the admin's keys, so everyone with access could read it. Editing it was accomplished via a script. Not an ideal solution, but it worked for us. I wanted something a hell of a lot more user-friendly if I was going to be using it more than a dozen times a day. So, I adopted Callpod Keeper. It's a solid solution, except that it wants $30/year to work in a useful way. Basically, I enter site, userid and password for all my password type stuff into the application on my Mac. Hit save and it encrypts and syncs through the cloud with my (excitingly new) Droid. From there I can copy the password and paste it into the password field in the browser. Problem solved, or at least rendered painless enough that I'm actually following best practices. It worked on my iPhone 3G too, but the lack of easy task-switching on my old 3G and general slow crappieness meant I hardly used the browser side of it anyway.

Those of you who know me know that I'm cheap. Not absurdly cheap, but wasted money bothers me. $30/year rankles. I suspect that Randy Pausch would chide me for squandering my decreasingly free time on something that's not "important" when I could just spend $30/year, but... I can't help but think that the awkwardly named keepass stuff in conjunction with Dropbox would solve this problem... and cost $0... Droid: http://www.keepassdroid.com/ at the market OSX: http://www.keepassx.org/

And sure enough it does. Install both the droid and the osx versions for both keepass and dropbox. Generate a keyfile and put it somewhere other than your dropbox directory, with a copy on both the droid and the mac. Put your password database in your dropbox (in a private section). As long as you use a keyfile and keep it fairly much under wraps, even if someone compromises your dropbox (you're using a proper password for it now, right?), your passwords are still relatively safe.