Search Results: "Joe Wreschnig"

23 June 2006

Raphaël Hertzog: The Python transition can continue

Since the initial announce of the transition to the new Python policy, there has been some grumblings due to some unexpected last minute changes. I spent a copious amount of time discussing with all parties involved (Matthias Klose and Josselin Mouette mainly), rewrote dh_python 2 times to accomodate everybody’s needs (those who use the XS-Python-Version field, those who won’t) while still preserving backwards compatibility and went as far as NMUing debhelper to unblock the situation (Joey didn’t want to take an active role in the dh_python update). But this is now over and things have settled down. All the infrastructure is now in sid, the interfaces have been defined and won’t change anymore. It’s now really time to continue the transition. Update your python related packages by following the instructions here. Please help by providing patches and NMUing all the packages that have not yet been updated. Join #debian-python on OFTC if you have any questions. Thanks to everyone who gave a hand to update the infrastructure required for this new policy: Matthias, Josselin, Marc Dequ nes for the CDBS class, Joe Wreschnig for the update of the policy, Steve Langasek and Andreas Barth for their advice as release managers.

8 February 2006

Joe Wreschnig: An Open Letter: Notification of copyright infringement to Abaakouk Mehdi

Update: The Listen website has been temporarily taken down, and Abaakouk Mehdi is in the process of fixing the copyright notices. I am very grateful for this. In my mind, this issue is finished; we’ll soon see a new release of Listen, with intact copyright notices, and everyone wins. Also, so people don’t take my opinion as anything other than solely mine - Eduardo Gonzalez and Michael Urman, the other Quod Libet developers who had their copyrights infringed, have also commented on the issue with slightly different views. (But first second, a brief open letter to people who leave anonymous comments calling me an ass: The only tool free software developers have to defend themselves is their copyright. Copyright infringement is not a “minor problem” but the single largest mistake you can make when writing free software. When you take my work, and strip my name from it, and plasters yours all over it, I have every legal and ethical right to be as pissed about it as I want. I love it when people use my code. I see no reason to love it when people misrepresent my code. Without the ability to pursue copyright infringement, I might as well be writing public domain code, and in that case, I might as well be getting paid for helping software hoarders, and screw you all. Abaakouk screwed up, really badly, but you guys who don’t want me to enforce my license are a real threat to free software.) Dear Abaakouk Mehdi, author of “Listen, just listen,” Your program is ugly. But beyond that, it’s infringing upon my copyright and that of my friends. Your mmkey support, on-screen display, config.py, stock.py, much of your utils.py, and probably more but because I’m already angry enough I’m going to stop looking, is taken directly from my audio player, Quod Libet. Normally, that’s fine. It’s free software. Enjoy the source. You didn’t credit any of our work on the website. That’s fine; it just makes you an asshole, albeit a law-abiding one. But you had to go one step further and rip off most of the copyright notices. You also licensed all the code under “GNU GPL v2 or later”. You can’t do that. Quod Libet’s source is released under the GNU GPL, version 2. My one consolation is your complete incompetence. I mean, it’s really obvious from your screenshots that you ripped off our OSD, and you even left in the horrendous Python style guideline violations that we’ve since fixed. You copied and didn’t use a lot of our utility functions (and you didn’t copy and reimplemented improperly a few others). You left in half my comments, but then translated some docstrings. And to cap it off, you authenticate yourself to leoslyrics.com as auth=QuodLibet. Remove my code from your release, until you can learn how to properly, and legally, credit people.

19 January 2006

Joe Wreschnig: You can talc the talc, but can you rock the rock?

Everything has fallen into place. So. Angry, Drunken Dwarves 1.0.1 is out! Get it for Windows, Debian, or get the source. Why? It’s fun. At least I think so, and most people who enjoy competitive falling block games agree! It’s finished. There’s no “unfinished ending” or “real graphics coming soon” or menu entries that do nothing; instead there’s 7 characters, an original soundtrack, and so many gameplay features we had to hide some of them. It’s free. As in free software. Not just the program source, but the XCFs, SVGs, and Reason files are also available. Jessi Silver, Jenn Hartnoll, and Michael Urman made the graphics. Ben Zeigler and Brendan Becker composed the soundtrack. Zach Welhouse wrote the dialog and character designs. And I hacked the code.

12 January 2006

Joe Wreschnig: Angry, Drunken Dwarves

