Why I still heart k5

Sure, it’s probably one of the meanest spots on the intarweb, but there’s just so many smart people on there. I can get good advice on just about any topic imaginable. Some recent diary posts:

and so forth. And the insults are pretty clever too.

Comments

Neat code complexity tool.

David Stanek wrote a nice utility to measure code complexity. This post explains the details. Anyway, I downloaded his code and tried it out. I really like it:

$ cat matt.py
"""A few functions for use with pygenie."""
def f(x):
    "Make an 8-way branch, 1 layer deep."
    if x == 1: return 1
    elif x == 2: return 2
    elif x == 3: return 3
    elif x == 4: return 4
    elif x == 5: return 5
    elif x == 6: return 6
    elif x == 7: return 7
    elif x == 8: return 8
 
def g(a, b, c):
    "This function has 8 paths."
    if a:
        if b:
            if c:
                return 1 # a and b and c.
            else:
                return 2 # a and b and not c.
        else:
            if c:        
                return 3 # a and not b and c
            else:
                return 4 # a and not b and not c.
    else:
        if b:
            if c:
                return 5 # not a and b and c.
            else:
                return 6 # not a and not b and c.
        else:
            if c:
                return 7 # not a and b and not c.
            else:
                return 8 # not a and not b and not c.
 
def h(x):
    if x: return True
    else: return False

And this is what happens when I run the code:

$ ./pygenie.py complexity matt.py
File: /home/matt/svn-checkouts/cyclic_complexity/matt.py
Type Name Complexity
------------------–
F    f    9          
F    g    8  

The functions f and g have a complexity exceeding 7, so they print out.

This might make a nice nose plugin.

Comments

What is the connection between IM IN YOUR MANGER… and Venture Brothers?

This video is great. One of the voice actors sounds a lot like Monarch henchman #24.

Comments (1)

lolcats apotheosis

The snake is eating its tail.

Comments

Working with em-based widths can be baffling

These four paragraphs have the same number of characters, but because the letter M is fat and the letter I is skinny, different amounts of characters appear in each line:

M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M

I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I

This is the exact same text, but now I’m using a monospace font:

M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M

I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I I

Comments

Franz Kafka would like this

I got a subscription to Backyard Poultry magazine earlier this year. It’s awesome. This month’s issue led me to to the City Chicken website. And that led me to this hilarious video that chronicles one man’s quest to find out if he can raise chickens in Chicago:

Update: Cleveland Heights has an ordnance against keeping chickens. Grr. Maybe I can team with the libertarian dude down the street and make a run for city council to get this thrown out.

Comments (2)

Use bazaar and subversion together

Subversion is great and I have been using it for years. But I keep running into the same two problems over and over:

  • I did a bunch of work and I want to commit it, but I don’t have network access.
  • I spent a day playing around with a crazy idea, and I want to store my half-finished and buggy work. I don’t want to put it into the trunk because it will break a bunch of other people’s work. I don’t want to make a branch because I find branching and merging again to be tedious.

Both problems could be solved if I could make commits that were local to my hard drive and visible to me only.

Today I spent a few hours on IRC and I found out that bazaar plays really nicely with subversion, and now I have a solution.

  1. First, I loaded my subversion repository into bazaar. Here’s the command I ran:

    bzr branch svn+http://my-svn-repository.example.com/myproj

    My subversion repository has 990 revisions. This command took about 3 minutes to finish.

  2. Then I went into the local myproj directory and edited some code. I used bzr status and bzr diff to see what I changed while I worked. They operate nearly identically to their svn counterparts, but bzr diff has no --summarize option.
  3. Committing locally is really simple:

    bzr commit -m "This is a local commit and svn won't see it!"

  4. Then I did some more edits and committed those:

    bzr commit -m "OK, now maybe I have something that I want to put into subversion."

  5. Before committing to the subversion repository, I pulled down other people’s updates to the subversion repository like this:

    bzr pull svn+http://my-svn-repository.example.com/myproj

    This is a lot like running svn update.

  6. After making sure my stuff plays nice with other people’s updates, I pushed my stuff into subversion:

    bzr push svn+http://my-svn-repository.example.com/myproj

  7. Now when anyone runs svn update in their subversion working copy, they will get my work along with my commit comment.

