Fuzzy notepad

this is very hard to write on

arrived
fluffy
[info]eevee
And checked in.

Room block is 1004 for Team Kecleon, 1006 for Fag Squad, and 1005 for Miscellaneous.

I am temporarily rejoining the Twitter bandwagon, since this sort of thing is exactly what it was best for in the first place. I am still @eevee. Follow me if you're, like, here.

Giratina is hard to catch!

I haven't slept right in three days and am fucking exhausted. Ungnjergkjherg.
Tags:

-> anthrocon
fluffy
[info]eevee
Already in Baltimore, and going the rest of the way tonight. I'll be in Pittsburgh by 1pm tomorrow, and likely some flavor of exhausted.

Anyone stying in my room block should probably get my phone number or something.
Tags:

Scoping is fun
fluffy
[info]eevee
>>> for f in [lambda: _ for _ in range(3)]: print f()
2
2
2

>>> for f in [(lambda x: lambda: x)(_) for _ in range(3)]: print f()
0
1
2



Here's a crash course in dicking with Python functions.

lambda is a keyword that creates a function you can call from a single expression. It's usually used for passing around very small operations that you're not going to reuse. For example:
>>> double = lambda number: number * 2
>>> double(4)
8

Practical use:
>>> numbers = [-4, 1, 5, -2, 3]
>>> sorted(numbers)
[-4, -2, 1, 3, 5]
>>> sorted(numbers, key=lambda _: abs(_))
[1, -2, 3, -4, 5]

Normally sorted() will sort a list in normal numerical order, but by passing a function as a key parameter I can change what it uses to sort by.
I'm getting in the habit of using _ as a very short-lived variable name, since it's quick and stands out.

If you want to make a list by transforming another list, you can use a list comprehension.
Normally you'd have to do this:
>>> squares = []
>>> for n in range(5):
... squares.append(n ** 2)
...
>>> squares
[0, 1, 4, 9, 16]

But with a list comprehension:
>>> [_ ** 2 for _ in range(5)]
[0, 1, 4, 9, 16]

By the way, if it weren't obvious, range(n) creates a list of integers from 0 through n-1.

Now, let's look at that first line again.
>>> for f in [lambda: _ for _ in range(3)]: print f()
The bit in brackets is a list comprehension, creating three functions that each just return a number. We can turn this into a regular list:
>>> for f in [lambda: 0, lambda: 1, lambda: 2]: print f()
Then the loop goes through them one at a time and calls them all. We can expand this loop, too:
>>> print (lambda: 0)()
>>> print (lambda: 1)()
>>> print (lambda: 2)()

Which should result in:
0
1
2


Notice, though, that I got three 2s back. Why is this?

The problem is that all functions in Python are actually closures, and that variables are function-scoped.
What the hell does that mean? Let's rewrite that list comprehension so we can examine it a little more closely:
>>> results = []
>>> for _ in range(3):
...     results.append(lambda: _)

This does exactly the same thing; it creates a list of three functions, each of which returns a number. So why do we not get three different numbers?
The first problem is that our loop variable, _, is not destroyed and recreated for each run of the loop. This is true in some languages, but not in Python; it's the same name for the same chunk of memory. Variables are only created discarded at the end of a function. So this loop ACTUALLY unrolls to:
>>> results = []
>>> _ = 0
>>> results.append(lambda: _)
>>> _ = 1
>>> results.append(lambda: _)
>>> _ = 2
>>> results.append(lambda: _)


Well, so what, right? It's still three different numbers; why shouldn't it work?

The other problem is that Python, like most languages worth a damn, uses closures. This means that functions have access to all the visible variables defined outside of it. More importantly, a closure isn't frozen in time; they are the same variables, so any changes that are made also apply to the function. So when we call each of these lambdas, we aren't retrieving the _ was; we're retrieving what it is, and after the loop is finished it's still set to 2!

This DOES work fine in Perl, though, because Perl uses block scoping. That is, a variable belongs to the block it was created in, whether that block is a file or a function or a loop or just two braces you stuck around some code. At the end of a loop run, the variable is discarded, and a new one is created for the next time around—so functions you create in a loop like the above would all be pointing to different variables, even if the name looks the same, and it would work how you expect.

The problem plagues JavaScript, too, but it's a little more insidious there. You can explicitly declare variables in JavaScript just like in Perl, including inside a loop, so it looks like the variable only belongs to the loop. But, like Python, JavaScript uses function scoping. (JavaScript 1.7 now has block scoping, with a new keyword let, but I don't think this is cross-browser yet.)


So how to fix this?
[info]duskwuff has brought to my attention that there is a much more elegant fix than mine:
>>> for f in (lambda: _ for _ in range(3)): print f
This works because the parentheses (as opposed to square brackets, which always mean a list) create a generator. That's a magic function that returns a value when it's called, then picks up where it left off and returns some next value when it's called again. This way, the print is done for each value before the next one is assigned to _. But this is clearly cheating and doesn't work for all cases so nyah.