So previously, if you were stalking me for some reason and tried to track my hacking activity, there was a hole of a few months between finishing pydance and going back to more Debian work. Not anymore. Two years later than expected, I m announcing Angry, Drunken Dwarves, an insanely fun block-dropping game that plays a lot like Puzzle Fighter, at least at first. It has seven playable characters, six levels of AI, secret game modes and characters, and an original soundtrack. Unfortunately, one of the things that held up the release and never got solved was the lack of Windows packages. I m really sorry, especially to the people who helped design it and use Windows. Hopefully someone steps up to provide those soon. I m not providing Debian packages either, until I can get other things related to Debian finished. Anyone can feel free to hijack my ITP and upload it if they want. I apologize for the code. It spans two or three Python minor revisions, and for about the last 1/6 of development the Pygame community was falling apart and it was hard to care much. (P.S. Due to a last minute incredible stupidity by the Numeric developers, the release was actually delayed another 20 minutes. This project is cursed.)

14 December 2005

Joe Wreschnig: How to remove features

Given that the perennial, uh, “discussion” about GNOME’s features is on us again, I thought I’d share the method I use to remove options from Quod Libet. I break them, and see how long it takes people to notice. Well, no, not really, but the amount of brokenness in an option is a good metric for whether or not people change it. One of the first options in QL was a checkbox for “Show album cover”. Sometime around 0.7 or it became impossible to turn this off, and I didn’t notice until I was redoing the preferences dialog for 0.11. Rather than fixing it, I just removed a few dozen lines of code and made it always on. No one has ever asked for it back (though someone probably will now). This has happened a couple of times. On a related note, three months ago Bram Cohen made an interesting post about configuration in software, which has been rolling around in my head picking up smaller objects since. There’s a lot of “configuration” that we don’t think of as configuration — for example, the volume in an audio player is stored in basically the same place (same file, GConf tree, whatever) as, say, where the program looks for files. But we only think of the later as part of our “configuration.” That’s because we control the volume “nearby,” in the same place we view it, but the location to look for files in a very different spatial place (an entirely separate window). No one would be crazy enough to put a volume control in a Preferences dialog. So “configuration” becomes synonymous with “hard to find”. The answer to configuration creep, then, is to provide as much direct manipulation as possible. At least from the UI perspective. You’re still screwed from the combinatorial explosion on the implementation side. Beyond that, one thing I’d really like is for context menus to be more common. That is, users should be able to expect to right-click on a widget, and change changable aspects of that widget. This also means making right-click involve no surprises — it shouldn’t activate buttons, shouldn’t delete things, etc. Otherwise people will be too afraid to right-click to try configuring. This feels like a good substitute for when direct manipulation isn’t really possible, because the most direct form of manipulation is already taken up by the widget’s primary purpose. Anyway, Quod Libet is going to be moving in this direction in the future. We already have plugins configurable in the same dialog where you turn them on and off. In 0.16 the tray icon has become an interface almost unto itself, and so it has a separate Preferences dialog now, launchable only from the icon. (It also only has one thing to configure, but that might change. Most importantly, it can grow, without getting in the way of people who don’t care about the tray icon.) For 0.17 I’m probably going to fulfill the common “display remaining time” feature request by putting a radio context menu on the time display. And so on. Fixing Real Bugs
But enough about UI wankery. Does anyone know of a nice C parser for Python? Inspired by a bug he found in mmapmodule, Michael’s written a tool to find type signature issues in CPython functions, but its usefulness is lessened by the fact it returns a ton of false positives and probably also misses many things as well. You Are All Self-Absorbed
My project for a class this semester involved trying to extract useful categories from the link structure of weblogs. Unfortunately it turns out weblogs are all about navel-gazing, and the link structure isn’t at all useful. The majority of shared links on Planet Perl,Debian,GNOME,Python pointed to perl,debian,gnome,python .org, and the majority on MSDN Blogs pointed to microsoft.com. Only about 10% of links pointed to a post on another weblog. Given that additionally weblogs tend to not have comments (and even if they do, people reply in another weblog post anyway), that’s kind of sickening. Can you imagine how much email would suck if only one out of every 10 mails got a reply? I wouldn’t be able to spend all day reading about how Debian’s FTP masters are doing their job properly.

2 December 2005

Joe Wreschnig: Python, again

Accessors
Matt, Python has advanced tremendously and supports uniform access even more nicely than Ruby. You don’t need to play __getattr__ games at all. class Foo(object):
    def get_foo(self): return unmangle(self.__foo)
    def set_foo(self, value): self.__foo = mangle(value)
    def del_foo(self): ...
    foo = property(get_foo, set_foo, del_foo, "docstring goes here")
There’s actually a nicer syntax with the new decorators, but this will work with the Python in Debian. Unlike Ruby, this means you can un-wrap the attribute later if it turns out you don’t need mangling functions and do need speed. (Dick Davies pointed out I said this without anything to back me up. Timing these different methods, it turns out raw attribute access in Python is 30% faster than Ruby’s attr_*, which in turn is 50% faster than manual attribute setters in either language; non-property-ized Python get/sets are slightly faster than Ruby, but property-ized ones are slightly slower. There is a definite advantage to being able to expose the raw attributes.) Really, public get/set methods are a nasty hack, mostly restricted to C++/Java and Ruby/Python/etc. written by people who spent too much time around C++. Welcome
Michael Urman, co-developer of Quod Libet (and author of its sexiest parts), finally got a weblog. Currently there’s not much there, but he’s (hopefully) going to write about the metaprogramming he used to write an awesome Python ID3 reader/writer, and also some details on the Python interpreter bugs we keep turning up.

