Search Results: "piman"

17 March 2016

Enrico Zini: Enhanced xkcd password generator

gpw and xkcdpass have entered testing. How about putting them together?
#!/usr/bin/python3
import subprocess
import random
import re
re_spaces = re.compile(r"\s+")
def get_words(cmd):
    out = subprocess.check_output(cmd, universal_newlines=True)
    return (x for x in re_spaces.split(out) if x)
words = set()
words.update(get_words(["xkcdpass", "-c", "10"]))
for l in range(6, 9):
    words.update(get_words(["gpw", "10", str(l)]))
for i in range(7):
    print(" ".join(random.sample(words, 5)))
Let's check the results:
#!/usr/bin/python
from __future__ import print_function
from zxcvbn import password_strength
import sys
for line in sys.stdin:
    pw = line.strip()
    info = password_strength(pw)
    print(" pw :  crack_time_display   entropy ".format(pw=pw, **info))
$ xkcdpass -n 5 -c 7   ./checkpass
moribund fasten cologne enamor by-and-by: centuries 132.586
woolen leptonic pogrom roster Serra: centuries 127.145
shorthand Piman suctional elution unholy: centuries 119.809
Blackwell mauvish covey selenium finished: centuries 112.936
asthma bloat crenulate clean-cut cytoplasm: centuries 150.181
agreeable refined racism Captain Cyrenaic: centuries 104.28
Bothnia stagnant atomist these revise: centuries 97.91
$ gpw 7   ./checkpass
ncenspri: 11.0 days 33.903
orsterma: instant 19.54
entsssel: 14.0 hours 29.788
tempispi: instant 20.058
nidgersi: 14.0 hours 29.725
oligalin: 51.0 minutes 25.824
iseartio: 10.0 minutes 23.207
$ ./metapass   ./checkpass
herups icirop overdub oldster cingsape: centuries 147.265
mujahidin usufruct rition porky prignam: centuries 153.684
cannula irenics tableaux ntshed calcific: centuries 152.196
stopgap stale orthente Amazonia sharer: centuries 113.474
edudives mmingsso eremab prignam tableaux: centuries 147.354
tingei heroism Nathaniel cannula molasses: centuries 103.007
Torres blood lewdness prignam eremab: centuries 118.475
The strength, according to zxcvbn, seems only marginally better, and it's a wonderful way to grow a vocabulary of nonexisting words that can be dropped into cheap talk conversation to confuse the innocents.

21 March 2006

Andres Salomon: python and ruby

Martin pointed out something that I’ve complained about before, and was subsequently given the reason for (by piman, iirc). It makes sense, but it’s still kind of lame for usability purposes. Of course, that’s the python interpreter, not a front-end for users. What I really miss from ruby is something like irb for python. I don’t want a full-fledged IDE; I want a quick command line thing that can be spawned for testing code snippets, or for inspecting objects. I want it to support tab completion (it’s quite useful to be able to type “foo”.<tab><tab>, and get a list of all String methods). I’ve mentioned my desire for such a thing before, but no one’s ever pointed anything out. I just did a quick google search for “irb for python”, and discovered ipython. It seems to almost do what I want; “foo”.<tab><tab> doesn’t quite work, but x=”foo” and x.</tab><tab> does work. Nifty! Of course, it seems to have its own stupid exit behavior:

In [4]: exit
Do you really want to exit ([y]/n)? y
Yes, I really want to exit; otherwise, I wouldn’t have typed “exit”…

19 March 2006

Clint Adams: This report is flawed, but it sure is fun

