Google presentation at Clepy on August 6th, 2007

Tonight Brian Fitzpatrick (Fitz) from the Chicago Google office did a presentation for the clepy group on version control at Google. They use subversion on top of their own super-cool bigtable filesystem back end.

We had a good discussion on the merits of centralized vs. decentralized version control. According to Fitz, decentralized systems discourage collaboration. He made the joke, “Did you hear about the decentralized version control conference? Nobody showed up.” He made the point that centralized repositories encourage review and discussion. I agree with that.

Apparently subversion 1.5, which will be released in a few months, will have much improved merging facilities. We won’t need to use --stop-on-copy to figure out where we branched. Also, it will be safe to repeat a merge, because nothing will happen on the second attempt.

I don’t like the dispatching system in turbogears

I wanted to translate a(1).b(2)into the TurboGears URL /a/1/b/2. A browser making a request for /a/1/b/2 would trigger that code.

This page explains how to do it. You build a single default method that catches everything and then does introspection to figure out where to send the request.

It works fine, but it isn’t nearly as obvious or concise as the regular-expression approach I’ve seen in rails and Django.

Learning flex without spending $0.01, day one.

I downloaded the command-line compiler and lots of documentation PDF files from here earlier today.

Then I started working through the “getting started” tutorial PDF.

I made a few edits to my ~/_vimrc file so that working with mxml files would be a little easier:

” Do some specific maps for flex files (.mxml files).
” F10 rebuilds the swf.
autocmd BufNewFile,BufRead *.mxml map <F10> :! mxmlc %<CR>

” F11 executes the swf.
autocmd BufNewFile,BufRead *.mxml map <F11> :! start %<.swf<CR>

And I was able to build this do-nothing widget after about 15 minutes of goofing off:


That’s a screenshot of my homemade swf running above the vim session where I wrote it.

Next stuff to figure out:

  • Where do my trace statements go?
  • I need to figure out how to pass in locations of actionscript files when I compile my mxml files into swf files.
  • I need to learn the tags in MXML. They’re different than HTML.
  • I need to learn how to talk to a webserver.

Pre-employment drug screens ate my balls

This is a really old k5 diary that I’m proud of. The original post is here. I made some minor edits.

The bratty and unhelpful HR troglodyte just called and said she forgot to mention earlier that I’ve gotta take a pre-employment drug screening.

Now I gotta go and piss in a goddamn cup.

She’s unhelpful because so far, she’s been unable to answer even one of my questions about vacation, benefits, health insurance or retirement without putting me on hold and asking somebody else first. She’s bratty because she doesn’t like how I ask her to explain the nonsensical corporate jargon she throws out; I think she’d prefer that I just trust her judgement about my options rather than try to comprehend them myself.

Anyway, she should have told me about the drug test two weeks ago when I got the offer. Now I gotta get to the new city a few days ahead of my original time so I can excrete urine for these fuckers.

Dogs urinate as a sign of submission. Maybe that’s how this drug-testing thing got started; it’s just a way to break the worker’s spirit right off the bat.

I tend to glaze over when libertarians fuss about stuff like grocery store club cards, or Radio Shack asking for my address. I agree with them, but I don’t really get upset about it.

But pre-employment drug tests really make me mad. It’s not what you’re thinking. I’m clean, man. Just like our president, I can pass the FBI background check that examines the last seven years.

And I doubt these tests really accomplish anything, anyway. It’s not as if American productivity shot up after employers started screening new hires. Almost any of the tests can be easily circumvented. They’re just another sign that we’re slowly giving our dignity away.

I’m not mad because I think drugs ought to be legal. I don’t really care anymore about whether they should or shouldn’t be illegal; they are illegal, and most likely, they’re going to be illegal for a really long time. People might as well rant about bad weather. Furthermore, I wouldn’t touch them anyway.

I don’t like being treated like a criminal. Drug screening places are always shitty hellhole offices, with employees that are unhappy at the fact that they handle piss all day, so they take it out on the poor saps that need work bad enough to submit to this degradation.

This job didn’t perform a credit check (well, at least not to my knowledge) but I’ve been asked to grant permission for those for other jobs.