So far, I’m really happy with this set up. The Bazaar-Subversion FAQ had a lot of really useful tips. Finally, there’s still a lot of stuff I haven’t tried yet, like renaming or copying files with svn.

Comments (2)

My zeal for McCain just evaporated

Yeesh. This is akin to a programmer mixing up javascript and java:

Questioned by reporters, McCain continued, adding that it is “common knowledge and has been reported in the media that al-Qaida is going back into Iran and receiving training and are coming back into Iraq from Iran, that’s well known. And it’s unfortunate.”

Then, Senator Joseph Lieberman, who, like McCain is a staunch supporter of the war in Iraq, stepped forward and whispered in McCain’s ear.

McCain then said, “I’m sorry, the Iranians are training extremists, not al-Qaida,” the Washington Post reported.

This article has the bloody details.

Comments

Python’s hash lookup is insanely good

As near as I can tell, looking up a string inside a set is effectively free.

I made a 9000-element set, where each element is foo_0, or foo_1, foo_2, … , on up to foo_8999. Then I measured the time cost of testing whether an element belongs to that set:

$ python -m timeit -s 's = set(["foo_%s" % i for i in range(9000) ])' '"foo_4500" in s'
1000000 loops, best of 3: 0.447 usec per loop

Next I measured a few scans across a list of the same size:

$ python -m timeit -s 's = ["foo_%s" % i for i in range(9000) ]' '"foo_0" in s'
1000000 loops, best of 3: 0.447 usec per loop
$ python -m timeit -s 's = ["foo_%s" % i for i in range(9000) ]' '"foo_1" in s'
1000000 loops, best of 3: 0.659 usec per loop
$ python -m timeit -s 's = ["foo_%s" % i for i in range(9000) ]' '"foo_900" in s'
10000 loops, best of 3: 130 usec per loop
$ python -m timeit -s 's = ["foo_%s" % i for i in range(9000) ]' '"foo_4500" in s'
1000 loops, best of 3: 631 usec per loop

It takes more time to do to two string comparisons than it does to hash the string and look it up in the set.

Comments (8)

A few rules I try to follow with TurboGears

These are a few of the rules I try to follow in my design. So far, they’ve helped me out.

I aim to finish all interaction with the database before I get to the template layer.

This is non-trivial because it is so easy to forget that a method or an attribute will evaluate into a query. I use this rule because it lets me be certain about the number of interactions each page will have with the database.

I avoid branching (if-else clause) in my templates as much as possible.

I have a really hard time detangling code when I find a bunch of nested if statements. For all but the most trivial instances, I prefer to have a bunch of similar templates and then choose the best one. For example, instead of handling both a successful login and a failed login in a single template, I’ll make two different files and then choose the right one in my controller.

In practice, I have some really similar templates. But then I go back and strip out as much of the common code as possible and put those into widgets.

Any time I find a select() call in my controller, I consider making a new method in my model.

When I write something like this in a controller:

bluebirds = model.Bird.select(Bird.q.color == 'blue')

I usually come back later and put in something like this into the Bird class:

class Bird(SQLObject):
    color = UnicodeCol()
 
    @classmethod
    def by_color(cls, color)
       return cls.select(cls.q.color == color)

Now I have something that I can reuse. If I’m feeling whimsical I’ll use functools.partial to do something like this:

class Bird(SQLObject):
    color = UnicodeCol()
 
    def by_color(self, color):
        return self.select(self.q.color == color)
 
    redbirds = classmethod(partial(by_color, color='red'))
    bluebirds = classmethod(partial(by_color, color='blue'))

Sidenote: I couldn’t figure out how to use the @classmethod decorator in the second version of by_color because partial complained. Appararently, callable(some_class_method) returns False, and partial requires the first argument to be a callable.

Maybe a reader can explain to me what’s going on there…

Comments (4)

« Previous entries · Next entries »