91D63469DFdnusinow1243
63DEB0EC31eloy
55A965818Fvela1243
4658510B5Amyon2143
399B7C328Dluk31-2
391880283Canibal2134
370FE53DD9opal4213
322B0920C0lool1342
29788A3F4Cjoeyh
270F932C9Cdoko
258768B1D2sjoerd
23F1BCDB73aurel3213-2
19E02FEF11jordens1243
18AB963370schizo1243
186E74A7D1jdassen(Ks)1243
1868FD549Ftbm3142
186783ED5Efpeters1--2
1791B0D3B7edd-213
16E07F1CF9rousseau321-
16248AEB73rene1243
158E635A5Erafl
14C0143D2Dbubulle4123
13D87C6781krooger(P)4213
13A436AD25jfs(P)
133D08B612msp
131E880A84fjp4213
130F7A8D01nobse
12F1968D1Bdecklin1234
12E7075A54mhatta
12D75F8533joss1342
12BF24424Csrivasta1342
12B8C1FA69sto
127F961564kobold
122A30D729pere4213
1216D970C6eric12--
115E0577F2mpitt
11307D56EDnoel3241
112BE16D01moray1342
10BC7D020Aformorer-1--
10A7D91602apollock4213
10A51A4FDDgcs
10917A225Ejordi
104B729625pvaneynd3123
10497A176Dloic
962F1A57Fpa3aba
954FD2A58glandium1342
94A5D72FErafael
913FEFC40fenio-1--
90AFC7476rra1243
890267086duck31-2
886A118E6ch321-
8801EA932joey1243
87F4E0E11waldi-123
8514B3E7Cflorian21--
841954920fs12--
82A385C57mckinstry21-3
825BFB848rleigh1243
7BC70A6FFpape1---
7B70E403Bari1243
78E2D213Ajochen(Ks)
785FEC17Fkilian
784FB46D6lwall1342
7800969EFsmimram-1--
779CC6586haas
75BFA90ECkohda
752B7487Esesse2341
729499F61sho1342
71E161AFBbarbier12--
6FC05DA69wildfire(P)
6EEB6B4C2avdyk-12-
6EDF008C5blade1243
6E25F2102mejo1342
6D1C41882adeodato(Ks)3142
6D0B433DFross12-3
6B0EBC777piman1233
69D309C3Brobert4213
6882A6C4Bkov
66BBA3C84zugschlus4213
65662C734mvo
6554FB4C6petere-1-2
637155778stratus
62D9ACC8Elars1243
62809E61Ajosem
62252FA1Afrank2143
61CF2D62Amicah
610FA4CD1cjwatson2143
5EE6DC66Ajaldhar2143
5EA59038Esgran4123
5E1EE3FB1md4312
5E0B8B2DEjaybonci
5C9A5B54Esesse(Ps,Gs) 2341
5C4CF8EC3twerner
5C2FEE5CDacid213-
5C09FD35Atille
5C03C56DFrfrancoise---1
5B7CDA2DCxam213-
5A20EBC50cavok4214
5808D0FD0don1342
5797EBFABenrico1243
55230514Asjackman
549A5F855otavio-123
53DC29B41pdm
529982E5Avorlon1243
52763483Bmkoch213-
521DB31C5smr2143
51BF8DE0Fstigge312-
512CADFA5csmall3214
50A0AC927lamont
4F2CF01A8bdale
4F095E5E4mnencia
4E9F2C747frankie
4E9ABFCD2devin2143
4E81E55C1dancer2143
4E38E7ACFhmh(Gs)1243
4E298966Djrv(P)
4DF5CE2B4huggie12-3
4DD982A75speedblue
4C671257Ddamog-1-2
4C4A3823Ekmr4213
4C0B10A5Bdexter
4C02440B8js1342
4BE9F70EAtb1342
4B7D2F063varenet-213
4A3F9E30Eschultmc1243
4A3D7B9BClawrencc2143
4A1EE761Cmadcoder21--
49DE1EEB1he3142
49D928C9Bguillem1---
49B726B71racke
490788E11jsogo2143
4864826C3gotom4321
47244970Bkroeckx2143
45B48FFAEmarga2143
454E672DEisaac1243
44B3A135Cerich1243
44597A593agmartin4213
43FCC2A90amaya1243
43F3E6426agx-1-2
43EF23CD6sanvila1342
432C9C8BDwerner(K)
4204DDF1Baquette
400D8CD16tolimar12--
3FEC23FB2bap34-1
3F972BE03tmancill4213
3F801A743nduboc1---
3EBEDB32Bchrsmrtn4123
3EA291785taggart2314
3E4D47EC1tv(P)
3E19F188Etroyh1244
3DF6807BEsrk4213
3D2A913A1psg(P)
3D097A261chrisb
3C6CEA0C9adconrad1243
3C20DF273ondrej
3B5444815ballombe1342
3B1DF9A57cate2143
3AFA44BDDweasel(Ps,Gs) 1342
3AA6541EEbrlink1442
3A824B93Fasac3144
3A71C1E00turbo
3A2D7D292seb128
39ED101BFmbanck3132
3969457F0joostvb2143
389BF7E2Bkobras1--2
386946D69mooch12-3
374886B63nathans
36F222F1Fedelhard
36D67F790foka
360B6B958geiger
3607559E6mako
35C33C1B8dirson
35921B5D8ajmitch
34C1A5BE5sjq
3431B38BApxt312-
33E7B4B73lmamane2143
327572C47ucko1342
320021490schepler1342
31DEB8EAEgoedson
31BF2305Akrala(Gs)3142
319A42D19dannf21-4
3174FEE35wookey3124
3124B26F3mfurr21-3
30A327652tschmidt312-
3090DD8D5ingo3123
30813569Fjeroen1141
30644FAB7bas1332
30123F2F2gareuselesinge1243
300530C24bam1234
2FD6645ABrmurray-1-2
2F95C2F6Dchrism(P)
2F9138496graham(Gs)3142
2F5D65169jblache1332
2F28CD102absurd
2F2597E04samu
2F0B27113patrick
2EFA6B9D5hamish(P)3142
2EE0A35C7risko4213
2E91CD250daigo
2D688E0A7qjb-21-
2D4BE1450prudhomm
2D2A6B810joussen
2CFD42F26dilinger
2CEE44978dburrows1243
2CD4C0D9Dskx4213
2BFB880A3zeevon
2BD8B050Droland3214
2B74952A9alee
2B4D6DE13paul
2B345BDD3neilm1243
2B28C5995bod4213
2B0FA4F49schoepf
2B0DDAF42awoodland
2A8061F32osamu4213
2A21AD4F9tviehmann1342
299E81DA0kaplan
2964199E2fabbe3142
28DBFEC2Fpelle
28B8D7663ametzler1342
28B143975martignlo
288C7C1F793sam2134
283E5110Fovek
2817A996Atfheen
2807CAC25abi4123
2798DD95Cpiefel
278D621B4uwe-1--
26FF0ABF2rcw2143
26E8169D2hertzog3124
26C0084FCchrisvdb
26B79D401filippo-1--
267756F5Dfrn2341
25E2EB5B4nveber123-
25C6153ADbroonie1243
25B713DF0djpig1243
250ECFB98ccontavalli(Gs)
250064181paulvt
24F71955Adajobe21-3
24E2ECA5Ajmm4213
2496A1827srittau
23E8DCCC0maxx1342
23D97C149mstone(P)2143
22DB65596dz321-
229F19BD1meskes
21F41B907marillat1---
21EB2DE66boll
21557BC10kraai1342
2144843F5lolando1243
210656584voc
20D7CA701steinm
205410E97horms
1FC992520tpo-14-
1FB0DFE9Bgildor
1FAEEB4A9neil1342
1F7E8BC63cedric21--
1F2C423BCzack1332
1F0199162kreckel4214
1ECA94FA8ishikawa2143
1EAAC62DFcyb---1
1EA2D2C41malattia-312
1E77AC835bcwhite(P)
1E66C9BB0tach
1E145F334mquinson2143
1E0BA04C1treinen321-
1DFE80FB2tali
1DE054F69azekulic(P)
1DC814B09jfs
1CB467E27kalfa
1C9132DDByoush-21-
1C87FFC2Fstevenk-1--
1C2CE8099knok321-
1BED37FD2henning(Ks)1342
1BA0A7EB5treacy(P)
1B7D86E0Fcmb4213
1B62849B3smarenka2143
1B3C281F4alain2143
1B25A5CF1omote
1ABA0E8B2sasa
1AB474598baruch2143
1AB2A91F5troup1--2
1A827CEDEafayolle(Gs)
1A6C805B9zorglub2134
1A674A359maehara
1A57D8BF7drew2143
1A269D927sharky
1A1696D2Blfousse1232
19BF42B07zinoviev--12
19057B5D3vanicat2143
18E950E00mechanix
18BB527AFgwolf1132
18A1D9A1Fjgoerzen
18807529Bultrotter2134
1872EB4E5rcardenes
185EE3E0Eangdraug12-3
1835EB2FFbossekr
180C83E8Eigloo1243
17B8357E5andreas212-
17B80220Dsjr(Gs)1342
17796A60Bsfllaw1342
175CB1AD2toni1---
1746C51F4klindsay
172D03CB1kmuto4231
171473F66ttroxell13-4
16E76D81Dseanius1243
16C63746Dhector
16C5F196Bmalex4213
16A9F3C38rkrishnan
168021CE4ron---1
166F24521pyro-123
1631B4819anfra
162EEAD8Bfalk1342
161326D40jamessan13-4
1609CD2C0berin--1-
15D8CDA7Bguus1243
15D8C12EArganesan
15D64F870zobel
159EF5DBCbs
157F045DCcamm
1564EE4B6hazelsct
15623FC45moronito4213
1551BE447torsten
154AD21B5warmenhoven
153BBA490sjg
1532005DAseamus
150973B91pjb2143
14F83C751kmccarty12-3
14DB97694khkim
14CD6E3D2wjl4213
14A8854E6weinholt1243
14950EAA6ajkessel
14298C761robertc(Ks)
142955682kamop
13FD29468bengen-213
13FD25C84roktas3142
13B047084madhack
139CCF0C7tagoh3142
139A8CCE2eugen31-2
138015E7Ethb1234
136B861C1bab2143
133FC40A4mennucc13214
12C0FCD1Awdg4312
12B05B73Arjs
1258D8781grisu31-2
1206C5AFDchewie-1-1
1200D1596joy2143
11C74E0B7alfs
119D03486francois4123
118EA3457rvr
1176015EDevo
116BD77C6alfie
112AA1DB8jh
1128287E8daf
109FC015Cgodisch
106468DEBfog--12
105792F34rla-21-
1028AF63Cforcer3142
1004DA6B4bg66
0.zufus-1--
0.zoso-123
0.ykomatsu-123
0.xtifr1243
0.xavier-312
0.wouter2143
0.will-132
0.warp1342
0.voss1342
0.vlm2314
0.vleeuwen4312
0.vince2134
0.ukai4123
0.tytso-12-
0.tjrc14213
0.tats-1-2
0.tao1--2
0.stone2134
0.stevegr1243
0.smig-1-2
0.siggi1-44
0.shaul4213
0.sharpone1243
0.sfrost1342
0.seb-21-
0.salve4213
0.ruoso1243
0.rover--12
0.rmayr-213
0.riku4123
0.rdonald12-3
0.radu-1--
0.pzn112-
0.pronovic1243
0.profeta321-
0.portnoy12-3
0.porridge1342
0.pmhahn4123
0.pmachard1--2
0.pkern3124
0.pik1--2
0.phil4213
0.pfrauenf4213
0.pfaffben2143
0.p21243
0.ossk1243
0.oohara1234
0.ohura-213
0.nwp1342
0.noshiro4312
0.noodles2134
0.nomeata2143
0.noahm3124
0.nils3132
0.nico-213
0.ms3124
0.mpalmer2143
0.moth3241
0.mlang2134
0.mjr1342
0.mjg591342
0.merker2--1
0.mbuck2143
0.mbrubeck1243
0.madduck4123
0.mace-1-2
0.luther1243
0.luigi4213
0.lss-112
0.lightsey1--2
0.ley-1-2
0.ldrolez--1-
0.lange4124
0.kirk1342
0.killer1243
0.kelbert-214
0.juanma2134
0.jtarrio1342
0.jonas4312
0.joerg1342
0.jmintha-21-
0.jimmy1243
0.jerome21--
0.jaqque1342
0.jaq4123
0.jamuraa4123
0.iwj1243
0.ivan2341
0.hsteoh3142
0.hilliard4123
0.helen1243
0.hecker3142
0.hartmans1342
0.guterm312-
0.gniibe4213
0.glaweh4213
0.gemorin4213
0.gaudenz3142
0.fw2134
0.fmw12-3
0.evan1--2
0.ender4213
0.elonen4123
0.eevans13-4
0.ean-1--
0.dwhedon4213
0.duncf2133
0.ds1342
0.dparsons1342
0.dlehn1243
0.dfrey-123
0.deek1--2
0.davidw4132
0.davidc1342
0.dave4113
0.daenzer1243
0.cupis1---
0.cts-213
0.cph4312
0.cmc2143
0.clebars2143
0.chaton-21-
0.cgb-12-
0.calvin-1-2
0.branden1342
0.brad4213
0.bnelson1342
0.blarson1342
0.benj3132
0.bayle-213
0.baran1342
0.az2134
0.awm3124
0.atterer4132
0.andressh1---
0.amu1--2
0.akumria-312
0.ajt1144
0.ajk1342
0.agi2143
0.adric2143
0.adejong1243
0.adamm12--
0.aba1143

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.

