Artikel getaggt mit python

lpshell – convenient launchpadlib script

These days I often use launchpadlib in my projects for scripting access/modifications in Launchpad. While launchpadlib has quite a good API documentation, this only covers the method calls, not the attributes or collections. So it often takes some poking and trying until you figure out how to access/change things.

I found myself typing the same things over and over, so I finally wrote a little script called lpshell:

#!/usr/bin/python -i
import code, os, sys
from launchpadlib.launchpad import Launchpad, STAGING_SERVICE_ROOT, EDGE_SERVICE_ROOT
lp = Launchpad.login_with('test', STAGING_SERVICE_ROOT)

This logs into Launchpad and gives you an interactive Python shell with an “lp” object:

$ lpshell
>>> lp.bugs[439482].duplicate_of

Update: I committed this to ubuntu-dev-tools now, renamed to lp-shell for consistency with the other lp-* commands.

Tags: , , , ,

Using PackageKit in Python

In order to provide a sensible upstream implementation for package query/install/remove methods in Jockey, I started playing with PackageKit and recently packaged and fixed the latest upstream version 0.2.2 work reasonably well on Intrepid.

Unfortunately there are no official Python bindings yet. The raw D-BUS interface is slightly inconvenient to use, since it is fully asynchronous. This seems to be pretty redundant to me, since D-BUS already provides asynchronous method calls (if you need them) and makes writing code painful in synchronous programs.

Thus I went ahead and created a fairly easy Python class for calling the most common PackageKit functions from a Python program (source code), including some demo code.

Now the usage becomes fairly simple:

    pk = PackageKitClient()

    print pk.Resolve('none', 'pmount')
    # [(False, 'pmount;0.9.17-2;amd64;Ubuntu', 'mount removable devices as normal user')]

    print pk.GetDetails('installation-guide-powerpc;20080520ubuntu1;all;Ubuntu')
    # ('unknown', 'unknown', 'This package contains the Ubuntu installation guide \
    # for the PowerPC architecture, in a variety of languages.\nA shorter reference, \
    # the installation HOWTO, is included in an appendix. ', '', 1074334)

    def cb(status, pc, spc, el, rem, c):
        print 'install pkg: %s, %i%%, cancel allowed: %s' % (status, pc, str(c))
        return True # return False to cancel
    pk.InstallPackages(['pmount;0.9.17-2;i386;Ubuntu', 'quilt;0.46-6;all;Ubuntu'], cb)

As usual in Python, errors are represented as exceptions.

This just leaves a few nitpicks now, such as PackageKit not being able to determine the package license with Apt, but by and large this provides the basic building blocks now.

Tags: , , ,

Asteroids bot submitted, publishing source

A while ago I blogged about my participation in the c’t programming contest to write a bot that plays against the 1979 Atari console.
Submission deadline was June 30th, and the results are trickling in now.

I am on rank 104, which I’m more than satisfied with. Unsurprisingly I didn’t make the top 50, I spent way too little time on it. But I had lots of fun with it, I have something that works, and at least outperforms my own Asteroids skills :-)

In case anyone is interested in it, the source code is on http://piware.de/bzr/ct-asteroids/. It’s a bzr branch, so you can bzr get the directory.

Tags: , , ,

My computer discovered playing games

The other day I read about the current c’t programming contest and got addicted immediately. The task is to create a program which plays the Atari Asteroids game from 1979:

Unfortunately they do not send that gem to everyone :-) , but they do send the original 8 KB of ROM, so you can play it on the MAME emulator.

So far I got the emulator and the game running, and have a Python script which tracks the objects and their velocity vectors. I spent half of the weekend doing the vector analysis bits with good old pencil and paper. Reviving all the maths bits from school (about 11 years ago) was a lot of fun! Now I have useful formulas for determining the shooting angle to hit a moving comet from a moving and decelerating ship, determining if and when two moving objects with given radius collide, etc. In my head I have a first cut of a strategy, too.

Now I just need to find some time to actually implement all of this…

Once the contest is over, I’ll publish my sources, in case anyone else is interested.

Tags: , ,

Python code coverage

Today I was playing with python-coverage, which seems to be the tool of choice for code coverage measurement in Python. Since I am constantly hacking on Jockey’s test suite, I want to strive for perfection and cover everything, so it does sound like something worthwhile.

First I tried to use it like documented:

python /usr/share/python-support/python-coverage/coverage.py -x tests/run

which just caused the tests not to run at all, for no immediately obvious reason (it worked fine with real Python modules in apport). However, it gets much nicer once you stop trying to wrap it around the command line call and start to integrate it into the test suite code itself:

import coverage
coverage.erase()
coverage.exclude('raise NotImplementedError')
coverage.start()

[... run all the tests ... ]

coverage.stop()
coverage.report(glob(‘jockey/*.py’))
coverage.report(glob(‘examples/handlers/*.py’))
coverage.erase()

(which is more or less what I committed).

This will run all the tests, and give me a report about how much code they covered, plus a list of code lines which weren’t touched. For example:

Name                 Stmts   Exec  Cover   Missing
jockey/handlers        248    242    97%   402-405, 420-421, 514

Also, the exclude() interface is much more flexible than putting #pragmas all over the place (which do not seem to really work anyway unfortunately).

Now, off to fixing everything to get 100%. I was surprised how many little bugs I found and fixed while completing the tests. Test suites FTW!!

Tags: , ,