So, more specifically, how does MY fix work?
Well, we need a new variable for each run of our loop. But it's a loop, so it's running the same code, which means it has to reuse the same name. A new variable with the same name can only exist in an inner scope, and in Python that means a function. So.. make a function. A function that returns the function we want.

>>> results = []
>>> for _ in range(3):
...     def function_maker():
...         inner = _
...         return lambda: inner
...     results.append(function_maker())


Look what I did here. inner is created within function_maker, so it only belongs to that function. function_maker is redefined every time the loop runs, so the scope is, too, which means inner is recreated. This is exactly what we want, and you may notice that it works as expected.

So how is this the same as what I wrote above? Let's cut it down a bit. First, we don't actually need to define inner like that; we can just pass it as an argument, since arguments are all scoped to their function.
>>> results = []
>>> for _ in range(3):
...     def function_maker(inner):
...         return lambda: inner
...     results.append(function_maker(_))

Now function_maker just returns an expression, so it can be turned into a lambda.
>>> results = []
>>> for _ in range(3):
...     function_maker = lambda inner: lambda: inner
...     results.append(function_maker(_))

This looks weird, but it does exactly the same thing: function_maker is a function that takes a value called inner and returns a function that, when called, will return that value.
Of course, since function_maker is only used once, there's not much point in giving it a name. We can just stick that mess in parentheses instead.
>>> results = []
>>> for _ in range(3):
...     results.append((lambda inner: lambda: inner)(_))

Here we're creating the function and immediately calling it. This is, of course, exactly equivalent to the list comprehension in my original solution.


I am sure I have bored everyone who already knew all this and bewildered everyone who didn't. Oh well. :V
Tags: ,

A Question Without an Answer
fluffy
[info]eevee
http://www.futilitycloset.com/2009/01/09/a-question-without-an-answer/

Melodramatic! It's not that bad a problem.

MATH OH NO )

the answer )
Tags: ,

Irony
fluffy
[info]eevee
There's that one song, Ironic, which quite misunderstands the concept and is full of examples of bad luck rather than actual irony.

People who like to feel smarter than the average ranger enjoy pointing out that nothing in Ironic is ironic, and that's the real irony.

The realer irony is that those people don't know what irony is either—a couple things in the song are, at least arguably, situational irony.

Mmm, metairony. I think the moral of this story is that most people slept through high school English class. (I know I did!)


Cue argument about the correct definition of irony and how situational irony isn't really irony and so forth.
Tags:

Networking a house
fluffy
[info]eevee
We are, as you may have heard or otherwise discerned, nerds. In fact, we have an average of two computers each—three if you count less-than-operational machines.

All of these beasts need to get online, naturally, and that poses something of a problem: delicious Internet juices must flow from some hole in the wall to various machines scattered throughout the house. Our current solution to this conundrum is to have untold feet of cat-5 taped to the floor in the hallway. On a scale of classiness, this ranks about as high as having spare car parts in an overgrown front yard.

This sets the stage for our current endeavor. Please note that when I say "our", I really mean "Doc's", because this involves venturing under the house and into some hellish spider haven.

He has decided that we are going to install a network port right in the wall of every deserving room in the house and wire them all to a switch in the crawlspace below, uniting them all with the router in our office. Yes, friends, we are going to have Internet coming out of the fucking wall. Excellent.

After a few days of scattered investigation and purchasing of power tools (which we have hitherto not been manly enough to possess), he tonight began the arduous task of drilling holes in everything until some of them line up well enough to feed a cable through.

I have constructed a convenient diagram illustrating the progress made thusfar.

I am glad to report that there has only been one hole made in the floor, after Doc mistook it for the inside of a wall. This was swiftly corrected, and now we proudly sport a cat-5 port in the room that already has the router in it. It is in fact possible for us to get online on a laptop with no wireless card from within the crawlspace. Technology never ceases to amaze.

Twitterpating Season
fluffy
[info]eevee
Twitter sucks.

Sorry. I've been using it for longer than I think most of you have -- over a year, in fact, which is eons in Internet Time -- so I consider myself an authority. And it sucks now. Maybe it always sucked, but it definitely sucks now.

Unfortunately, Twitter's suck isn't really inherent to Twitter; I'm sure Facebook sucks for the same reasons, but I had sufficient disinterest to avoid that. The next bandwagon everyone jumps to will also suck, because the public makes everything suck. I thought I was too young to care about the Eternal September; apparently not.

Let us examine the type of content that now makes up Twitter.

Spam.


Easy target, I know.

Anything that gets popular gets spammed, and we don't have any good way to prevent this yet. Twitter does a decent job of blocking spammers quickly, but only after they've already tricked dozens of people into actively looking at the follower's tweets. Worse, because URL shortening is enforced (rather than, I don't know, some age-old technology like a label), I have no idea what the links in someone's tweets are and it becomes all the harder to tell at a glance what's spam and what's someone trying to run a classic link-and-comment blog in 140 characters.

Then there's "legitimate" spam, where real people hock their real site and mass-follow people to get more eyes on their crap. Except I don't think you can get banned for this one.

