February 18, 2004

Learning Python As You Go

A co-worker asked how global/class variable scoping worked in python today. Specifically, how to access globals/class variables from within a class method. I told him what I knew (global keyword.. yadda yadda.. self.. yadda yadda..) and he was satisfied. Then he asked, "where did you read that?" I thought for a second and realized that I had not really ever read much formal documentation on variable scoping and that I must have picked most of what I knew up from looking at code or just playing around. "What do you mean playing around?" he wants to know. "Well," I said, "I just try different stuff and see what happens." It occured to me that Python is excessively easy to pick up as you go because it is easy to try things quickly, measure results, and draw conclussions. Some people call this "The Scientific Method" or something. The conversation ended shortly after but I didn't get the feeling he took me seriously on the trial and error thing. Do most programmers feel that formal documentation is a requirement for learning? I sure don't. I'm positive I learn as much, if not more, scientifically than I do reading documentation. My python-fanboy column for today will thus be on how python lends itself well to those that prefer to learn scientifically as opposed to dictorially [is that a word?].

My thought process when encountering a need for global variables in python probably went something like this:

Me: Need a global variable here.
Little Angel: No you don't. Globals are always bad!
Little Devil: Shaddap.. slap, slap. We just need to do this thing real quick. This isn't java.
Me: Hmm.. Maybe we can just use automatic scoping..

>>> x = 5
>>> def y():
...   print x
...
>>> y()
5

Me: Good. So I just use it then.. Hmm.. but wait, surely there will be name clashes..

>>> x = 5
>>> def y():
...   x = 10
...
>>> print x
5
>>> y()
>>> print x
5
>>> # aha!
>>> def y():
>>>    global.x = 10
  File "<stdin>", line 2
    global.x = 10
          ^
SyntaxError: invalid syntax
>>>    __main__.x = 10
>>> y()
>>> print x
5
>>> # ughh
>>> def y():
>>>   ../x # yea right.
[Ctl-D,Ctl-D]

Me: Sneaky little thing you.. So, you're automatic unless I scope something in local. I'm going to need some help here..

Google: python globals
Me: "18ft snake eats glowing balls of..", huh?

Google: python global variable scope
Me: Better. Here's a good code snip:

x = 5
def somefunc():
   global x
   print x

Me: ahh..

>>> x = 5
>>> def y():
...    global x
...    x = 10
...
>>> y()
>>> print x
10

I now know how to use globals in python. That looks like a lot of work but that probably took all of 2 minutes. I guess I could have bypassed the initial tests and went to google first but I was able to find out a lot with simple trial and error.

I'm lead to the opinion that there are two kinds of programmers and two kinds of languages. You have the scientific, trial and error, show-me-the-source type hacker and then you have the businessy, formal documentation, show-me-the-sdk type. If I had to slot languages I would say C, Python, Perl, and maybe Lisp all seem to fall into the first category and Java, C++, C# fall into second. Some languages, like the different BASICs, seem to fall somewhere in between.