My sister had to take a lie detector test in order to get a promotion at one job. Where does it fucking end? Will firms send out investigators to root around houses of job applicants and look for anything that might mark them as a bad employee? Why not profile family members and find out if any of them indicate a family predisposition towards deviance? Maybe future junior partners at PricewaterhouseCoopers will have to go out and kill some nameless victim in order to make it to full partner; that way, the company always has something on them.

It’s days like this that make me want to cash out my retirement and head out of town, buy a farm, and live off the grid. But that’s not really very safe anymore either, right? A bunch of bored ATF assholes would probably come after me.

A friend warned me not to eat any poppy-seed muffins before the test. That got me thinking. In some other parallel universe, I’m gonna look up every drug analog possible and eat all of them: poppy seeds, cough syrup, cranberry juice, etc, and try to grand-slam that drug test. I want a goddamn siren to go off because of everything I (falsely) test positive for. Based on the results, doctors will want to know how I can remain standing.

But in this universe, I figured out what I’m gonna do. I’m going on an all-asparagus diet the week before my test. My piss is gonna stink so bad, lab techs will have to wear masks or risk losing consciousness. They’ll have to close the place down to fumigate.

Using dictionaries rather than complex if-elif-else clauses

Lately, I’ve been using dictionaries as a dispatching mechanism. It seems especially elegant when I face some fairly elaborate switching logic.

For example, instead of:
if a == 1 and b == 1:
log("everything worked!")

elif a == 1 and b == 0:
log("a good, b bad")

log("a failed")

Do this:

