login
v2
v1

jmoiron.net

Good of Society?

posted May 10th, 2008 @ 18:47:37

- tags: development , python

- comments: 0

I've disabled comments because I have some neat captcha-less ideas for how to tell bots to fuck the hell off from my comments section but I don't feel like implementing them for django. The new system (mostly homegrown glue w/ selector, beaker, mako & werkzeug thrown in) has been in heavy development the past few weeks and commenting should be available by the summer. Sorry Mike; now you've no reason to come here.

For a while the bots were just hitting a few old posts about 5-10 times a day, so I'd kill the spam every once in a while, but then I started to get pretty disgusting stuff on brand new posts so now it's gone. It's one of the classic models of digital social interaction at work, I suppose.

Otherwise, I've been hard at work developing the new site. As part of creating the new site, I wanted to develop very specific things and then generalize them out quickly to create a sort of reusable toolkit. That toolkit (which is standalone, basically) is davenport, and it's been getting a lot of love recently. Some couch-specific modeling stuff and hopefully a davenport CRUD generator will be in the future, as I flesh out the backend of the Hot New Shit. I also have to get my act together and send cmlenz some patches for python-couchdb. Busy Busy Busy.

Swap is good for computers

posted May 1st, 2008 @ 02:06:49

- tags: linux

- comments: 1

Or, using the distribution upgrade for Ubuntu to move from 7/10 to 8/4. I've tried on 2.5 machines so far. The full install, if you are using Ubuntu and have already downloaded the ~1GiB of package data, can still take around 45 minutes to an hour, and stopping halfway could seriously bork things beyond what a journeyman could repair.