And then there's metaspam, where people mass-follow in an attempt to sell their Twitter mass-follower thing. I got followed by a guy who was actually trying to popularize his pyramid scheme Twitter following app. Basically you give him your username and password, and his app will follow the last five people who used it (plus him) on your account. Then you're part of the list, so the next five people to use it will follow you, and you get some stranger who probably doesn't care about anything you say automatically reading it anyway. Awesome! I'm so glad communication has been reduced to quantity over quality.

People who don't know how to use RSS.


This is getting really dumb, and I am ashamed that I am participating.

There are a whole bunch of Twitter accounts that serve no purpose except to stream an RSS feed. There's even a site devoted to setting one of these up with minimal effort. (Which I used. Yes, yes, shame etc.) Well, okay, that's fine, I guess. A newsreader takes at least 20 seconds to set up, and is only about six hundred times more functional, so why not stick feeds in Twitter?

But a lot of people with both a Twitter and a blog will post the contents of each to the other.

So if I follow both of these accounts—as I imagine most people will do—I'm reading everything twice. Twitter is cluttered with tiny announcements of new posts I will already read later. My friends page is cluttered with lists of offhand thoughts I've already seen multiple times that usually don't tell me anything interesting or useful.

Why are we doing this? RSS is an incredible tool, and yet we are preferring the copy-paste approach. Here, try it out: go log into Google Reader, add a few feeds from sites you normally check religiously, and enjoy. Firefox even supports adding feeds to Google Reader for you; just click the button in the address bar.

If you're following someone on Twitter but don't use LJ, follow his/her LJ feed. If you have someone friended on LJ but don't use Twitter, hey! There's a feed for that too. There's no good reason to be duplicating all this content (and non-content), especially when it doesn't at all fit the medium it's being copied to. LJ is for writing, Twitter is for.. saying, I guess.

Other people's private—or privater—conversations.


At any given time, two-thirds of my Twitter stream is other people holding a conversation with other other people I don't know. And yet the model encourages this, and with the limits of Twitter profile fields it's difficult to shift a conversation to another medium like IM if I don't already have alternative contact information for someone.

Exacerbating this problem, half the conversations I try to follow are private. So not only do I have halves of conversations mixed in with public messages, but I can't see the other half of many of the conversations even if they do sound interesting.

Things that could have been interesting blog posts.


On multiple occasions, I've caught myself reducing an interesting problem and its eventual solution into two tweets: a complaint and a retraction. I could have written an interesting explanation of what caused the problem and how I solved it and why it worked, thus passing on my experience to anyone else who has a similar problem in the future or is just plain interested. And I have been deliberately trying to only tweet interesting things; even with that, I am still encouraged to dumb down everything I think to fit in a tiny box. I'd hope my thoughts are worth slightly more than that.

Things that couldn't have been interesting blog posts.