Ross Burton: Oh Dear Lord

This has quite amazing amounts of crack. It looks like someone thought, "Hey, some people like Muine and some other people like Rhythmbox. Let's glue them together!". Please make it stop. Update: apparently people think I'm mocking the author. Yeah, maybe a little. However, there are some serious cracky features in there, which I personally don't like, and as this is a personal blog this is where I get to say that sort of thing. Of course there is a hell of a lot of effort in this program (albeit in Python so its easier to get stuff working), but why is this another program? We already have music players. If I only count the blessed and pratically-blessed players, there is Totem, Rhythmbox and Muine, all with different UI designs. The author of Listen must have at least partially liked one of those (from the screenshots he liked the playlist of Muine but the overall design of Rhythmbox) and then worked on one of those, say adding a pane to Rhythmbox to do what he wanted instead of duplicating large amounts of non-trivial code. It's likely that the result of this would look nothing like Listen, as I still firmly believe that it is ugly. Of course what he does in his time is his choice and none of my business, so if he wants to write another music player he can, but if someone wants to make a real contribution to the community they should interact with the community in the first place. Otherwise it's just a pet project and if it duplicates existing programs, will likely remain a pet project. Maybe this comes down to centralised source code verses distributed source code (CVS vs Arch), but I doubt it. Downloading a tarball to start patching is easy, and for most people creating an Arch branch isn't exactly trivial. Update 2: This is a very amusing open letter.

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.

30 November 2005

Ari Pollak

< piman> Why don't we have a drama severity/tag?
< ari> piman: because we're not on livejournal
< ari> let's post all of -private to livejournal with backdates
< mjg59> We should move debian-devel to Livejournal
< piman> Let's move all Debian development to LJ.

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.

20 November 2005

Erinn Clark: quod libet

Joey Hess blogs about how nice Quod Libet is. In general, I agree with him. I use it at work now, though I've historically preferred cplay as it's nice and simple and does what I want. Due to the popularity of Audioscrobbler and my curiosity about it, I decided I'd try out some of the clients that support it. It was sort of a rude awakening to discover that QL won't actually work on AMD64, which I use at home. The reason for the bug not being fixed (or RC for that matter) is really sort of funny in a sad way. EDIT: Hmm, that didn't take long. The bug's now fixed (of course, not due to my whiny blogging, but rather due to Steve upgrading the bug to RC.) Something valuable to take away from this: amd64 bugs that qualify are RC and should be treated as such. I'd probably still hesitate to upgrade severities in the future without input from an RM, but at least now it's not a questionable situation. Also, yay, now I can use QL at home. Thanks for the quick fix, Joe. Thou ninja'st. :)

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.