23 November 2005

Antti-Juhani Kaijanaho: Argh

Can we agree on not calling Anthony Towns AJ? Every time someone refers to AJ in the lists or in Planet Debian, it takes me a few moments to realize it's not me they are talking about. Let's face it, AJ is a fairly obvious nickname for anybody with the (partial) initials A. J. And there are bound to be many of those. I personally discourage people calling me A(-)J, but there still are many people who do so. Since I have been called that by many people since eigth grade (around 1991), I have learned to respond to that name. I personally use it only in the three-letter signature AJK. It took me some time to realize that Joe Wreschnig wasn't calling my reading of the old SC very strange, and even now I cannot be 100 % sure. Update: Joe has updated his post to no longer refer to Anthony as AJ.

15 November 2005

Joe Wreschnig: Sick, 0.15, and so on

Ick.
So I caught some sort of cold/flu thing, which inverted my sleep schedule (especially since it happened as daylight hours began ending around 5PM). In the process of rotating it back I got sick again, probably due to lack of sleep. Last night I didn’t sleep at all, so hopefully I can pass out around 10PM tonight without a problem. Quod Libet 0.15
Released (and uploaded to Debian), featuring all the aforementioned speedups (SVN actually has even more yet, and some significant memory reductions). We are polishing everything up (and working on the audio feed browser (feedparser is seriously hot)) for 1.0. It’s all very cool. Well, except the times GStreamer segfaults; that’s not so cool. Geeky Jokes
In a lecture on quantifier semantics, my NLP professor made the comment “In America, a b F(a, b). In my country, b a F(a, b).” Much of the class laughed. Speaking of NLP, my final project for that class is likely to segue into the next thing [info]gesten and I tackle, assuming I have any free time at all next semester. Books
I haven’t spent money on books in almost two months (aside from textbooks). This means the amount of books I own and haven’t read is actually for the first time in about a decade. Soon maybe I’ll even be able to go back and reread the books I read when I was 12 but don’t remember very well (ruining precious childhood memories in the process). Python Optimizations
Just because all my posts have had one of these lately, two recent things that surprised me: if s[:1] == c: is slightly faster than if s and s[0] == c:. And if v: is slightly faster than if v is not None: if v could be 0, “”, or (), the false immutables (this one surprised me less after some thought, but it’s still easy to forget when is is otherwise faster).

11 November 2005

Joe Wreschnig: More Python

I’m writing a registration database for Anime Detour, our local anime convention. Normally I would hate this kind of work (does anyone actually like SQL?) but SQLObject, which [info]gesten pointed me towards, is really awesome. It basically turns any SQL database (in my case SQLite) into a Python object database, with classes as tables, instances as rows, and Python class methods for queries. People stuck writing database code should definitely check it out. Another Optimization Lesson
Quod Libet stores a library of your music, like most other players. The most common things the library needs to do, and therefore the most efficient things it should do, are 1) get a list of songs in the library, and 2) check to see if a song is in the library (or equivalently, given some handle, retrieve the song with that handle from the library). Anyone familiar with Python will probably think of a dict keyed to something unique, like the filename or URI. That’s what I did, and that’s what I wrote. When QL saves, it serialize the song list using pickle, and dump it to the library: pickle.dump(library.values(), file). When it loads, it does something like for song in pickle.load(library): if song.valid(): library.add(song) where song.valid() reloads the song if its mtime has changed or removes it if the file no longer exists. So what’s the problem with this code? I sure didn’t see one until this morning, when our Italian translator complained about interestingly long cold cache startup times. The answer’s at a lower level than Python programmers usually have to work at: This sucks for disk cache. library.values() dumps the file in Python dict order, which is not only not meaningful, it’s actually semi-random for security reasons. When I reload the dumped file and iterate through the songs in it, I’m stat(2)ing files in an order designed to be as unpredictable as possible. How is the cache supposed to cope with that? The answer is, it doesn’t. Sorting the songs by filename when saving the dict costs almost nothing (Python out-sorts every other language as far as I know), but saves 10% wall clock time for me when starting - it will probably save even more on filesystems that perform poorly on stats of large files (reiser3), and directory trees that go more than 2 levels deep. Lessons learned: First, CPU profiling is good, but doesn’t have all the answers; profile.py insists the program is slower because of the sorting on exit. Second, ideas that work fine for n=100 don’t work well for n=10000 even if the algorithm you chose scales well with regard to complexity theory. Finally, the fundamentals still matter; fixing slow Python code still makes you consider OS/hardware-level cache effects.