I don't care what you had for lunch. Really. Summarize your day in some sort of live journal if you want, and I might take it all in as a continuous narrative, but I don't need real-time updating on the minutia. (This is why I haven't been following most people who follow me, if you are curious.)



So, due to the above, I'm dropping Twitter as yet another thing to check religiously when I'm bored. There is too much more noise than signal. It's great if I'm at an event and need to track where people are right now, but beyond that it is fairly worthless and contains very little that I find I'm glad I read.

I'm going to try to really write more instead and attract real readers to this blog/journal/thing, rather than just discarding potentially interesting thoughts—or flinging them into the ocean of irrelevance that is the latest social networking fad.

Also, em dashes are awesome.


addendum:
I would like to add that the sudden increase in ajaxyness in the Twitter Web app has certainly not helped. It's gone from simple and responsive to nearly unusable. The page takes forever to load, I lose focus the moment it finishes which is annoying if I've already started typing, and the Back button never works any more because heaven fuckin' forbid we actually do page loads any more. Even NoScript cannot seem to save me. Hrrgh ajax.

House
fluffy
[info]eevee
So I bought a house.

Well, we bought a house; doc and I both went half in, since we could both afford the mortgage alone and it seemed the most fair thing to do. So I own half a house, and if some unfortunate accident were to befall doc, I would own another half of a house, and then a few more and I could put down a hotel.

It's a pretty roomy house, with a decent-sized backyard crammed full of trees, a ~hot tub~ included (and it even comes with complimentary dead bees), etc etc. Better is that the house is actually designed for people to live in, unlike the last three goddamned apartments I've been in, so all the cupboards and plumbing and everything is actually built like a reasonable human being might expect instead of having been outsourced to a Chinese child making 20 cents an hour. We have ceiling lights in every room and I have never felt fancier. But best is that there is a Subway six minutes away -- by foot! -- and it has an adjacent strip mall with a grocery store and other such sources of delicious treasures. As I have managed to go five years without actually owning a car, this is mighty convenient for me, and beats the last place's 26-minute distance by at least now-I-don't-have-to-order-pizza-when-we-run-out-of-food percent.

There's also hardwoo-- well, hard flooring. Immediate advantage is that my DDR pad actually stays in place now, which makes me look like I can sorta play. Less immediate advantage is sweeping instead of vacuuming.

I've been playing every night for the past three weeks now, in an effort to be less of a fatass and I guess more Korean. It had started to work back in March, but then I buggered off to visit Mel/PurpleKecleon for a month. Then we started moving and ate a lot of pizza and fast food while we didn't have food around or the patience to make it. So.. little bit behind there. And I am finally noticing that diet soda really does make me very inclined to munch on anything I can find, so I guess that's gotta go. :(

Uhm. Probably gonna have Mel over for a bit in June, then we'll both go to Anthrocon and watch furries together. Fascinating!

And on a complete tangent, I hate my current (work-sponsored, Storm) phone with a burning passion and really want an Android one. I was all geared up to snatch a dev G1, but now I see October will bring a v2 that is rather more streamlined. Still, any opinions on carriers or phones or Android in particular? If you tell me to get an iPhone I will feed you your own shiny white entrails.
Tags: ,

HEY: game developers
fluffy
[info]eevee
Stop making your games run full-screen by default! They are nigh impossible to kill if they fuck up and can leave my gamma screwed if they crash, they change my resolution without asking, they resist attempts to alt-tab away, and they are often too drain-bamaged to even realize that I have two monitors and try futilely to stretch across both. I don't think I've ever appreciated that a game ran full-screen out of the box.

Yeah, yeah, it'll run faster and look prettier if it's full-screen. I don't care. The default option should not be more potentially disastrous than the alternatives. It takes ricers all of two seconds to change to full-screen, and they're going to be mucking about in video options anyway.

Thanks. >:|
Tags:

Windows 7 XPM
fluffy
[info]eevee
First of all, dammit, XPM is an image format.


If you had not heard, to alleviate complaints from corporate customers -- that is, to get companies to buy thousands of copies of Windows 7 for no good reason -- Microsoft has come up with a brilliant backwards-compatibility scheme. The more expensive versions of Windows 7 will be able to download a Windows XP virtual machine and seamlessly run applications within an XP environment, as seen here. Any program that worked in XP but doesn't work in Vista or 7 can be run like this, so all compatibility issues are neatly swept under the VM rug.

Note that this is not the same as the Windows version dropdown in XP, which was a joke and rarely did anything at all. This is actually running a copy of Windows XP inside Windows 7 and showing Windows XP applications alongside Windows 7 ones.

I have heard this billed as "Windows 7 now fully compatible with Windows XP programs". Well, if that's how we're going to play it, then OS X is also fully compatible with Windows XP programs. It's called Parallels. Or VMware, which can also do this for Linux. All Microsoft is doing is giving away a free image of an eight-year-old OS to people who already paid double what the new one is worth.

Slashdot has also picked up on this and raises two complaints: for one, the XP environment is an entire new operating system, so it should have a second antivirus package installed. For another, unless this mode is promised to go away at some point, there is no real incentive for anyone to update applications to work with 7 and further. I doubt that will be a huge issue, but there will always be a few companies that drag their feet and don't update anything.


But there is a potentially deeper problem here.

Windows is infamous for dragging around a lot of legacy cruft for backwards compatibility reasons. There have been (to my memory) two major times when Microsoft has lost some compatibility with the last version: 2000/XP and Vista. Both of these were fairly minor cleanups; unless a program was doing something really wacky or was truly ancient, if it worked with the last version, it should work with the new one.

And that's exactly the problem. You can only really play the VM card once. (Well, alright, maybe once a decade.)

Apple did it for the transition to OS X, which was an unimaginably huge change.

Microsoft did it for the transition to 7, which is shinier than XP.

What happens if they want to do a real overhaul with Windows 8? Maybe not a rewrite from scratch against a UNIX kernel like Apple did, but at least something meaningful? Are we going to have one VM for XP, one VM for Vista/7, and then 8 applications run natively?

I'm sure to nerds this sounds reasonable, but think how this will look to most people. Okay, for OS X we have "just run this" or "run as Classic Mac". A program is either "old" or "new". In Windows 7, the same thing applies, albeit already without a useful moniker: a program is "old" or "new", and "just runs" or "runs in old Windows". What if there are two VMs? "old", "older", "new"? "old", "kinda old", "new"? "just runs", "runs in old Windows", "runs in other old Windows"?

It's the same chilling trend that IE8's "Emulate IE7" button hinted at. When is it okay to drop seamless backwards compatibility and just outright pretend to be the old system? IE8 still isn't perfect; will IE9 further improve and thus have a second Emulate IE8 button? What are the criteria here for needing a button to emulate an old version, and how many different sets of versions can we honestly expect users to remember? (Note that all major Web browsers already have an old version emulation built in: it's called quirks mode, where the browser tries to act like Netscape 4. Yes, Netscape 4.)

I suppose this is intended for corporate customers, so maybe they could just pretend the XP machine doesn't exist when releasing the hypothetical Windows RGE (Really Good Edition) and its seamless Win7 VM. But corporate is where most of the bulk comes from, and mediocre IT staff isn't going to be much better at screwing around with this. They blew this wad too early.

Ubuntu 9.04: Jaunty Jackalope
fluffy
[info]eevee
After a painful wait of like five hours to download it all -- which I guess is a good sign, as it implies popularity -- I am finally running Jaunty. I've only been on it a couple hours, but here is my impression so far.