d = {
(1, 1): commit,
(1, 0): report_that_b_failed,
(0, 0): report_that_a_failed

k = (a, b)
f = d[k]

This approach is also really useful when you face the need to change logic based on runtime values. You can imagine that d might be built after parsing an XML file.

How to have a better cygwin terminal

Cygwin is a wonderful tool. However, I don’t really like the default terminal. This article shows how to set up an rxvt terminal instead.

This is a screenshot of the default cygwin bash prompt:


Copying and pasting is not intuitive, you can’t stretch the box horizontally, and most importantly, it breaks the illusion that I’m on a Unix box. But a better terminal option exists! When you install cygwin, you can also install the rxvt package. After installing the rxvt package, try this in a DOS window:

C:\cygwin\bin\rxvt.exe -fg gray -bg MidnightBlue -fn "Lucida Console-14" -e bash --login -i

You should see a terminal like this:


As far as I can tell from my experience, this terminal acts exactly like a regular rxvt terminal on a linux box. I can highlight some text with my mouse, and then paste it by hitting either shift+insert or by hitting the middle mouse button. I can resize the terminal horizontally and vertically.

I set up a taskbar icon so that I can get that rxvt very quickly. The icon before the right-most icon will start an rxvt terminal for me.


Setting it up was really simple. I made a new shortcut by right-clicking on my desktop, then I copied this text:

C:\cygwin\bin\rxvt.exe -fg gray -bg MidnightBlue -fn "Lucida Console-14" -e bash --login -i

into the target field:


Then I hit OK, and then dragged the new shortcut into the taskbar, and that’s it!

How to use compound foreign keys with Postgresql

I am working on a multiple-choice quiz program. We have four tables related to questions and answers:

  • a table of questions
  • a table of answers
  • a table that links each question to multiple answers
  • a table that records a user’s actual answer to a question.

I needed a way to track answers to multiple-choice questions, and to limit possible answers to each question. For example, I want to make sure that if I ask the question “what is your favorite color?” then the answer is a color, and not something silly like “yes.” This is tricky, because “yes” is a valid answer for some questions, but not for others.

This table holds each question.

create table questions (
q_id serial primary key,
q_text text

Here are some questions. Since I used the serial data type, I’m not going to assign the q_id column. Postgresql will assign the q_id automatically.

insert into questions (q_text) values ('What is your favorite color?'); /* q_id 1 */
insert into questions (q_text) values ('Is it raining outside?'); /* q_id 2 */

After inserting, this is what the database looks like now:

select * from questions;
q_id | q_text
1 | What is your favorite color?
2 | Is it raining outside?
(2 rows)

This table lists every possible answer, each with a unique id.

create table all_answers (
a_id serial primary key,
a_text text

These are some answers.

insert into all_answers (a_text) values ('red'); /* a_id 1 */
insert into all_answers (a_text) values ('yes'); /* a_id 2 */
insert into all_answers (a_text) values ('green'); /* a_id 3 */
insert into all_answers (a_text) values ('no'); /* a_id 4 */

Here’s what all_answers looks like after adding data:

select * from all_answers;
a_id | a_text
1 | red
2 | yes
3 | green
4 | no
(4 rows)

This table links each question to meaningful possible answers. I am using question ID (q_id) and answer ID (a_id) numbers in order to save space.

create table possible_answers (
q_id integer references questions (q_id),
a_id integer references all_answers (a_id),
primary key (q_id, a_id)

Now, I’ll link certain questions with certain answers. This insert links ‘What is your favorite color?’ with ‘red’.

insert into possible_answers (q_id, a_id) values (1, 1);

This statement links ‘Is it raining outside?’ with ‘no’.

insert into possible_answers (q_id, a_id) values (1, 3);

And, just to continue the trend…

insert into possible_answers (q_id, a_id) values (2, 2);
insert into possible_answers (q_id, a_id) values (2, 4);

Now let’s see what we’ve got:

select * from possible_answers;
q_id | a_id
1 | 1
1 | 3
2 | 2
2 | 4
(4 rows)

Finally, this is the table that will record the actual answer given for a question and make sure that the answer is appropriate for the question.

create table real_answers (
q_id integer references questions (q_id), /* simple FK */
a_id integer references all_answers (a_id), /* simple FK */
foreign key (q_id, a_id) references possible_answers (q_id, a_id) /* compound FK */

Now watch what happens when I try to insert an answer that doesn’t match the question into the database. I’m going to try to answer the question “What is your favorite color?” with the answer “yes”.

Hopefully the database will prevent me.

select q_text from questions where q_id = 1;
What is your favorite color?
(1 row)

select a_text from all_answers where a_id = 2;
(1 row)

insert into real_answers (q_id, a_id) values (1, 2);
ERROR: $3 referential integrity violation - key referenced from real_answers
not found in possible_answers
Hurray! We are prevented from entering the data! Now, let’s try storing an acceptable answer.

insert into real_answers (q_id, a_id) values (1,1);
INSERT 17196 1

That means it worked!

Oryx and Crake by Margaret Atwood

Summary: a good book about the downfall of civilization written by an author that doesn’t normally write science fiction.

Oryx and Crake is highbrow science-fiction. It’s not hard science fiction, like something written by Clarke or Sagan, where you’ll learn plenty of physics along the way. I mean it’s written by an author with literary credentials. Mainstream critics tend to all say the same thing about this book: “It’s sci-fi, but it’s good,” which is more than a little insulting to the rest of us. That put aside, this is a good book.

Most of the book reads sort of like what you would expect from everything else Atwood writes, despite the futuristic setting: children lose their innocence and discover their parents aren’t saints; love turns to jealousy; admiration turns to hate and fear and people do things they previously never could have imagined. In the end, which is usually where the book starts, the characters try to piece together some meaning out of it all, and grieve their loss.

If I didn’t like this book, I would say it’s sort of like A Separate Peace meets The Omega Man. But I did like this book. However, it’s still some seriously emotional stuff.

Margaret Atwood’s style by this point is well established: her characters change names when their situations change. The book starts off at the end, and the reader discovers what happened when the characters reflect on their lives in thoughts and conversations. Margaret Atwood loves writing about male-female and parent-child dynamics, and the subconscious forces that drive us, and Oryx and Crake is no exception.

I’m not going to run through the entire plot, but the book begins with somebody named Snowman picking through the detritus of western civilization. The plot unwinds while Snowman reflects on his life from childhood until the present. Along the way, we get the story of how the little boy named Jimmy grows up in a world that looks sort of like our near future, and becomes Snowman right after that civilization comes crashing down around him.

In Jimmy/Snowman’s childhood, the world looks vaguely like a more privatized, slightly more technically advanced version of today. As an adult, civilization has collapsed, Snowman is all alone, and he spends his time picking through the wreckage looking for snacks.

I’d wager that at least half of the books on the shelves in the sci-fi section in any bookstore revolve around some sort end-of-the-world scenario, leaving one or a few survivors to make sense out of it all. Atwood dodges the rookie mistake of trying to make her scenario seem plausible, or even worse, mentioning certain years, or real-life politicians. Instead, she goes in the opposite direction. We piece together a picture of the world in the future from snippets of conversation, consumer products, and advertising. We don’t get a detailed roadmap of how we got to a world where corporations run most everything, and their employees live in combination housing developments/office parks/shopping malls.

Crake is Jimmy’s childhood friend; they grow up together in the same private compound where their parents work. They play computer games together, they get high, they watch inordinate amounts of porn (no word on whether Atwood lurked on slashdot to research).

Like a lot of the little aspects of life in this future world, the computer games that Jimmy and Crake play are fleshed out almost to the point that it’s hard to believe these aren’t real games. “War of the Roses” is one game; it seems sort of like Magic The Gathering, or Pokemon, except the mythical monsters are replaced with the highs and lows of humanity. One player can play the Holocaust card, and another player can play the Sistine Chapel card” to negate it. Crake actually gets his name from another game, “Extinctathon”, where the players take turns wiping out species.

The boys grow apart. While Jimmy becomes more aware that he has none of his parents’ aptitude for science, Crake takes off in school. Jimmy goes to a crappy art school and Crake goes to a top science university where student research is sponsored by corporations.

Later, they come back together when Crake hires Jimmy to write marketing copy for the Crake’s corporation. Jimmy becomes possessive of Oryx, a woman who previously worked as a not entirely consensual prostitute in some unknown third-world region. Now, Crake employs her at his company, and they have some nebulous relationship that drives Jimmy away from Crake.

I liked this book because Atwood made the characters seem real. She really captures the alienated teenage boy vibe in Jimmy. The highlights of the book are Jimmy’s adolescence. Besides that, Atwood creates a fascinating view of a possible future, with pigs that are genetically engineered to provide compatible organs to humans, chickens that are refactored without sense organs, brains, or anything extraneous to the purpose of getting fat enough to harvest as quickly as possible, and popular revolts battling with corporatization. Inside all that clever scenery, there’s some pretty good characterization of children abandoned by their mothers that grow into alienated adults.

The next paragraphs could be construed as spoilers, so stop reading if that sort of thing bothers you.

Besides all the good things I mentioned above, I gotta say that the ending of Oryx and Crake left me dissapointed. We never get an explanation for why Crake wiped out humanity. We spend the whole book wondering about how civilization gets destroyed, and we eventually find out how, but we never get to the more important issue of why Crake destroyed it. Crake has been a cypher throughout the plot, so it’s not out-of-character, but, like I said above, the ending is a little dissapointing.

Maybe Atwood is trying to make some point about humanity in general: people do crazy stuff and the rest of us are stuck trying to pick up the pieces and figure out why; but, to borrow a line from Marge,

“That’s a pretty lousy lesson.”

Ubuntu and TurboGears

It shouldn’t be so hard to set up turbogears on ubuntu Feisty Fox. The easy_install-2.4 turbogears approach crashes when trying to install Cheetah.

So, here’s a list of everything I had to do:

  • I installed the Ubuntu package for Cheetah: sudo apt-get install python-cheetah
  • Then I could run the easy install: sudo easy_install-2.4 turbogears
  • I edited /etc/apt/sources.list and added multiverse to the list of available packages. In other words, I changed this section:

deb feisty universe
deb-src feisty universe

to look like this:

deb feisty universe multiverse
deb-src feisty universe multiverse

  • Then I installed the python profiler package: sudo apt-get install python-profiler.
  • I tried installing pysqlite2 through easy_install, but that blew up, so I installed ubuntu package for pysqlite2 instead: sudo apt-get install python-pysqlite2.

Now everything works.