2011-06-29

I joined NAFAA

North American Fire Arts Association, now that's a good idea.

2011-06-24

Beginners Programming Languages

So, Chaz says he wants to learn to program. I figure Python is the way to go, but... maybe I'm wrong.  These two look like they might be interesting.

http://www.alice.org/
http://scratch.mit.edu/

Clearly if he's going to do python, I need to get a better book for him. Recommendations follow:

http://learnpythonthehardway.org/
http://www.greenteapress.com/thinkpython/html/

2011-06-22

New Experiences

If Our brains have one just one scale, and we resize our experiences to fit, then is it a good thing to expand the breadth of our experience? I have always worked on that assumption, and it seems to be deeply ingrained in our society. Children have little if any breadth of experience and they seem to be mostly happy. If every day is awesome because we've never experienced anything enormously better with which to compare it, is it possible that the quality of our lives is greater? I have always looked for new experiences and new extremes. In doing so, have I made the common experiences less enjoyable? I don't think so. I think that new experiences are rewarding because they are new. I guess I need to constantly be chasing new experiences, and I'm not sure that's even a bad thing... but it certainly can be tiring.

2011-04-03

Tracing From An "idle in transaction" Postgres Backend To The Responsible Process On A Remote System

We've all seen those nasty little "idle in transaction" processes. So I can remember, here's how to go from an unhappy postgres backend to the guilty process on a remote system.

1) Find the unhappy backend

$ ps auxww | grep postgres | grep 'idle in transaction'
postgres 22838 1.2 0.3 74476 31736 ? Rs 16:40 4:36 postgres: nutricate trans_production 10.177.66.254(47257) idle in transaction

2) We now have a remote IP and port number. PostgreSQL 9.0 is quite forthcoming about this, but older versions (and other servers) aren't quite so friendly. Once you have the PID of the unhappy postmaster, you can use either lsof or netstat to find out about the tcp connection, if ps didn't give it to you.

$ sudo netstat -ep | grep $PID
tcp 0 138 db-trans01:postgresql db-reports01:57882 ESTABLISHED postgres 702200 22838/postgres: nutr

3) ssh into the remote server (db-reports01 in the above output) and use netstat again and grep for the port number (57882 in the output above) to figure out which process owns the other end of the tcp connection.

$ sudo netstat -ep | grep 57882
tcp 0 90 db-reports01:57882 db-trans01:postgresql ESTABLISHED nutricate 672248278 16388/python2.6 

4) We now have the PID of the misbehaving process and can delve deeper to find out what it is, and eventually what it's doing.

$ ps auxww | grep 16388
2000 16388 67.6 8.0 275056 89624 pts/8 Rl+ 16:26 212:26 /usr/bin/python2.6 lib/nutricate/django/reports/summarize_parallel.py root

2011-04-01

t-mobile Fails Security 101.

I remember back when AdECN was in the process of being acquired by Microsoft. One of the things we went through was a security audit. We did pretty well, but they busted us for storing passwords in the database and made us code a change before the acquisition went through.

With the recent rash of website hacks and password database leaks (I'd link them but there are sooo many), you'd think that a company the size of t-mobile would have clued into best practices around passwords and know better. Apparently not, and best of all they're even dumb enough to advertise it on their login page. "Lost your password? Have it sent to your mobile phone." So clearly the passwords aren't being stored using a one-way hash. Good grief.

Fire Poi!

I've been playing with poi for a couple of years now... and for the last couple of month's I've been serious about it. So serious that I bought myself some fire poi. Expect a followup post about how awesome it is to spin them... and another about how badly I burned myself.

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.