notify-osd
Ah, the big one people are getting all uppity about. The introduction of notify-osd has had three main effects:

1. Simple notifications are simpler. By "simple", I mean they just tell me something and don't (or usually won't) require interaction. These are now more like OS X's Growl: simple bubbles, appearing long enough to be read and then fading away. This is pretty cool, and I approve.

2. Complex notifications aren't notifications. I haven't actually run across any of these, but everything I've read indicates that any existing notification that reasonably expected input is now a pop-under (or worse) dialog. Let me be extremely clear about this: that fucking sucks. I don't like dialogs, especially from applications I'm not currently using. Hell, between the pop-under-ness and having multiple desktops, sometimes I don't notice them at all for a while. But there is hope...

3. There's a panel menu for stuff that wants my attention. This is an interesting step, as it starts to separate "here is something you might want to know" from "HEY BRO LOOK OVER HERE". I seem to have dicked it a bit up by accidentally adding a second one to my panel, but it puts (2) in an interesting new light. I think it's supposed to list Pidgin contacts who've said something to me that I haven't read, but this doesn't seem to work for me. Maybe because I dicked it up. Hm.

I hope Ubuntu is going in the direction I think it is. I like that notifications are being treated as quick simple tidbits I can afford to miss that get the hell out of my way, but applications that want attention sorely need a way to indicate that. This was previously done by having a notification bubble that pointed to the application in question and/or having buttons, but that has been abruptly removed and replaced with what I dearly hope is a stopgap measure. The update manager, for example, used to show a notification announcing new packages; now the whole window just spawns in the background. I'd really rather be alerted that something could need doing so I can damn well do it myself. If we need a richer method for this sort of announcement than tray icons and notification-daemon, that's fine, but just up and spawning windows probably isn't it.

Really, my ultimate goal is to not need a window list in my panel at all. A list of Important Things is moving in that direction.

I do have two more immediate complaints:
- Notifications from the same source seem to queue, rather than stack. So if I mash next-song a few times, I get each song's notification displaying in order for five seconds at a time. It can take me two seconds to skip forward six times, but it will take half a minute to show all those notifications. Eugh. Not sure if this is a problem with quod libet or the notification system.

- According to this comment, the bubbles are designed to show below a tray panel applet on a top panel. Well, I only have a single panel, on the bottom. But that's okay! The default is to show them at the upper right of the desktop. Except I have two monitors, and I use the secondary one largely to hold IRC or a fullscreen terminal, and I'm more often on the primary monitor working with Firefox. Thus all of my notification bubbles are spawning on a monitor I'm not looking at, with black backgrounds, atop a black terminal. So I rarely see them at all. And, of course, in grand Gnome style, there are no options for selecting where to put them, unlike the old notification-daemon.


Compiz
The config dialog is finally actually organized; no more miscellaneous category, and everything seems to be where I expect.
Seems a bit more stable so far.
Switching desktops only animates sliding the windows, rather than the entire desktop. I like the effect.
Finally fixed a bug that snuck into Intrepid and drove me crazy: the Exposé plugin (Scale) takes a keybinding, but it was apparently broken to assume that the key being held down is a modifier. What I wanted, and what Hardy did, is to press a key to get Exposé, and then press it again or hit Esc to abort. That way I can type (to filter by window title) without having to hold down anything, which is mighty convenient. Now that this is fixed, I might actually start using it.
I think my set-zoom-to-100% keybinding has been undone for some reason. Maybe the zoom options were shuffled around.
My second monitor blinks black for a second and then redraws completely on occasion. Half the time this happens when my highlight is set off in Irssi. Not sure what's going on there.
The Application Switcher plugin started zooming out the desktop by a small margin while I was alt-tabbing. Maybe this is a new option and that's just the default. Trivial to fix: set Zoom to 0.
Don't seem to be any new revolutionary plugins; I see a Grid (with no icon!) window arranger thing, but like many window arranger plugins I can't be buggered to figure out how to use it.


Appearance
As distinct from Compiz! For some reason.
On first boot, my font rendering was a bit weird; monospace (DejaVu Mono Sans) was noticeably smaller vertically at the same font size. I was using subpixel smoothing in Intrepid, and Jaunty switched me to... well, I'm not really sure. Neither was the Fonts dialog; all four rendering options had indeterminate checkboxes. Whatever. Switched it back and all is well.
I like that Dust was included -- I've been using it for a while and it's a great theme. Good dark themes are extremely hard to find. Most of them make everything dark, when what I really want is to have window borders and the panel dark with everything else medium-light so I can easily ignore chrome. Same reason I use the ADD Helper Compiz plugin, so every inactive window is dimmed.
The System Monitor panel applet now uses yellow for network activity. Cool; it wasn't very distinct from CPU usage as cyan.


Gnome Do
Huzzah! The Twitter plugin recognizes my password. 0.8, the latest version in Intrepid, didn't like my password at all for whatever reason.
As usual, a Do upgrade means that all my plugins are disabled and all the adaptive learning is reset. Even though it was an upgrade from 0.8 to 0.8.3. I will never understand this.