But do not despair. Everything (except some translation file for Russian Blackjack; sorry Russia, you're off the island) upgrades fairly smoothly. However, no upgrade is without it's hiccups, and here are two that "got" me. The "got" means that I was mildly annoyed but knew how to fix them.

One was unique to my situation and probably not due to the Ubuntu upgrade per se, but was definitely something I've been seeing more under the heavier-on-the-memory 8/4 than 7/10, and that was a complete system lockup. Happened when I "did too much". I checked free a couple of times too many before I noticed that my swap wasn't there, but that's how it was. As I might have mentioned earlier, swap is good for computers.

The cause of this is almost certainly some dodgy partition swapping I did a month ago when I installed Windows XP on this computer to play Dreamfall. I had a 10GiB partition all set up for Windows + Game for a long time, but never bothered with the install (YAGNI). When I needed it, I realized (after a few runs of waiting 15 minutes for the Windows installer to load all of it's drivers) that I was trying to install to a logical partition and Windows doesn't appreciate it thank you very much. I had to shift around my swap and Windows partition to make the swap logical and the Windows primary before it would yield and install.

Ubuntu uses drive UUID's in the fstab (and in dev under /dev/disk/by-uuid/); these uuid's don't change as long as the partitions don't change (HEH) and they are also device dependent, so you can put your card reader on /media/cardreader/ and your ipod on /media/ipod even if both are going to be '/dev/sdb'. UUID's for devices are generally a good idea, especially since linux has a habit of switching disks (sdb? sda? who cares!) when their position on the bus switches (or just randomly, it seems). Some people don't understand, but they probably just don't like seeing a big ugly UUID in their fstab. They should get over it because for now it's the best solution if your system is going to be managed programatically. Anyway, I never even remade the swap partition, so after mkswapping it and turning it on, I added the new UUID for the partition into the fstab and presto changeo things are nice.

The other issue is with flash sound. 8/4 moved to the "pulse audio" sound server, which is a Good Thing. PulseAudio is like every other sound server in existence except that it's a lot better and it is easier to integrate via wrappers. One such wrapper is the "libflashsupport" wrapper distributed in 8/4 to wrap the non-free flash player's direct use of /dev/dsp (or alsa, i forget which) in calls to PulseAudio. For people who think that this is just "stupid and pointless", PulseAudio buys you lots of nifty things like program specific volume control and a far better backend architecture than esd or arts, and it would behoove people to finally solve playing a sound without fighting over /dev/ resources once and for all in Linux.

So, if your flash stuff isn't working, the first thing to do is check if libflashsupport is installed. If it is, then chances are pulseaudio is not working correctly on your system. If you didn't have problems before with sound, or just want your goddamn youtube, remove libflashsupport. If your flash stuff isn't working and you don't have libflashsupport, install it. Remember, if you want to not use pulseaudio to edit your /etc/firefox/firefoxrc to use 'aoss' as the audio backend for firefox.

Mercurious

posted April 23rd, 2008 @ 22:49:26

- tags: development

- comments: 0

This past week/end, I set up Mercurial on my server and started a few projects there. One is called slipcover, which I talked about last time. The other project, which I've started more recently, isn't really called anything. It was started as a direct result of me using Hg and I must say that so far I am pretty happy.

That project is called Beaker and it already has a perfectly nice home. Beaker is a session management library for Python that allows a number of different storage backends: memcached, database (via sqlalchemy), memory, files, etc. My project is a branch that has a CouchDB backend extension for Beaker.

In Hg, the "checkout" operation actually creates a branch that is no different in terms of operation from upstream: you can checkout from it, checkin new revisions, etc. If you are more interested about how Hg being distributed helps make this type of operation simple, and are coming from a centralized versioning system background (as I was), I highly recommend you read Armin Ronacher's "Mercurial for SVN Users", which does the job of explaining the philosophy of Hg to people used to svn/cvs admirably and better than I could without lots of effort.

Hg is as of just last month "1.0" software, and has already proven itself in major projects like Java. There is a fairly mature trac plugin and various rcs conversion tools. Although there is no WebDAV support, hgwebserve supports most of the same uses with respects to checking in/out via https, and comes with a revision browsing interface that includes colorized diffs and various changelog views. In the coming weeks, I'll be migrating my old svn repositories to Hg and migrating my trac instances to use TracMercurial.

Slipcover

posted April 19th, 2008 @ 19:42:50

- tags: development , python

- comments: 0

I've been doing a lot with CouchDB and WSGI the past few months, with positive and negative results. I'm finally getting the "hang" of Document Orited Databases (DODB? Rubbish acronym), and starting to understand what is possible and what isn't, how to do one-to-many and many-to-many relationships without having lots of queries. It struck me that although the per-query time in CouchDB is thusfar a lot slower than relational databases, the overall database time for individual webpage loads is far less, and there are far less queries and complex information joins going on.

There are a few reasons for this. The first is that Django is a general purpose framework, and it's ORM is similarly meant to be general purpose. The result is that getting the comment counts for 10 posts on the front page takes 10 queries. This type of a query will be possible in one view in CouchDB when Reduce is implemented, but the only way to do this without modifying your "data schema" is to get all of the comments and count them manually.

Because data is so fluid, it's no problem to add a "comments_n" field to each of your commented-on documents. This kind of application specific update-on-write hack is probably going to become very commonplace as CouchDB gains mindshare and the "best practices" are discovered, not because there are inherent limitations with the view system (or at least, there won't be, once it's done), but because the lack of a schema makes it extremely easy, and it's always more efficient to write the application this way than to calculate it over and over.

In light of all this tinkering, I've done a few things. I've started to take a closer look at Erlang especially of late, as I've started to use CouchDB trunk instead of 0.7.2. I've also done a lot of python speed & feature related hacking with both the more or less official couchdb-python library and with my own re-implementation using pycurl instead of httplib2 which I've called curlcon. Originally, I had devised an httplib-style replacement object that used curl as it's transport layer (Hence Curl Connection) to be plugged into python-couchdb, but it evolved into a sort of experiment to see how fast I could get the http part of CouchDB to run.

The code is now available in my mercurial repository under the "slipcover" repository. As I start to add testing to some of my "web framework" for the next version of jmoiron.net, "slipcover" will become more of a full project whose purpose (besides to run my website) is to be an example of an idiomatic CouchDB/Python web application.

Clonable Server Demarshaller

posted March 18th, 2008 @ 21:05:38

- tags: politik

- comments: 2

I might just take all of my title names from classnamer from now on. It really saves me from the hardest part of writing these damned things.

This past weekend (and even now) I've had some foul flu-like disease which has really destroyed any Joementum I've had coming into the stretch here. I was ready to go to 2 concerts this week and reconnect with some old mates when this bug came in and kicked me straight in the ass. I was out even worse than Bear Stearns this weekend. It's pretty funny, right? Hah, Hah! But I'm actually extremely pissed off; I'm mad as hell and I'm not going to take it anymore. It's just so far past "I told you so" that I can't say that anymore. Doesn't have the requisite OOMPH. The only thing I can think to say is fuck you; It's the new black.

Lets put things into a ludicrous perspective. Anyone can go onto Yahoo and find out just how bad the dollar has taken a tumble since 2002 against the Euro (protip: it was on parity, now it's around $1.60 for 1 EUR), and it's very startling to an American's sense of idiotic superiority to learn that the CAD is worth more than the USD, but to me the anguish really concerns Japan.

A mere 2 years ago, I went to said island nation and was able to fetch 127 JPY for a single greenback.
Not 1 year ago, I revisited the land of the rising sun with my younger brother, and we received not less than 117 JPY per hard earned American Dollar at the very same money change counter in Narita. In those 15 months, something that I enjoy doing got 8% more expensive purely because our economy is in the shitter and nobody trusts the complete idiots in chief to right it.

This monday, the dollar hit as low as 96 JPY. 96. That's a roughly 18% drop in 9 months. In January, it was already down around 106, 105. Something that I liked doing in January 2006 is now 25% more expensive to do purely because our economy is in the shitter and... you get it. I'd love ever so much to blame this on Ohio, and I do; but the problem is really a sociopolitical perfect storm that can only be described as completely fucking retarded. I mean this with the utmost respect to the actual mentally retarded, because they don't deserve to be compared to the intellectually indigent beltway assholes steering everyone straight into the shit pile.

This is what happens, America, when you allow anti-intellectualism to become the dominant culture; you get people trying to stress already underfunded schools by making them teach idiotic filth alongside evolution, you get a hulking mass of voters who want their political representatives to be typical instead of exemplary, and you get a bunch of deified capitalist idealistic monsters who have just plain have no fucking place in reality as we know it. And you ruin my fucking trips to Japan. So if you are out there, and you voted for Bush because Kerry seemed like he was too boring, or his face looks like that of a horse, or you think John Edward's hair and plastic smile and double chin looked a bit too perfect, or (and I sincerely hope against hopes this doesn't apply) that you actually agreed with anything that ridiculous, impish conman said in his first 4 years, then I say to you fuck you as emphatically as a sick man can.

Happy Anniversary: An Introspective

posted February 22nd, 2008 @ 22:40:36

- tags: development , life , python , site news

- comments: 2

Happy Anniversary to me!

6 years ago I started my blog on the now defunct IRIX server attila.stevens-tech.edu. The first post in this blog was made with a bash script that basically used cat & sed to style a quasi-structured text file that I'd shell into the server and create. The server did not offer any CGI services (for fear that the students would screw up and bring down the server, which also handled email), so it would be a year or so until I was able to move my website to PHP.

From there, I wrote two versions of jmoiron.net using the classic LAMP stack. The second one used PEAR:DB for database safety, a thin home-grown templating system based in PHP (both heavily inspired by jeremy mikola).

In May, 2003, I started to learn the Python programming language (This was the beginning of my summer vacation for the Junior->Senior year of University). My very first mention of the language in these hallowed pages was, well, completely retarded: I was "gonna write an interpreter, or a C compiler, or something." It's funny ha-ha.

By late 2004/early 2005, I had ditched the PHP beginnings and had written some custom mod_python stuff to run the site. I ditched mysql at the same time. By late 2005/early 2006, I started writing my own plain-text -> HTML markup language based on MoinMoin syntax. I had almost my whole database converted (automatically) to this script when, in mid 2006, I traded manual mod_py for django and my markup language to markdown.

I quickly ditched the first iteration of the django site and ended up with what you see today; It's been here for over a year and a half! It was by far the harshest transition, because I also made a switch from storing my posts as HTML to storing them as markdown (which I am, of course, now unhappy with); and back then the automagic html->markup filters left a bit to be desired. I am working on yet another iteration with yet another set of technologies; the next iteration (probably set to finish around April) won't even involved SQL at all, and will be the first one without a real solid framework since I moved to Django.

This site is kind of a technical experiment of mine; It's where I express myself both through code, through design, and through words. Hopefully sometime soon, through pictures too. I hope that it will continue to be something that I can hang out there to dissuade future employers from hiring me!

On WSGI, CouchDB

posted January 30th, 2008 @ 01:25:41

- tags: development , python

- comments: 0

pythons on a couch

I've been thinking about WSGI and CouchDB recently, while on the subject of digital inflexibility. First, I want to clarify a few things about what I mean by flexibility with respect to an application, and how the current crop of frameworks approach this problem. If you want to follow this musing well, I highly suggest reading "What PHP Deployment Gets Right" by Ian Bicking; or just his entire blog, and most of the crosstalk on the web about REST, Web Services, and the evolution of the WWW.

How do modern frameworks (Rails, Django, Turbogears, or other "canonical" ones) deal with the problem of flexibility? They don't, for the most part. For one, flexibility is hard both programmatically and conceptually. Secondly, they replace flexibility with simplicity, which is almost always a tradeoff that results in quality. They achieve this simplicity by strictly dividing tasks and then conquering each task by building up a structure around how one is supposed to go about solving that task.

These are not negative qualities at all; one of the things that Rails has gotten right is that design ought to be opinionated. So your task when you go to develop in your now "classic" framework is to set up your REST API (your "Routes" or "urls.py") and your controllers, design your models, and set up your views, and you've got the whole MVC ready to go. The problem is rigidity, repetition, and BigDesignUpFront.

The solution is flexibility. Joel defends BigDesignUpFront, and when you are working with a team on some critical make-or-break software for your company, BDUF might be well worth it for it's benefits in fleshing out potential problems, helping with schedule and cost estimation, etc. But for prototyping, exploring technology, or exploring a problem space, BDUF is deadly. For "agile" or TDD, popular buzzwords that are worth far less than their hype but still provide useful insight for all developers, this is potentially damaging. Coupled with rigidity (in the form of SQL) and repetition (even in DRY espousing frameworks like Django) this is tough to overcome, especially when looking at migrating lots of data to a new application framework.

The first way to overcome flexibility I want to talk about is WSGI, whose design is inspired in part (or so I understand it) by Java Servelets. At it's core, WSGI is a specification for how web servers and python applications communicate; but more interesting (and far more necessary in the statically typed world of Java) it also defines specifically how various python applications are called by the web server. This means that other python applications, given that they abide by the specs, are free to call other WSGI applications themselves with impunity and expect them to work.

The way it's implemented, you need only define the __call__ method to receive 2 passed arguments and return an iterable in order to qualify as a WSGI application. These are incredibly weak requirements on applications, and make many middlewares truly plug and play. What's more, the effort was originally to define a standard that the existing plethora of Python frameworks could all use so that their component pieces would be interoperable with each other. WSGI is still pretty new, and opinionated frameworks like Django are probably not eager to ditch their middleware integration layers for pure WSGI interfaces anytime soon (although Django does work w/ WSGI, I think that's more of an interface between a web server and a Django application taken as a whole), but the proposition of using, say, Django's caching middleware, for any python web application written to conform to WSGI is really exciting.

This gives you flexibility in designing your own "framework" built of hand chosen component pieces. Pylons is essentially a framework built upon PythonPaste that facilitates you in choosing these WSGI middleware components, but I've found some of the areas (particularly the URI routing) to be a little less flexible than I'd like (and, sadly, the documentation is a far cry from Django's). Accepting the dogma of one framework or another does come at a practical advantage; you avoid writing the necessary glue between components. But as the glue itself is agonized over, standardized and simplified, it becomes just another component.

It also gives you another interesting flexibility: the ability to attach applications written completely differently (even in different frameworks) to different URIs at the same site, all of them using the same middleware. This blog works as a Django application; why change it? But my Gallery might be better implemented using other technologies (and I discuss this below); with everyone on board using WSGI, it'd be trivial to attach a different application to handle the '/gallery/' URI space but keep both applications using the same caching, gzip, and authentication middleware. This idea is extremely powerful, because it allows one to select the proper tool for the job and align with whatever tool chain most closely reflects the problem at hand.

What about flexibility at the genesis of the application? Web applications these days deal mostly with the storage and presentation of data. Certainly, the current crop of frameworks reinforce this idea; ditch Django's ORM or ActiveRecord and see what's left with respect to creation of a data driven website. This is where CouchDB, or what I perceive CouchDB to offer, enters the equation.

As a metaphor, lets look at programming languages and type binding as a method of describing and manipulating data. In a statically typed programming language, the structure of data is described explicitly and is enforced by the compiler. You go about defining what a widget is, and then create instances of widget. Methods that would manipulate widgets must receive a widget as their in put.

Where statically typed languages provide subtypes, super types, and other ways to make the definition of what qualifies as a widget more malleable, databases struggle at this. You describe data (in the form of tables, relations, etc) beforehand as before, with each field being a strict type and each table describing some strictly typed record. To alter these definitions, you have to define new tables to make additions to the previously defined record types, and modifying the type of their existing data is not possible.

If you want to act on all widgets, you must be cognizant of other widget like tables. Even if your new widget is exactly alike from the old one, grouping both is either manual or inane and always slow. So how do you do migration? You dump the database, add or massage the types of the new table columns you will be adding, and then re-import. Some frameworks provide tools around this process, but the necessity is fundamentally broken.

The document oriented approach CouchDB takes is much more like having a large, flat, "duck typed" table where you can store anything. You define views of your large data soup that pick out items based on specific characteristics of those items, not on their structure. Want all "things" published on some day? It isn't a problem; everything is a thing. A quick stab at structure is to add a type field that allows you to filter out "things" that match a type string. These things are guaranteed, upon delivery, only to have matched that type string and nothing more. This is a weak guarantee, but weak guarantees buy us flexibility.

In Python, often times functions are described as taking objects that allow certain actions on them; for instance, iterable. Requiring only that an object be iterable is a very weak requirement, far weaker than acting on "anything of type foo". In practice, many functions merely require that the objects they manipulate only contain certain methods or attributes, not necessarily that they satisfy some larger unused type structure. This is a trade off, to be sure, but it's a trade off towards both simplicity and flexibility.

As a concrete example of how this can be useful, lets take my ever languishing gallery application. The goal is to keep in the database my images as well as their EXIF tags such that I could easily perform a search like "Find me all images with this aperture" or "Find me all images taken with this camera." Because I have images taken from at least 3 different cameras (not to mention pictures my friends or family take that I might want to include), and camera makers all add their own types of tags in the "MakerNote" section, I can't have a single per-image "tags" table.

As it stands now, my proto-SQL database has 3 simplistic tables to handle this: a gallery_image consisting of id, title, description, etc; a gallery_image_tag, which is supposed to represent a single EXIF tag consisting of an id, title, desc, etc, and 'gallery_image_tags' which allows me to tie the two together so I can get "an image and all of it's exif tags" in one query. This is straightforward (albeit painfully unoptimized) using the Django ORM, but it's a horrible rigid design that sees me making potentially dozens of database updates for each uploaded image.

In CouchDB, I could simply designate my images as having a type field of "image", and then dump in the tags as key/value pairs. It is as trivial to create views of the type described above of this database as it is to create a view returning all images; while the 'all images' view would map documents based on their satisfaction of (type == image), the more complex views are just as simple (camera_model_name == ...).

Looking to the future, it is also far easier to modify the CouchDB database to allow for new features. Lets look at some potentially interesting features: an algorithm that gauges the color temperature of a photo to group "like" photographs together, such that you can view a "gallery" of dusk pictures, dark pictures, or black and white pictures algorithmically rather than by manual tags. Implementing facial recognition to determine whether or not a picture is a portrait. I could run these algorithms on my database images in batch mode and then simply update each document with their temperature score or their boolean portrait status without ever explicitly modifying any structure. As the temperature scores or portrait statuses are tabulated, they are added to each document and the "gallery" views incorporate them automatically.

Software developers have this kind of wish list view of the future, where writing a web gallery can quickly turn into pushing the forefronts of computer vision technology or spawn a perl to python compilation project. Sometimes these whims manifest themselves as something very interesting or inspiring, and wherever they aren't too critical they should be possible!

Digital Inflexibility

posted January 25th, 2008 @ 18:45:28

- tags: development

- comments: 1

I've been playing with a few ideas recently, stemming from the perceived inflexibility in my blog software and my inability to develop a gallery over the past, oh, year and a half.

I already know what level of flexibility I want; the wiki. No logging into an admin interface and filling out some convoluted form to create a flat page; you go to the URI you want to represent your text and you add it.

Wiki's can afford this flexibility by sacrificing a lot of what makes a traditional website powerful: structure. When you add data to a wiki page, there is no structure to the text within that page relative to the system. When I add a blog post, there is a strict structure: there is some text that is a "body", "title", "timestamp", etc. This structure is very powerful, because then you can treat all posts the same and provide different views on them. This blog post is rendered by the exact same tiny template as any other blog post in any other url that you find on my site.

But in a traditional "backend" driven website, that structure exists in a relational database. Changing databases is difficult and annoying, and gets moreso as the amount of data you store in them increases. More unfortunately, you have to create that database structure at the beginning of your website development, forcing you to think about the exact structure and interdependence of your data before you have anything off the ground. I've spent 12 months being paralyzed by the daunting task of coming up with all of the possible metadata I might want to save on an image to create photo gallery software.

Some of this is tool failure, some of it is personal failure, some of it might even be my very own ignorance. But there is a kernel of structural failure in the very way that the classic "web application" is created. As it turns out, the "new jersey method" of web content delivery, the completely unstructured wiki, is better for most things.

At its core, at its most deep philosophical level (ignoring community driven content, which is outside the scope of this discussion), a wiki is a way of linking a UID, represented by a URL, to a piece of text. The other step forward in wiki is the pervasive use of simple, human friendly markup.

What if you could apply these to more than just text? What if you could give structure itself an easy, wiki-like markup? A wiki's handling of rich content like images or movies is notoriously bad; what if you applied pythonic namespace theory to a wiki so that /!img/foo.png allowed you to "create" foo.png if it did not exist, or /!mov/bar.flv allowed you to "create" the flash video bar.flv at that "location"?

I've been mulling over this recently, and over my own dissatisfaction with django/turbogears/pylons and just SQL in general. I've had some interesting ideas for wiki extension (like pervasive use of DAV, using an RCS backend instead of a FS backend, etc), and looking into "thin" web glue technologies like paste to assist in creating a framework suitable to my needs using mod_wsgi, django's URL routing, CouchDB as a backing store and whatever templating language I end up preferring (probably the fastest one).

Resolve, Resolute

posted January 1st, 2008 @ 15:18:04

- tags: life

- comments: 1

resolve hangover medicine

Most of the past 5 years (chronicled for you, on this site) I've made some kind of attempt at listing something, telling a story about my year, or dodging such responsibility. Last year, I just wrote about some software I was writing. That's what happens when you're actually doing things; you don't take the time to reflect over how little you've done, and you're better for it.

This past year though, not so much. Maybe I'm starting to raise the bar too high, or I'm burned out, or something; but I just can't think of anything to be really happy about this past year. I left my old job but none of my old habits, I started working out in March and while I kept a good schedule the whole year and feel a lot fitter, I still look the same. I had some health problems that I can only assume were caused by doctors; they're all gone now (the problems).

But after a lull in the usual frenetic pace of the work/life/sleep cycle, I've taken a little time to look at myself and where I am and I think it's time to get serious. Serious like I got for my MS;
4.0 serious. The sun sets south and early in January in the northeast United States, and I think it's time for it to set on this uneasiness I've felt. Here are some things I expect to do or continue doing in the coming year, sorted roughly by the order I intend to do them in.

  • concentrate more on self expression (blog, photos)
  • continue going to the gym
  • work more on this very website
  • cut my hair
  • continue my Japanese studies
  • watch more live music
  • go down a pants size
  • run 5k in 25 minutes (that's a 8 minute mile pace, give or take)
  • learn a new programming language
  • contribute to an open source project
  • submit something i write or create to peer review
  • read a book once a month (last year i averaged once every other month)

That's just off the top of my head.

Knowing the Space

posted December 27th, 2007 @ 23:54:57

- tags: general tech , life

- comments: 0

Haven't been writing mostly for want of time. Wanted to drop this, for what it's worth.

It's the holiday season, and you know what that means. Time to provide technical support to relatives! I felt obliged to help out my great uncle with some video games that my godfather had sent him from Portugal. He said he had a disc, but didn't know what to do with it; how to get them installed.

I went up to his place and sat down at the machine. It wasn't on. I live in a world where computers are always on, for some reason, or another, or none, but this one wasn't. Turn it on, and it boots up into Windows 98.

Microsoft stopped supporting this operating system a while ago, and for good reason. It is still inexorably tied to DOS, and the shell is pretty bad. The whole machine locked up completely at least 5 times as I tried in vain to access the cdrom drive (start->run->(random letter:) .... nope, failure). Finally, I get it to boot where it'l show me what drives are what; his optical drives are F and G. Oookay.

Eventually, I'm about to give up, because I can't open any kind of explorer window on any directory at all without a full system lockup. Then I ask him, "Does internet work?" He says yeah, he clicks on the blue E. Bingo; Microsoft's monopolizing finally works to my advantage. I copy a bunch of games (which are mostly simple 3.1 and 95 era games) to his desktop to a directory named "Jogos", and we're on our way.

This story is not particular interesting. But a few things about his computer were interesting to me. He had what must have been a 8 year old hard drive that seemed to work just fine (probably off half the time, never been overwritten). He had a brand new-ish samsung syncmaster 17" LCD screen, which looked like it was displaying @ 640x480 at 256 color depth. I contemplated asking him why it was that way, but I knew the two possible answers: he didn't know it can be changed, or higher resolutions made the text too small.

Questions of resolution independence aside, I think my Uncle is a pretty typical pre-internet computer user. This is how most people used their machines before computers became central entertainment and socialization appliances. He had various directions scribbled out there on a pad on how to get a shortcut icon on the desktop, and various other passwordy strings. It really was a blast from the past, on the whole.

I think that this generation of computer user is going the way of the dinosaurs fast. I'd love to see some patterns of his usage, to see what it's like for a user of this type to use a computer, but kids are learning it now at that age where they just absorb knowledge at ridiculous pace; I can't imagine too many lost computer users in 20 years. On the whole, people at least think they know the technology space these days. They understand how to maximize their utilization of whatever gadgetry they buy into. Now they have to wake up fast and see how companies try to pull the rug over their eyes with schemes to artificially contract that space of possibility in their devices with lockware, drm, etc!