czottmann:
[via]
The latter feels surprisingly like my work life at this point.
Today's Document
The Bowery Presents
almost home
noise dept.
cherry valley forever
Mike Driver
taylor price

Jar Jar Binks Fan Club
let's talk about Bridgerton tea, my ask is open
YOU ARE THE REASON
d e v o n

if i look back, i am lost

Kiana Khansmith

PR's Tumblrdome
No title available

No title available
TMBGareOK. The Official They Might Be Giants tumblr

No title available

oozey mess

Product Placement

seen from United States

seen from United States

seen from China

seen from Germany
seen from Netherlands

seen from United States
seen from Singapore

seen from United States
seen from Bangladesh

seen from United States

seen from Malaysia

seen from Canada
seen from Canada

seen from Colombia
seen from Türkiye

seen from Philippines

seen from Kenya
seen from France
seen from Germany

seen from Malaysia
@mikewest-blog
czottmann:
[via]
The latter feels surprisingly like my work life at this point.
Mnot's Redbot
[Mark Nottingham][mnot] has put together a really useful tool that aids in the analysis of the behavior of HTTP resources. Visit [http://redbot.org/][redbot], type in a web address, and Redbot will report the resource's cachability based on the returned headers, and provide a helpful list of recommendations for improvement. Running it on [http://mikewest.org/][mike], for instance, [flags the fact][redbotme] that I compress the response if the browser tells me that it can accept compressed content, but that I've neglected to send the proper `Vary` header to let caches know that the response needs to be negotiated, and cached based on the `Accept-Encoding` request header. This is _useful_, especially for _actual_ applications for which it might matter. So useful, in fact, that I'm forking it to submit some patches. Mark's put the Redbot code up on GitHub ([mnot/redbot][github]), and I've started putting together a [command line version][cli] based on the web version he's built. I've mentioned that [I love GitHub][heart], right? This is exactly why. :) [mnot]: http://www.mnot.net/ [redbot]: http://redbot.org/ [mike]: http://mikewest.org/ [github]: http://github.com/mnot/redbot/tree/master [redbotme]: http://redbot.org/?uri=http%3A%2F%2Fwww.mikewest.org%2F [heart]: http://mikewest.org/2008/11/i-love-github [cli]: http://github.com/mikewest/redbot/blob/master/src/redbotcli.py
Nice afternoon grilling with friends, but it's starting to look like rain...
Playing with Placemaker
Yahoo's latest API is really quite cool: [Placemaker][] takes your unstructured data (e.g. any HTML page, RSS feed, etc), and extracts a nice list of _locations_ that your data refers to. It's a brilliant tool, and I can think of quite a few ways I'd like to use it in the future. Along with their release of a _ton_ of [WhereOnEarth ID codes][woe] that allows you to make use of Yahoo's various geo-services, this is a really good day to play with geocoding unstructured data. So, let's play: Accessing Placemaker is simple: assuming that you've somehow managed to [obtain an application id][appid], you simply make an HTTP `POST` request to Yahoo!'s Placemaker endpoint with a tiny bit of data specifying the nature of the data you're dealing with, and it's URL. If you like `curl` on the command line, this might look like: curl -d 'inputLanguage=en-US&documentType=text/html&documentURL=http://mikewest.org/&appid=[APPID]' http://wherein.yahooapis.com/v1/document You'll get back an XML document (RSS is also available as a response format). Digging into the contents yields: * Boilerplate: 0.380778 build 090508 15906 * A (list of) document element(s) containing the extracted locations: * A best guess at the document's "scope" (the smallest region that "best describes" the document): 20071093 County <![CDATA[Munich, Bavaria, DE]]> 48.1549 11.5417 29388625 MMA <![CDATA[MMA München, Bavaria, DE]]> 48.1549 11.5417 * Latitude/longitude for a bounding box that contains the places mentioned in the document (which makes it trivial to draw an "area of discussion" on a map): 48.1364 11.5775 48.0417 11.3771 48.2292 11.749 * Detailed breakdown of the places mentioned in your document, giving you lat/long coordinates identifying the place's center point. Moreover, it tells you _where_ in your document the place was found (string offsets _and_ XPath expressions, to each their own). This is helpful for those occasions when the text you've entered doesn't exactly match the place's name that Yahoo returns ("Munich" vs. "Munich, Bavaria, DE", in this example) Annotating your documents with this data should be a piece of cake. 676757 Town <![CDATA[Munich, Bavaria, DE]]> 48.1364 11.5775 0 1 7 676757 50 56 0 <![CDATA[Munich]]> xpathwithcounts <![CDATA[/html[1]/body[1]/div[2]/div[1]/p[1]]]> * And some more boilerplate. :) Full documentation of the Placemaker [query parameters][query] and [response format][response] are available on YDN. Christian has put together a demo of a [basic PHP implementation][php] (though it's XSSable, and shouldn't ever be used in production). In general, this is _brilliant_ stuff. I'm looking forward to playing with it! [Placemaker]: http://developer.yahoo.com/geo/placemaker/guide/ [woe]: http://developer.yahoo.com/geo/geoplanet/data/ [appid]: http://developer.yahoo.com/wsregapp/ [query]: http://developer.yahoo.com/geo/placemaker/guide/api_docs.html#query_parameters [response]: http://developer.yahoo.com/geo/placemaker/guide/api-reference.html [php]: http://isithackday.com/hacks/placemaker/
Jetpack looks like a huge improvement over the current plugin/extension structure that Firefox provides. It's building on the basics of HTML, JavaScript, and CSS, and the development cycle looks _much_ cleaner than the build, restart, build, restart, build, etc. that anyone who's tried to build an extension is familiar with. Nice work!
Well. That was easy.
Getting [JSLint running inside Spidermonkey][that] was much simpler than I expected it to be: [14:12] src/jslint $ python Python 2.6.2 (release26-maint, Apr 19 2009, 01:58:18) [GCC 4.3.3] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import spidermonkey >>> rt = spidermonkey.Runtime() >>> cx = rt.new_context() >>> text = file( './fulljslint.js' ).read() >>> cx.execute( text ) u'use strict' >>> cx.execute( text + 'JSLINT("i++", {})' ) False >>> cx.execute( text + 'JSLINT("i++", {}); JSLINT.report();' ) u'
Error:
Implied global: i 1
Problem at line 1 character 4: Missing semicolon.
i++
No new global variables introduced.
' Yay! [that]: http://blog.mikewest.org/post/108613427/running-python-spidermonkey-on-jeos
Running `python-spidermonkey` on JeOS
Paul Davis' [`python-spidermonkey`][ps] project looks brilliant. In a nutshell, he's building a Python bridge to Mozilla's [SpiderMonkey][] "JavaScript on C" environment. I'm excited about that, because it means I might be able to put together a headless testing environment without trying to make everything work correctly inside Rhino. Hooray for options! I ran into a snag or two while getting up and running on JeOS (my [dev environment of choice][brad]), so I'm documenting the process here. [brad]: http://intranation.com/entries/2009/03/development-virtual-machines-os-x-using-vmware-and/ [SpiderMonkey]: http://www.mozilla.org/js/spidermonkey/ [ps]: http://github.com/davisp/python-spidermonkey/tree/master 1. Install python headers and `pkg-config`. Forgetting to install `pgk-config` will give you some exciting errors in the compilation phase later on that make it sound like NSPR failed to install correctly. If you're on JeOS, it's more likely the case that you don't have `pkg-config` at all: sudo apt-get install python2.6-dev pkg-config 2. Install netscape portable runtime: sudo apt-get install libnspr4-dev 3. Pull down python-spidermonkey mkdir -p ~/src cd ~/src git clone git://github.com/davisp/python-spidermonkey.gitnsp 4. Build `python-spidermonkey` cd ~/src/python-spidermonkey python setup.py build 5. Test `python-spidermonkey`: Actually, __don't__ do this. [One of the tests fails on JeOS][fail], and it fails in a way that sucks up all your resources and leaves you in an infinite loop. Yay! [fail]: http://davisp.lighthouseapp.com/projects/26898-python-spidermonkey/tickets/15-test_exceed_time-fails-on-jeos 6. Install: Even though the max time test fails (spectacularly), the bridge seems to work pretty well. Install the package anyway, just don't rely on being able to set a max execution time on your code. :) sudo python setup.py install Now, to see about getting [JSLint][] running in this environment... Fun! [JSLint]: http://jslint.com/
Ex-Yahoo! Monthly Meeting...
YUI3 is starting to look pretty interesting. Satyen Desai's presentation goes over the design of the library, talking in detail about how it differs from YUI2, and _why_ they made the decisions they made. I didn't get a chance to play with this new iteration while I was still at Y!, but I'm looking forward to trying it out in the relatively near future. jQuery is nice, but it doesn't really feel like I'm writing JavaScript; I'm writing jQueryScript instead... YUI2 was _JavaScript_, with a normalizing layer that you could bring in when you needed it. I'm hoping YUI3 will have the terse expressiveness of jQuery's syntactic sugar, while continuing to be JavaScripty in one way or another...
It's raining outside, but it's nice here inside Augustinerkeller. Beer!
A quick note to Tumblr staff: it might make sense to exclude relatively new Tumblogs from your Tumblarity measurements. It's not exactly inspiring to know that the writing I've done over the last week or so has made me the _least popular_ Tumblr in all of Germany. :)
Another good caching resource for visual learners is Gregg Pollack's "Advanced HTTP Caching" screencast. He goes into a bit more depth with regard to the mechanics of reverse proxy caches (e.g. Varnish or Squid), and why you should be smacking yourself for not running one yet. He's coming from a Rails point of view, so the code snippets might not make sense to you, but the _concepts_ are completely language/framework agnostic. You can even do this stuff in PHP apps. :) The only point of this presentation that I disagree with is Gregg's conclusion. HTTP caching with a reverse proxy isn't a last-resort kind of thing that you should only think about when you're expecting millions of hits and after you've fixed everything else in your system. It's something that you should be thinking about up front, as it's probably the single best way to scale your site, especially if your site is more read-oriented than write. If you're not caching from the get-go, you're wasting server capacity, which is going to cost you time and money down the road.
Ryan Tomayko has put together a great presentation outlining the very basics of HTTP caching. The diagrams are perfect, and explain exactly how simple `Cache-Control` headers work, and how they become even more powerful in conjunction with ETags. There's nothing in this presentation that's not in his older essay "[Things Caches Do][tcd]", but it's worth sifting through if you need a refresher. [tcd]: http://tomayko.com/writings/things-caches-do
Running sushi FTW. There's a decent place up the street from where I live, where I seem to end up on Monday nights after work. Elisabeth is out with her folk-dancing group, and I get to spend some quality time with uncooked fish. We've divided up the entertainment perfectly. :)
The Value of Measurement
While I agree fully with many of the conclusions Lukas Mathis draws in an [excellent essay on the recent Google/Douglas Bowman split][mtui], a few bits deserve further study. Lukas hits the central problem squarely on the head in his [footnoted claim][fn] that measurement isn't Google's problem, rather the lack of a design team capable of _balancing_ those measurements against other concerns. I'd elaborate on this claim, and argue that the _kind_ of testing being discussed matters. In general, engineers understand and can relate well to automated A/B testing, and designers understand and can relate well to more personal usability testing. The two are, however, not the same, don't provide the same data, and ought not be conflated. [fn]: http://ignorethecode.net/blog/2009/05/10/measuring-the-user-interface/#fn:google [mtui]: http://ignorethecode.net/blog/2009/05/10/measuring-the-user-interface/ "Lukas Mathis: 'Measuring the User Interface'" ### What do A/B tests test? ### "41 shades of blue" has become a catchphrase for those who see Google's approach as flawed; this seemingly mindless insistence on A/B testing as the sole arbiter of a design's "value" seems to me to be the point Bowman most objected to. I have a good amount of sympathy for that viewpoint. A/B testing is, as Lukas rightly points out, hugely valuable to any team focused on improving an established system through a series of small, iterative changes. Serving a green button in place of a red button to 1% of your users, and discovering a statistically meaningful shift in usage patterns distinctly tells you something about your audience that no amount of surveying could. Ignoring these user's _claims_ while carefully observing their _behavior_ can reveal interesting and useful bits of data about the way they interact with the interfaces you've built. Especially with an audience the size of Google's, you'd have to be crazy to write off the value of building small changes incrementally, and testing those piecemeal improvements against a subset of your audience. You'll discover that one small tweak or another has an impact, and feed that back into your design process. Continually testing each iteration of tweaks against your audience will continually improve the quality of your pages and the overall user experience: It's a virtuous circle of exactly the kind I'd like to encourage. I absolutely stand behind the core of Lukas' essay: "Design is not held back by data, design is refined and perfected by data." ### The Downside ### A/B testing is appealing because it's obvious. It's absolutely clear what needs to be done, the results are generally clear in the direction they lead (it's either "A" or "B"), and if you have the tooling in place to make it easy (Google does), it's easy to see how it can become a central part of the way you work. That said, you'd be just as crazy to make _every_ decision dependent on this sort of testing. In order to isolate the effect of a change, as a true engineer-statistician ought demand, broad and sweeping suggestions should be broken down into testable components, and each served across a just-wide-enough swath of audience to return meaningful data while minimizing risk. An insistance on A/B measurement of each change, no matter how small, means that _everything_ you measure will be "trivial" in the way that the most glaring examples of "Googlism" have been: shades of colour, or widths of border. Only _trivial_ changes are _testable_ changes, everything else is fraught with layers of uncertainty: "Was it the new 3px border, or the new position of the button, or the completely new logo that drove traffic?" "Who knows, let's do more tests!" Moreover, it's easy to see how a reliance on A/B testing might lead to a culture of extreme risk-aversion. When you have a ton of data at your fingertips that help guide your decisions, your worst enemy is the black hole that a new untested/untestable/unmeasured change represents. If a change isn't testable/tested, it's unknown. Unknown changes might be catastrophic. Catastrophic is bad. Therefore untested/untestable/unmeasured changes are, in the absence of _evidence_, bad. I suspect that Bowman isn't at all exhorting his fellow designers to abstain completely from testing; I'd interpret his remarks as cutting against an _over-reliance_ on A/B testing. Within a primarily A/B framework, I'd consider it impossible to do _real_ design work that reevaluates a product's decisions from first principles. Where can you begin? What interesting set of changes can you propose when each has to be buildable in a way that allows testing against the current status quo of the product as a baseline? I believe that Bowman is right to worry about missing "truly great" designs by getting bogged down in continual, iterative improvement of a mediocre design. Getting wrapped up in asymptoticly approaching the _best_ shade of the _best_ button you can possibly create, and backing it all up with testing, might blind you to the fact that the action might really be better represented as a slider. Or a dropdown box. Or that it's completely wrong and would be better reworked entirely. Lukas quickly notes one answer in passing. I think it deserves more attention. ### Usability Testing and Prototypes ### In an [interview with Salon in 2008][salon], Leander Kahney said:
Steve Jobs doesn't wake up one morning and there's a vision of an iPhone floating in front of his face. He and his team discovered it through this exhaustive process of building prototype after prototype.
Each of these prototypes functioned in one way or another, and each was put into someone's hands to play with. This methodology of testing (especially for _new_ designs) is simply not measurable in the same way as determining whether a green link on a pre-existing page is clicked on more or fewer times than the same link in red. A/B testing _is not_ usability testing sweeping new prototypes; it has a different purpose, and gives different data points. Prototyping new solutions to problems, and putting them in front of real people as quickly as possible, is probably the best way to make sweeping changes while maintaining some semblance of confidence that you're moving in the right direction with regard to the audience you're aiming for. This sort of guerilla testing designs on friends and acquaintances with something like [Silverback][] absolutely ought to be part of the design process, early and often. Getting real feedback from people who _use_ the system you're trying to improve is critical to designing and implementing an interface that makes the right tradeoffs in the right places. In short, I'm highly sympathetic to the [Nielsenian notion][nielsen] that users _can't_ and _won't_ tell us what they want, that we need to examine their clicks in order to measure the impact of the changes we make. However, I think that notion needs to be tempered insofar as _never_ asking a user what she thinks is incredibly dangerous because it never allows you to break out of a certain comfort zone surrounding the product as it stands. So. Test. Early, often, and persistently. Testing gives you immense amounts of data, and data is invaluable to your designs and implementations. But don't limit your tests to those best expressed in a spreadsheet. Prototyping, and asking actual users actual questions, should be a part of your creative process. Finally, to reiterate Lukas' point: you aren't Google. Even if they're dangerously-reliant on A/B testing, you almost certainly aren't A/B testing _enough_. I know I'm not... [salon]: http://machinist.salon.com/blog/2008/06/09/leander_kahney/index.html [silverback]: http://ignorethecode.net/blog/2008/08/04/silverback/ [nielsen]: https://twitter.com/iA/statuses/1752478005
I've mentioned, I believe, how much I adore the Volant series of tiny Moleskine notebooks? Now they come in red. Red! Just _imagine_ how much more important and informative my on-the-fly notes will be when they're written in a tiny _red_ notebook!
DSL Woes
My DSL connection is really quite fast; I'm apparently only ~800m away from the nearest DSLAM, and so I should in theory be capable of maxing out the connection. This holds up pretty well in speed tests: I get great downstream, and passable upstream scores when connecting to pretty much anything in Europe. All told, I should be thrilled with my service, but I'm not, because it only seems to actually _work_ about 80% of the time. Every 10 minutes or so, my DSL modem gets confused about exactly what's going on and drops the connection, picking it up again about a minute later, and continuing on it's merry way with a new IP. This wreaks havok with any sort of persistant-connection driven tool, be it SSH or IRC or Adium... drives me a bit nuts, actually. It's gotten bad enough over the last few weeks that even Elisabeth notices the problem... :) I've been on the phone with [Alice][] pretty regularly for a few weeks now, and it's the same every time: I call in, explain the problem to the first-line tech, who checks the logs, asks me what kind of modem I have, and passes me on to the second-line tech, who checks the logs, asks me what kind of modem I have, and runs a line test. The line test is pretty much ok, but they pass it on to the third-line tech anyway. The third-line tech does whatever it is that they do, and calls up a few hours later to tell me that they don't see any problem, but that they'll replace something anyway. Last week it was the splitter. The time before that it was something in-between my apartment and the DSLAM. I'm curious to see what it'll be this time. Maybe the modem? [Alice]: http://www.hansenet.de/index.html I'm actually not as frustrated about this as I could be. The customer service has been more or less all that I could ask for (short of actually solving the problem, of course). The reps are friendly, seem relatively knowledgeable, and don't treat me as though I'm the problem. I'd love for them to actually track down the bugs and get them worked out so that I don't drop out of chat rooms every few minutes, but I'm willing to give them the benefit of the doubt so far. This is a marked contrast to our previous dealings with [T-Online][] and Telekom in general, with whom I now simply refuse to do business based on the absurdity of the customer experience. [T-Online]: http://www.t-online.de/ In any event, they're working on my DSL again, and I'm hoping the days of `mikewest_`, `mikewest__`, and `mikewest___` will soon be behind me.