Evolution
I've used Thunderbird for email for years now, but I started up Evolution to try out that "hay listen" panel button, and it is now my default email client. It sucks less resources than Thunderbird, the options dialogs are far richer and easier to navigate, and most importantly, it's native. Native widgets, correct theme colors, and native notifications. Good lord, Thunderbird 2's widget drawing has been annoying me for ages. I've tried the beta for 3, but it's not built against Ubuntu's Cairo so the font rendering sucks, and honestly it doesn't seem much different from 2 besides the Gecko upgrade.


screen
screen now has a two-line toolbar at the bottom by default. One is a window list; the other is a little status bar with a quick overview of resource usage and the current time. There's also a semi-graphical menu available with F9. This is pretty damn cool, except that I really only use screen on tekkanin for holding Irssi. As in, just Irssi. This makes a status bar a little ridiculous. I might upgrade veekun's machine just for this sometime, though, and I would love to somehow get it on $work's dev machines with minimal fuss.


NetworkManager
Uggggh. When I first booted, connecting to $work's VPN completely disabled any non-work connections; everything was being routed through their network, which doesn't take kindly to VPNers trying to use Google. Turns out there's a checkbox I had to check in Configure > IPv4 Settings > Routes... entitled 'Use this connection only for resources on its network'. I don't know if this was in Intrepid or if it's new in Jaunty with a default that doesn't work for me, but it sure freaked me out for a few minutes.


OpenOffice.org 3
I honestly use OO.o very very rarely; sometimes I get a spreadsheet from $work and need to look at it, but that's about it. But since everyone has been bitching that OO.o 3 was hard to get in Intrepid, I gave it a spin. Seems to respect my theme a little better, but other than that I don't see what the big deal is. Whatever; don't listen to me about office software.


I also had tracker complain constantly that the index was corrupted. Got it to reindex everything after a few attempts.

I guess that's everything that's stood out to me so far. Overall, only minor hassles with the upgrade, and I'm generally pleased. I've seen claims that Jaunty is super-snappy in general now, and I guess it feels pretty quick, but I didn't notice many delays before (save for e.g. when video drivers fucked up) so I can't speak to that. Also can't comment on boot time: I've only booted it once and it dicked around for a bit configuring kernel modules. I suppose if you're intensely fascinated, you can install it yourself and see.

Regarding this Amazon moral outrage
fluffy
[info]eevee
Trying to stop this before it gets any further. Like there's any further to go!

http://community.livejournal.com/brutal_honesty/3168992.html
mirror: http://j.wuffgirl.com/amazonfailexplained.txt

You have been metatrolled.

Amazon didn't do anything. One person grabbed the list of every gay/lesbian book on Amazon and repeatedly used the 'report as offensive' link across a ton of accounts to make Amazon think every single one was an adult product.

On Ferrox
matrix vee
[info]eevee
I am torn.

On the one hand, I would like to finish this project. I have a habit of working on something until it ceases to hold my immediate attention and then starting something else. Not to say this is inherently a bad thing, but it would be nice to have something to point to and say I did that.

And I really want to see FA improved; the furry community deserves a decent meeting place, and what they have now is a rusting bucket of bolts.


But.

Well, for starters, there are far more people making jokes about Ferrox never coming out than actually showing legitimate interest in it. I'm trading my spare time for absolutely nothing, and I'm coming to dread working on this thing or even thinking about it. Large necessary features still don't exist because I just never want to waste that many hours on grunt work for people who don't much care either way.

But far more of a problem is that I fundamentally disagree with the administration on a lot of things.

I don't think the community should be babysat; posting a journal saying someone else is a dickhead is not "harassment" and should not warrant moderation.

I don't think galleries should be filled with cruft like vanity photos or voice memes, whether or not they are delegated to scraps. Community aspects should not degrade the art side.

I don't think there should be a witch-hunt over preventing 17-year-olds from seeing crudely-drawn penises, based entirely on legal grounds nobody can cite that I'm not sure exist.

I don't think users should be locked out of their accounts with no warning for being on a password list some of them didn't know existed and then mocked for it.

I don't really like the general tendency to moderate arbitrarily, with no clear goal for either the moderation or the site itself.

The "rest" of the staff gives the strong impression that they would prefer I shut up and go back to code monkeying. Far between are the times someone agrees with me. I have no power and no influence. I'm not sure how that qualifies as 'staff'.

Every time I sit down to work on Ferrox, I wonder why I am helping to provide a product that I know will be used to advance practices I strongly disagree with. I wonder why I am wasting my time on users who will cheerfully get snarky with me and accuse me of reshaping FA in my image because I don't want to implement a backwards feature that I think is fundamentally a bad idea. Many people close to me wonder the same and have told me I should just bail; I don't have very good excuses to give them.

I got on board for two reasons: to learn Python and to fix FA. I've done the former, and I'm not entirely convinced the latter is possible.



addendum: finally passed journal id 300,000 woo B)