5 November 2005

Joe Wreschnig: Paint a bikeshed!

So we’re trying to come up with a name for the Podcast subscriber/player part of Quod Libet. For obvious reasons, we don’t want to call it “Podcasts” any more than we called the paned browser “Please Sue Us For Patent Violations, Apple”. “Audioblogs” and “Blogcasts” both have the disadvantage that I’d want to claw out my eyes after seeing the word “blog” every time I click on the View menu. While we’ve gotten plenty of suggestions that are perhaps even worse than blogcast (”Webtap”, “Audio Planet”, “Quodcast”, “Oggregator”), the only marginally good one we’ve found is “Audio RSS” or “RSS Audio”. Which is to say, that’s the only pair I’ve liked. Anyone got a better idea? Update: Many people have informed me that there are actually podcasts out there using Atom, which I was unaware of. “Audio Feed” seems to be the most popular. “RoggSS” is even worse than the ones I mentioned.

3 November 2005

Joe Wreschnig: GNOME Performance Day + 3 = Python Performance Day

To whoever decided it would be a good idea to make Python’s gettext.ngettext search the filesystem for the domain’s mo files every time it is called (potentially one “J. David Ibanez”), please don’t go near any standard libraries ever again. You are personally responsible for almost 30% of the time spent loading Quod Libet’s album list, and probably a proportional amount of time wasted elsewhere in the program. For people using gettext.py, here is something to replace gettext.install with:
def install(domain, localedir=None, unicode=False):
    import __builtin__
    t = translation(domain, localedir, fallback=True)
    __builtin__.__dict__['_'] = unicode and t.ugettext or t.gettext
    __builtin__.__dict__['ngettext'] = unicode and t.ungettext or t.ngettext
(Python 2.4 users may want to have the codeset kwarg as well. Update: Fixed a thinko where I used “self” and meant “t”. Submitted upstream.) Now with added bonus of not having to import ngettext yourself in every module. (Yeah, using __builtins__ is kind of ugly, but I’m just going for minimum interference with existing code.) Before:
   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
     1851    0.020    0.000    1.070    0.001 gettext.py:475(ngettext)
After:
   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
     1851    0.000    0.000    0.010    0.000 gettext.py:345(ungettext)

21 October 2005

Joe Wreschnig: Vorbis comments and tracktotal

Breaking radio silence to complain about something both trivial and technical, so it’s probably best if everyone skips this post. Unless you write a CD ripper or audio tagger. Then please read this post, because I’m going to explain why you’re wrong. (Someone emailed me about why Quod Libet acts this way, and I figured I’d make my answer public, with the hope it helps things.) History
Decades ago, before there was Ogg Vorbis, people used an obsolete standard called MP3, and tagged it with something called ID3 (in particular, ID3v2). One of the possible tags was TRCK, for the track number. It was stored as a string in “x/y” format, for track number x out of y total tracks. Perhaps this could be improved upon; maybe not (I’ll make a case for not later). Regardless, that’s how hundreds of thousands, if not millions, of files were tagged. Ogg Vorbis Comments
These days we have something better — Ogg Vorbis and its tagging format. Vorbis specified a tag called tracknumber, analogous to TRCK.
TRACKNUMBER: The track number of this piece if part of a specific larger collection or album
Now, this is a bit ambiguous. In particular, TRCK says how you should store the total number of tracks, and the Vorbis comment specification doesn’t. A strict reading indicates you can’t, but then the same standard is designed to be particularly loose about the data stored in the tags. So a lot of programs, including really popular ones, just kept their ID3 format and wrote tracknumber=x/y. Everyone was happy. Then someone — I wish I knew who, so I could write this to them personally — decided trying to parse the track number in this format was too hard, and so decided they would make a tracktotal tag that stored, as a single number, the number of tracks. Whoever Did This Is Wrong
Whoever decided to do this was pretty dumb. There’s a number of false assumptions here, roughly in decreasing order of annoyance: The result is that every program still needs to understand x/y — even if every Vorbis file used the new format — and the new format, and also needs to do the work to construct track numbers in the new format, assuming it wants to use them. That’s why Quod Libet converts everything to x/y format. I urge authors of tagging applications and CD rippers to abandon stupid standards. Instead, you should be spending time fixing your ID3v2 readers and writers, because they all suck too. P.S.
If anyone knows what program is putting ISO-8859-1 values into Vorbis tags, please let me know. I have spiked cluebat for you. A Summary of Other Things
I moved into a new apartment building next door to my old one, owned by the same student co-op, so it doesn’t actually seem like I moved at all. School started and is going well. I saw DOOM earlier this week for free, and enjoyed it. I’ve learned a lot about Python i18n over the past few months and am writing a brief howto explaining how to do it properly.