It seems that one of the key benefits of the "learn as you go" languages, and Python specifically, is that you can apply much of what you've learned in other languages very quickly. I have a decent background in Java, C, and Perl. I'm constantly amazed at how much I already know in python by simply asking myself questions of the form, "If I had to write a programming language that did XXX from YYY, how would I write it?" For example, "If I had to write PACKAGE MANAGEMENT from JAVA, how would I write it?" It would look a lot like Python. "If I had to write LIST and HASH stuff from PERL, how would I write it?" Again, it would look a lot like python (well, it would be a lot less useful, I'm sure).

Python really is a language that you can learn as you go, especially if you have experience in other languages. I'm constantly surprised by how much of the language I already know but don't remember learning. Combine that with the ability to do rapid and productive trial and error'ing and you have a language that is sure to be a hit with the scientific types, as is already clearly established.

Posted by Ryan Tomayko at 03:00 AM | Comments (0) | TrackBack

February 16, 2004

ET Covert Ops Rocks

I played way to much Enemy Territory [flash, eww] this weekend. I was hoping to get some Schwag work done but I guess I just needed a mindless weekend.

Anyway, the game really is spectacular. I'm not a big gamer and I usually veer towards the consoles since the Linux gaming situation isn't so hot and I can't be bothered with the wine mess. My attention span for games is somewhere around 2 weeks and I can't remember the last time I actually beat anything. I know ET is special because I've been playing it on and off for about a year. I latched onto the Medic class right from the start and haven't tried anything else until last night. I was out of respawns and following some guy playing Covert Ops. He completely blew me away. It occured to me that one of the best ways of getting better in ET is to go in as a spectator and follow someone with high XP. I played five or six hours as Covert Ops and I don't think I'll be going back to the Medic crutch any time soon.

My basic play style thus far has been as follows. I use the FG42 as a rifle. I haven't seen anyone say one good thing about this gun but I seem to win more than not in SMG battles. I rarely snipe and pretty much act like a soldier/rambo, except I have satchel charges and can wear enemy uniforms. Speaking of satchel charges, they rock. The best weapon in the game, IMO. I try to always have a satchel sitting at a frequented passageway and then run around defending myself with my rifle until I can blow the satchel. This means you have to "have your head on a swivle", watching for guys to shoot but constantly glancing at the satchel for a kill their. Besides kills, my big goal in the game is to blow up as many enemy structures as possible (outposts, turrets, bridges, etc). Lastly, one thing I've found extremely useful in long (10 map+) campaigns is to start as a Medic and work your ass off for the Adrenaline shot. Once you get the Adrenaline you can switch to Covert Ops and still use the Adrenaline. This pretty much makes you unstoppable in my experience. I figured out that last bit on accident after switching to Covert Ops initially.

So tonight I've been on a quest for other people's Covert Ops strategy/tactics. I figured I would linkdump what I found useful.

RTCW & ET 4 Newbies - Covert Ops
Good overview of Cov. Ops /w pictures. Nothing to spectactular regarding more advanced strategies.

http://wolfensteinresource.com/forum/board21/thread1100.htm
Wolfenstein Resource forum post that goes into good depth on Cov. Ops tactics. A little more orthodox than how I've been playing though.

GameFAQs : ET : Covert Ops Guide
In progress at time of writing. This has detail on how to level up and what you get for leveling in different areas. Should be good when finished.

Posted by Ryan Tomayko at 01:43 AM | Comments (0) | TrackBack

February 14, 2004

URLGrabber Merged

We finally got the two URLGrabber source tree's sync'd up in CVS. Michael to audit and then we should be able to push out a stable 0.3 release for Seth. There was also an interesting bug found in current yum related to urlgrabber today. The user:pass parsing for authentication in URLs wasn't unescaping before it set values into the AuthHandler. I need to remember to log this in bugzilla and push up a patch for Seth.
Posted by Ryan Tomayko at 02:53 AM | Comments (0) | TrackBack

Meet the Prez

The Daily Show Feb 09, 2004 had a hillarious crack on Bush's Meet the Press interview, which I haven't seen in full yet. From what I've read, they should have just aired the interview on the comedy channel to begin with.

Here's some video (MOV).

Posted by Ryan Tomayko at 02:48 AM | Comments (0) | TrackBack

February 13, 2004

Schwag Decisions

I need to make some decisions with what to do with Schwag. There are two real directions and I just cannot decide which I want to take. Part of me thinks I should keep it real simple and make it a planet.gnome.org like aggregator that would be used as generation tool for multi-user / public sites. The other half of me really wants to develop this personal portal thing. This goes more in the direction of a single-user, desktop aggregator/reader that has really strong aggregating and reading facilities as well as the ability to act as a bookmark manager type thing.

It just occured to me that the reason I started this project was because I wanted a reader similar in scope to AmphetaDesk that I could then implement bayesian filters in. At some point I decided that aggregation and conversion were important.

I'm just kind of frustrated. It may be that what I'm looking for is a lot of different stuff that needs broken up into separate projects. For instance, schwag could provide the aggregation and feed normalization and another app could handle the whole bookmark management stuff. It should be trivial to integrate normalized feeds into the bookmark manager.

Posted by Ryan Tomayko at 02:16 AM | Comments (0) | TrackBack

February 12, 2004

Back into URLGrabber

I spoke with Michael and Seth a bit yesterday about getting back into a groove with URLGrabber. I finally put together a TODO list today and sent that out to them. It would be nice to get this stable for Seth's yum work.

Seth teased me with suggestions of trying to get some of the urlgrabber/byterange stuff into python core when we started. Running back through the code had me thinking that a lot of the FTP byterange stuff would fit better as a urllib(2) patch anyway.

Posted by Ryan Tomayko at 11:54 PM | Comments (0) | TrackBack

February 02, 2004

Schwag - A Syndicate Feed Normalizer / Aggregator

I've been working on a little Syndicate Feed Reader in Python that I am calling Schwag (don't ask, don't tell), although the name is more of a place-holder for some other really cool name ™. It is less of a Reader, really, and more of a Normalizer/Converter/Aggregator that has some light reading facilities. It uses Mark Pilgrim's Ultra Liberal Feed Parser for support of all flavors of RSS / RDF / Atom feeds (even the bad one's). The feeds are normalized into Atom 0.3 format and dumped to disk. There is a light templating system that allows one to apply XSLT [1] transformations to the normalized feed to produce different representations (e.g. RSS 0.9x, RSS 1.0 / RDF, RSS 2, XHTML, etc). So, the basic idea is to have a feeder component that manages retrieval and normalization to a common format and then a templating component that provides pluggable representations of the normalized feed. This may sound semi-complex but the code is fairly simple as the feed parsing and XSLT machinery is handled by Mark's piece and libxml/libxslt, respectively. My code just kind of introduces the two to each other.

The whole feed normalization / transformation thing is cool in and of itself but nothing special, really. The ideas here have been talked about before (although the specifics are little different). Where it gets interesting, IMO, is when you get into organization and aggregation. I've decided to maintain the list of source feeds as an XBEL [2] document. This is kind of a bastardization of the format but oh well, it is actually perfect for what I need. XBEL is a simple little XML vocabulary for describing browser bookmarks. It has the concept of Folders, Bookmarks, and Aliases. You see where this is going, right? You organize feeds into Folders and can also use Aliases to link a feed into multiple Folders. Good? OK. I am using the Folder concept for more than just simple organization however, and this is where I think I may be on to something half-way useful. Put simply, folders provide aggregation points. The feeder aggregates all feeds in a folder into an Index Feed. To push this concept a little further, the folder aggregation is performed recursively. Index Feeds contain entries from feeds in the immediate folder as well as all feeds in descendant (xpathwise) folders. One result of this is that the Index Feed for the root folder is an aggregate of all feeds available. You can then drill down into sub folders to limit/filter aggregation.

Along with normalized Atom feed generation, the feeder component dumps out an XBEL file in each generated directory that contains the XBEL fragment for the corresponding folder. You can apply XSLT transformations to these as well. I'm currently using this to generate OPML [3] as well as XHTML representations of the folder index. So the concept of treating each Folder as a partitioning device exists here too.

At the end of the day, you end up with a system that takes an XBEL document as input and produces a directory structure containing normalized / converted feeds as well as aggregated index feeds. These are all simple files and directories so exposing via your favorite web server is straightforward. I've written XSLT for RSS 0.91, RSS 1.0/RDF, and XHTML on the feed side and OPML and XHTML on the index side. It is pretty trivial to plug in new representations for both feeds and indexes given an XSLT that takes an Atom 0.3 document on the source side.

This is all very experimental right now and while I'm using the system for day-to-day reading, I'm also breaking stuff and performing major restructing of code and concepts very often. The system is definitely not without its problems. I plan on blogging the success and failure of various approaches in moderate detail over the next couple of months. I haven't even put a distribution together yet but please feel free to browse the sources or grab a tarball if you're interested in really early, often broken applications. I will have to find a home for the project eventually (I'm trying to avoid sourceforge if possible) as all of this is hosted off of a P300 sitting in my living room with only a humble Road Runner pipe. I imagine I will get more serious about this when I think of a name or the code starts stabilizing, whichever comes first. In the meantime, please leave comments or shoot me an email if your interested.

[1] XSLT : http://www.w3.org/TR/xslt
[2] XBEL : http://pyxml.sourceforge.net/topics/xbel/
[3] OPML : http://opml.scripting.com/

Posted by Ryan Tomayko at 11:45 PM | Comments (0) | TrackBack