Why Python?
fluffy
[info]eevee
Veekun is written in Perl. It has always been written in Perl, since it was an early Perl 5 CGI app at the end of the century. So it's only natural that several people have asked why I'm using Python for the current rewrite.

Really, it's nothing about the languages themselves; I like Perl, and I like Python. The problems arise with the tools.

I like Mako way more than Template Toolkit.


Compare.

TT:
<ul>
[% FOR foo IN foos %]
    <li>[% foo %]</li>
[% END %]
</ul>


Mako:
<ul>
    % for foo in foos:
    <li>${foo}</li>
    % endfor
</ul>


Template Toolkit is a whole new language that tries to emulate features of Perl it likes and fix features it doesn't like, turning everything into a semi-object and hiding the differences between data types. This is okay in most cases, but:
- Some of the syntax is vaguely-defined, so it can be unclear how a common construct like foo(key => value) will map to actual Perl code. I could look into all these things, but I'd rather not have to care.
- TT tries to abstract away the difference between arrays and arrayrefs, which falls apart when trying to interact with non-trivial Perl code that specifically wants one over the other.
- Support for repeatable included blocks of template (aka "subroutines") has always felt woefully flaky to me. There aren't even parameter lists; passed-in params are just dumped into the namespace.

Mako, on the other hand, is all just direct simple mappings to Python with a handful of different delimiters. It feels a lot more like I'm just wiping away a lot of print statements, rather than writing in an entirely different language.

There are alternatives to TT, of course, but I have yet to see anything that feels quite as natural as Mako.

Native Pokedex, someday


I have made minor headway into creating a wxPython downloadable Pokedex in the past, and would still like to finish it someday. This is far easier if the Pokedex code, ORM definitions, libraries, etc. are all written in Python already. I can't very well go the other direction: wxPerl was embarrassingly incomplete last time I had a look, and there is just no good Perl equivalent to py2exe.

setuptools and pkg_resources


setuptools makes it absolutely trivial to write a setup script for a package and define entry points, which is incredibly useful with Spline's attempted plugin system. pkg_resources lets me bundle Pokedex data, sprites, etc along with the code.

Perl doesn't really have equivalents. There's Module::Pluggable, but that feels very low-level and seems far more intended for simple one-class plugins for a framework or other library.


I guess it comes down to: I want to write an application and make it distributable. Perl doesn't really lend itself so well to this; all of its tools are built for libraries or console applications for machines that already have Perl installed.

