« | » Main « | »

Talking technically

Sunday 26 September 2010

I've been thinking a lot this week about how to talk about technical topics, for a few reasons. First, the PyCon 2011 call for proposals is out. Second, as the organizer of the Boston Python meetup, I'm frequently talking to members about possibly presenting, and this week I was considering an especially complex proposal, and trying to wrestle it into a digestible form.

Lots of people, when presented with the possibility of doing a technical talk, will decide that they aren't skilled enough at speaking. It is scary doing your first presentation, but you should know that everyone is bad at it before they try it. I was a nervous wreck before and after my first conference talk, but now I look forward to them. You aren't as different from the people you see up there now as you think.

Another big self-barrier is "I don't have a good topic." This is also not an insurmountable hurdle. If you don't have a topic now, you can probably find one easily. Here are some ideas for finding a topic:

  • Jack Diederich suggested the heuristic of looking back a year and asking yourself what you had wished you knew back then. Tell others about it.
  • Alternately, think about what it is you hope to learn in the coming year. One way to learn it well is to suggest it as a PyCon talk. Giving talks don't have to be just teaching experiences, they can also be learning experiences.
  • Have you built something you think is cool? Tell the world about it.
  • Even if you haven't built it, is there something you use that you think deserves broader exposure? Explain why.

If you are going to talk about something you (or something else) has built, you have to figure out how to make it applicable to other people:

  • If your project is useful to other people, your topic could just be the project itself: "How to Use MyProject to Fooble your Baz Better", or whatever.
  • But you may have a project with a small audience, or maybe it's only interesting to you. Was there a special challenge in building it? That can be your topic, so long as you can generalize the problem so that others can appreciate it. If you've built a connector so that Django can query your 40-year-old legacy database, you don't want your topic to be "How to Read AncientDb Records," you want it to be "How to Build a New Backend for Django."

This last point is the most important: put yourself in other Pythonistas' shoes, and ask yourself why they will care about your topic. Don't get me wrong, I'm not trying to dissuade you. If anything, I hope you'll do this and find the story you can tell that will interest more people than you thought.

Propose a PyCon (or Python meetup!) talk, you'll be glad you did.

Coverage.py v3.4

Sunday 19 September 2010

Coverage.py 3.4, the latest release of my code coverage tool for Python, is now available. If you haven't been trying the betas, then new in this release are better ways to direct's coverage.py's attention on your source code, a number of fixes to reporting, especially the XML report, and now completely unexecuted files can be reported as 0% covered.

Enjoy!

Python Meetup: Beginner's Night

Friday 10 September 2010

Next Wednesday, the Boston Python meetup will be having a Beginner's Night. I'll lead the session using an expanded version of my Whirlwind Python presentation.

Boston Python

The goal is to introduce programmers from other languages to the Python world. I'm hoping it will be a lively interactive session. I know a number of experts will be on hand to help and probably heckle.

If you're in the area and either want to learn Python or help others learn it, drop in, all are welcome.

And now a question for old hands out there: What do you wish someone had told you earlier when you were first learning Python? Did you have an "aha!" moment later than you should have? What was the part of the language or culture that held you back until you got it?

Coverage.py v3.4 beta 2: uncovered files

Monday 6 September 2010

I just posted Coverage.py v3.4 beta 2, the latest version of my code coverage measurement tool for Python. The biggest change is now if you specify --source to tell coverage where to find source files, it will identify file that weren't executed at all, and add their 0% coverage to the final report. This has been a highly requested feature for a long time, and for good reason: what's the point in measuring lines that aren't executed if entire files slip by unnoticed?

But unexecuted files are only detected if --source is specified, because otherwise coverage.py won't know where to search for files. I don't know if there's a useful default for something like this. Let me know if you have any interesting ideas.

A small but interesting change: coverage percentages will now only be reported as 100% or 0% if they are truly all or nothing. In the past, you could have 99.6% rounded to 100%, or 0.4% rounded to 0%.

Making good tar files on Windows

Sunday 5 September 2010

I work on Windows, and produce Python kits for various projects. Of course one of the kits is a source kit, as a .tar.gz. Python's distutils does a fine job of this, but it uses the native system command to tar up the files, and this means my tar files are from Windows.

The problem is that Windows doesn't know how to make tar files that look native on Unix: the permission bits aren't right, they come out as 0700:

drwx------ batcheln/100      0 2010-08-21 14:13 coverage-3.4b1/
-rwx------ batcheln/100    516 2010-08-08 09:36 coverage-3.4b1/AUTHORS.txt
...

The tar command let me set the mode bits in a command-line switch, which means I could set them in an environment variable, but that would make all the files have the same permission bits, and directories and files should be different.

To fix this problem, I wrote a distutils extension command. It turned out to be not difficult, distutils has good extensibility.

To make a new command, create a new package directory somewhere, I called my "distcmd". To make a command called "fixtar", you you derive a class from distutils.core.Command, name it fixtar, and put it in a file called fixtar.py. You have to provide three methods:

from distutils.core import Command
import shutil, tarfile

class fixtar(Command):
    """A new setup.py command to fix tar file permissions."""

    description = "Re-pack the tar file to have correct permissions."

    user_options = []

    def initialize_options(self):
        """Required by Command, even though I have nothing to add."""
        pass

    def finalize_options(self):
        """Required by Command, even though I have nothing to add."""
        pass

    def run(self):
        """The body of the command."""
        # Put something useful here!

The initialize_options and finalize_options methods are required. It's too bad distutils didn't allow them to be omitted in cases like mine where there are no options to specify. The run() method is the interesting one, that's where all the work will happen. In mine, I read the tar file distutils made, and I create a new tar file just like it, but with the permissions and owner info that I want:

def run(self):
        """The body of the command."""
        for _, _, filename in self.distribution.dist_files:
            if filename.endswith(".tar.gz"):
                self.repack_tar(filename, "temp.tar.gz")
                shutil.move("temp.tar.gz", filename)

    def repack_tar(self, infilename, outfilename):
        """Re-pack `infilename` as `outfilename`.

        Permissions and owners are set the way we like them.

        """
        itar = tarfile.open(infilename, "r:gz")
        otar = tarfile.open(outfilename, "w:gz")
        for itarinfo in itar:
            otarinfo = otar.gettarinfo(itarinfo.name)
            if itarinfo.isfile():
                otarinfo.mode = 0644
            else:
                otarinfo.mode = 0755
            otarinfo.uid = 100
            otarinfo.gid = 100
            otarinfo.uname = "ned"
            otarinfo.gname = "coverage"
            otar.addfile(otarinfo, itar.extractfile(itarinfo))
        itar.close()
        otar.close()

To invoke my new command, I have to tell setup.py to pull it in with the --command-packages=distcmd switch. Then I can simply use "fixtar" as a command on the line just like any other:

python setup.py --command-packages=distcmd sdist --keep-temp --formats=gztar fixtar

Now I get a tar file that looks right:

drwxr-xr-x ned/coverage      0 2010-09-04 19:44 coverage-3.4b2/
-rw-r--r-- ned/coverage    516 2010-08-08 09:36 coverage-3.4b2/AUTHORS.txt
...

There's a bit more complication to it, because of the --keep-temp switch that I needed to keep the original tarred files around so they could be re-tarred. The real fixtar.py also cleans up that directory.

This was more than I wanted to do to get the right permissions in a tar file, but it was a chance to see how distutils extensions work, and it lets me make all my kits in one place.

« | » Main « | »