Sorry Perl! I still love you, but I think we should see other languages :(

Firefox 3.1 is a pretty cool guy
fluffy
[info]eevee
eh has CSS transforms and doesn't afraid of anything

vertical text demo

To be fair, WebKit already had this. But who cares, it's cool.

No images, no Flash, no JavaScript, no inline SVG. Just one line of CSS: -moz-transform: rotate(-90deg);. Copy/paste and change moz to webkit, and it'll work in WebKit browsers too.

I hate to see cool new features implemented by Gecko/WebKit go unused, so I sneak them in whenever I get the chance. border-radius, inline-block, rgba and opacity, etc. Also, I abuse the crap out of outline when developing. Still looking for an excuse to use <canvas> for something.

There is some wackiness here because the entire header cell is rotated, not just the text. That is, if I threw an outline on one of them, it would extend past the left/right of the visible cell and not reach the top/bottom. Doesn't seem to have any effect on rendering; I assume layout ignores transforms entirely, so this is just a display thing. But this means that the cell width is calculated before the rotation, so it's currently as wide as the widest of the text there, even though none of it actually spans the cell horizontally. The cells have just as much padding as the 'Platinum' header up top, and you can see that that's very close to the bottom border, whereas the vertical headers have plenty of space around them. Not sure if there's any real solution for this, besides maybe trying to force the cell width to 2em.

Could also pose a problem when I actually style the table, if I give headers borders or backgrounds; might have to use a wrapper for just the text, which kinda sucks.
Tags: , , ,

History of Veekun
fluffy
[info]eevee
I'm still banging away on spline-pokedex, which is now at least minimally functional. But I think this is going to bring me to the fifth or sixth generation of this same Pokedex. It wasn't always on veekun.com; the same project has existed for years, almost a decade now. I've explained to several people how the various incarnations are good landmarks for how I've gotten better at programming, so I might as well write it down somewhere more permanent.


The very first edition existed somewhere around the time Yellow came out. Wikipedia tells me this was late 1999, which sounds about right. It was a CGI program running against Apache on my computer, spitting out the same data every time. The data was in one giant text file, formatted something like this:
Bulbasaur
grass/poison
2'4"
15.2

...and so on for some 30 lines, then immediately followed by the same for Ivysaur, and so forth. The move lists were crammed into one line and split up as necessary, and TM compatibility was a string of 55 digits; 0 for no, 1 for yes.

The data was pretty much entirely copied from the Prima Red/Blue guide, as it was all I had, and I wasn't yet aware that other resources even existed (or that Prima was awful). People still find errors in my Red/Blue data because of this.

This version was never made public.

The background was the Red/Blue ground texture, except the little sandy pixels were transparent, and behind it was a color corresponding to the Pokemon's primary type (for my own definition of "primary", where main elements like fire and water overrode bland attributes like flying and normal). It actually didn't look too bad, for 90s web design.


At some point, this giant data file was split into multiple data files; one file per "column", one Pokemon per line. A single request would open all the files, slurp them all into arrays, pick the rows it needed, and spit out a page. Gorgeous, I know.


By the time Gold and Silver rolled around, I had significantly upgraded: someone had convinced me to use XML because it was all new and cool. Since it took ages to actually generate anything (still CGI, and now I had to parse some hundred-kilobyte XML file), I had to create the pages statically and then upload them all to the way cool server my friend let me use.

I had also upgraded to copy/pasting data from other Pokedexes, painstakingly, one page at a time. I had not yet even heard of screen scraping.

The design has been lost to the sands of time, but it was black with 2px borders the same color as the Pokemon's primary type. TMs were in this 10x5 grid, and their type colors would become their background on hover. It was some classic minimal web design as done by someone who doesn't know anything about web design in 2002.


I think this was around the time I wrote a miniature dex, which was a tiny popup window with a small tabbed Pokedex in it. I don't remember what the point was or what happened to it. The tabs, of course, were colored by type. I think that was the last time I clung to my precious type colors.


The Ruby and Sapphire era brought about all sorts of revolutionary changes. I had a new friend-with-a-server who gave me a whole subdomain, a radical improvement over the mere /alex I'd had before. Even better, I now knew how to use databases. I had read a book and everything. Armed with my glorious new knowledge of MySQL, I imported all my XML into tables -- tables that had columns like 'moves' containing data like 01-136|01-009|05-062... because I didn't know anything about normalization or joins. (Fun fact: some remnants of this crap plague veekun to this day.) The Perl scripts were now in reusable pieces, but rather than use any of the modules I didn't know about, I just had tons of includes and printed HTML and so forth. It all ran under mod_perl as registry scripts.

You can even see this faggotry. (I like to think my design skills have improved at least slightly since this.)

My data scraping had vastly improved, too: I could now rip whatever I needed from GameFAQs, which so conveniently provided long easily-parsable lists. Except when it was full of typos, which people still occasionally point out.


Along the line, I got my own domain, and could finally say I had a real web site. Check THIS horrible sense of color out: 2005, 2007


Diamond and Pearl, of course, really made veekun. I had a domain, I had almost a clue what I was doing, I was using templates and multiple tables and joins and all sorts of things. I was even parsing data out of the game image directly, and helped decode the sprites. I had made it. Now people are actually using this thing. Cool.


And now I'm trying to break it all into separate small projects and rewrite it all in Python, because it once again feels like it's full of legacy cruft. Sweet smell of progress..?

Good learning experience though.

fuck yeah finally
fluffy
[info]eevee
we have liftoff

eevee@tekkanin:~/dev/porigon-z$ porigon-z pkmn-platinum.nds cat /poketool/pokegra/pokegra.narc | xxd | head
0000000: 4e41 5243 feff 0001 74ba b300 1000 0300  NARC....t.......
0000010: 4254 4146 ac5c 0000 940b 0000 0000 0000  BTAF.\..........
0000020: 3019 0000 3019 0000 6032 0000 6032 0000  0...0...`2..`2..
0000030: 904b 0000 904b 0000 c064 0000 c064 0000  .K...K...d...d..
0000040: 0865 0000 0865 0000 5065 0000 5065 0000  .e...e..Pe..Pe..
Tags:

porigon-z
fluffy
[info]eevee
We have liftoff.

output )

I think this is a slight improvement over the very stunted list of files I was getting yesterday.

Almost ready for git.

rom hackin'
fluffy
[info]eevee
I still have the code from when I was ripping things from the D/P images, after the games first came out in Japan. My process involved breaking up the image with narctool and piping several files through two or three badly-named and undocumented scripts all dumped in a folder. I could barely keep track of it all at the time and certainly can't now.

With the advent of Platinum, I find myself again needing to rip from these games, and figure I'll try to do a better job of it this time:

>>> from porigonz.dppt import DSImage
>>> pt = DSImage('pkmn-platinum.nds')
>>> print pt.banner.title_jp
ポケットモンスター
プラチナ
Nintendo


Poketto Monsutaa Purachina!

This is hard. :( I'm trying to extract files based entirely on the lovely C code of a project I can't seem to actually compile. Fun times.

Will throw this on git once I can at least get files listed correctly. Right now I have a bunch of filenames but can't figure out how to assemble them into a tree.

Eevee has gained 1387 experience points!
fluffy
[info]eevee
doo dodo DOO

EEVEE has grown to level 14 22!

Strength: +3
Perception: +14
Endurance: +4
Charisma: +12
Intellect: +82
Agility: +1
Luck: +93


I'm a bit late, but I didn't really make a big deal of it this year. No party mode; no mass of gift art; no announcement beforehand or much else really. Oh, well. Doc got me a bunch of Magic cards. And this.

What did I do this year? It's a bit fuzzy at the moment. I got glasses, woo?
Tags: