Skip to main content

Posts

Showing posts from 2006

Linux: Netgear Open Source Wireless-G Router

Summary:I just bought Netgear's Open Source Wireless-G Router, model KWGR614. The setup wizard doesn't work with Firefox. I spent a lot of time fighting with tech support. They told me to use Internet Explorer even though the box says, "Open source code enables router customization for Linux developers and hobbyists". I tried to fix the source myself, but the C code for the admin interface is specifically missing from the source download. I'm quite frustrated.In the setup wizard, I tried to click the "Next" button, and it didn't do anything. I got the error, '"document.forms.MatchSubnet" has no properties'. I'm using the Firebug Firefox extension (which I love) to see such error messages.

I decided to call tech support. It was some woman in India, of course. Here were her suggestions over the course of a 45 minute conversation with her:Use XPPay for premium support (Yeah right! Pay $35 for a problem in their code!?!)Us…

Linux: Coping With Settings on Remote Systems

If you're like me, you probably end up working a lot on remote systems. It can be a pain to manage your settings on them. I think we all have a way of dealing with this. Ideally, we'd all manage our dot files in some publicly accessible source control. If you're a mere mortal like me, though, you just want a way to copy your dot files to the remote system and install your ssh key.

If so, then the following snippit from my .zshrc may be helpful to you. It's been tested with zsh, but probably works just fine in .bashrc. If you add to your .zshrc, remember to re-source that file or re-login. Edit to suit your tastes:# Install my ssh key on a remote system.
ssh-installkey() {
[ -n "$1" ] || {
echo "usage: ssh-installkey username@host" >&2
return 1
}
ssh $1 "mkdir -p -m 700 .ssh"
ssh $1 "cat >> ~/.ssh/authorized_keys2" < ~/.ssh/id_dsa.pub
}

# Install some bas…

Python: Trick of the Day

Let's say you have a function that makes use of a global. (Pretend for a moment that global isn't a dirty word.) Let's say you want to define that global within that function, but only if it doesn't already exist. You can use "globals()" and "setdefault" together in the following, fun one-liner:x = globals().setdefault("x", 0)This will get the value of the global x. If x didn't already exist, it'll be initialized to 0.

Blogger: New Template

I just picked a new template for this blog. Reading Ian Bicking's blog, I learned that fixed width columns are like totally uncool. Hence, I picked something that flowed to the page width.

If this new look pisses you off, I can change it back. If there's anything you see missing, please tell me. Otherwise, tell me if you like the new template. It's the one that irritated me the least.

Linux: Internet Explorer on Linux Using a Separate User Account

My library provides free access to Rosetta Stone which I wanted my kids to be able to use to learn Spanish. Rosetta Stone requires Shockwave which doesn't run under Linux like Flash does. The Ubuntu wiki offers some instructions on how to get it to work under Wine using a Windows version of Firefox. Alternatively, CrossOver Linux specifically supports Shockwave.

Unfortunately, neither of these options worked out for me on either of my laptops or in either Ubuntu 6.10 or Ubuntu 6.06. I was having weird X issues with both Wine and CrossOver Linux on my home machine. A bit of Googling suggested that the problem had not been fixed. My work machine wasn't being very cooperative either. In trying all the possible combinations of ways to get this to work, I wasted two days of my Thanksgiving vacation. I was really hoping that patience would lead to victory. Oh well, at least I upgraded my home laptop to Ubuntu 6.10 in the process.

There were some really nice instructions here

JavaScript: Douglas Crockford Video

Douglas Crockford is Yahoo!’s leading JavaScript Architect. He has written extensively on JavaScript and has been among the protagonists of the JavaScript developer community for more than a decade. Douglas is the discoverer of the JSON data format and a frequent contributor to YUIBlog.I saw him give a talk at Yahoo's Hack Day, and it was amazing. The video is now available. Douglas provides an amazing historical perspective on JavaScript.

MySQL: Deleting Orphans

Referential integrity is a beautiful thing. Foreign key constraints are a godsend. However, sometimes, in certain situations you might have to get dirty and deal with orphans. Orphans are records that contain foreign key references to other records that don't exist anymore.

Suppose we have two tables, tags and article. Now suppose they have a many to many relationship via the tag_article_map table. Now, suppose for some unknown reason that someone deleted some tags from the tags table. We may now have orphans in the tag_article_map table. How do we delete them? Some special MySQL syntax makes it quite easy:DELETE tag_article_map FROM tag_article_map
LEFT JOIN tags
ON tag_article_map.tag_id = tags.tag_id
WHERE tags.tag_id IS NULL;References:http://www.phpfreaks.com/forums/index.php?topic=113742.msg462454http://dev.mysql.com/doc/refman/5.0/en/delete.html

Books: Building Scalable Web Sites

Imagine if Forrest Gump developed a famous Web site. Imagine if one day he sat down on a park bench to tell you how he did it. Now, imagine it with a strong English accent ;)

"Building Scalable Web Sites" is a virtual brain dump of everything technical that you need to know in order to build something like Flickr. (The author, Cal Henderson is the engineering manager for Flickr.) If you're a new engineer, it might be a godsend. If you're a more senior engineer with little time and less patience, it can be incredibly frustrating.

I found myself alternating between these two extremes. I was tearing my hair out when Cal spent five pages explaining what source control is and listing its basic features. I questioned relevance when Cal explained how to write an HTTP client from scratch in PHP (p. 143), and I was baffled when the very next section randomly jumped to the topic of "Remote Services Redundancy" (p. 145). On the other hand, I was grateful when Ca…

Vim: More Vim Tidbits

I reread "vimtutor" for the first time in years. I learned a few things:e"e" is a motion that means "to the end of the word". "ce" is useful.

/searchterm<enter>nNWhen searching, "n" to search forward, "N" to go backwards. Start with "?" to aways go backwards. I had forgotten about "N".
:#,#s/old/new/gDo a search and replace only between two line numbers.
:%s/old/new/gcDo a search and replace with prompts.
:r !shellcommandExecute a shell command and insert the results at the cursor.
RThis is over-write mode.
partial-command^D<tab>Show possible command completions, then tab to complete.
evimgvim in "easy" mode.In the Vim tutorial, there's a mention of "$VIMRUNTIME/vimrc_example.vim" which I had never seen before. This helped me to improve my own .vimrc:" These are general settings.
colorscheme torte
set autoindent
set guifont=Monospace\ 9
set hlsearch
set incsearch
set rule…

Scalability: The Scaling Myth

Scalability is not about using Java...We can create a scalable system in PHP that contains only one tier, no XML, no Java, and isn't even very fast:<?php
sleep(1);
echo "Hello world!";
?>...It meets our three scalability criteria nicely. We can accommodate traffic growth by adding more web servers; nothing in the code needs to be changed...Our code is also very maintainable; there's not a trained programmer out there who couldn't figure out how to maintain it--for instance, if we needed to change it to say "Hello there". ["Building Scalable Web Sites" p. 203]

Python: Myghty vs. Django templates

It came out today on the Genshi mailing list that Myghty performs far better than Django templates.

I personally think that the productivity improvements afforded by Genshi by things such as its match mechanism and the fact that you don't have to worry about XSS attacks fully compensate for any loss in performance.

However, I'd like to say something specifically about Myghty vs. Django templates. Both are good software. Both have friendly authors. I personally think in this case the performance issue is a red herring. If you can't trust your template authors to run with scissors, you should not use Myghty. If your template authors know the difference between a function and a dict, you shouldn't use Django templates.

I think that what the Django guys did makes a lot of sense for their situation, but using Django templates drives someone like me crazy. I like to create functions (containing re-useable bits of HTML) within my templates. I don't like repeating myse…

Web Design: Faking Alpha Blending with gifs

pngs are nicer than gifs because they have true alpha blending, not just transparency. However, they don't work in IE. I'm using the "pngfix.js" script to make alpha blending work in IE, but it's just not perfect. The divs that the script adds mess up my CSS. True alpha blending becomes important if you're rendering your image on a complex background such as a gradient.

I found a suitable workaround. If I start with a png and get it to look right in the browser, I can grab a screen shot. Then I trim the outside of the image to make it transparent. Hence, the actual background is "hard coded" into the gif along the edges of where it becomes transparent so that true alpha blending is not necessary, but most of the image is still transparent so that the complex background shows through. Best of all, the gifs are a lot smaller than the original pngs.

I'm sure this trick is well known, but it was new to me. Oh the depths I go through to make I…

Vim: Getting Started With Vim

A couple of readers asked me to do an overview of how to get started with Vim. I'm sure there are far better overviews than mine, but here are some personal notes:

Be sure you take the Vim tutorial. You can use "vimtutor" from the shell command line.

When you're taking the tutorial, learn how to use "hjkl" instead of the arrow keys. Not having to use the mouse or the arrow keys and rarely needing to use the control key is one of the great benefits of being a Vim power user.

It's best to get Vim out of compatibility mode. You can do this by creating a .vimrc file (even an empty one) in your $HOME directory.

Next, I personally prefer to use gvim. Using the gvim command starts Vim in GUI mode. I like the GUI menus, etc. Of course, you'll need a version of Vim with GUI support. There are GUI versions of Vim for Windows, Linux, Mac, etc.

Next, if you can get Vim 7, do that. It has nice, native tabs and a bunch of other useful features.

In response to …

Foxmarks: We Just Launched!

We just launched the new version of Foxmarks!Foxmarks keeps your bookmarks automatically synchronized between two or more computers. A simple wizard guides you through the startup process. Foxmarks works silently in the background. As a bonus feature, you can access your bookmarks from anywhere via my.foxmarks.com. It's simple and solid.We had to hustle in order to get it out the door before Firefox 2 comes out. The dust hasn't yet settled, but at least I got some sleep last night ;) Word to the wise--vainly attempting an all-nighter every night for a week just doesn't work. No, it doesn't matter how much coffee you drink!

Anyway, I'm pretty excited. Despite the short timeline, our team was amazingly well organized, and the code is really clean. My co-worker wrote the synchronization server using Twisted, and it's performing amazingly well. My boss is still primarily responsible for the extension itself, although he was very helpful with all the other code…

Vim 7: Lovin' It

I finally installed Vim 7. I also took the time to install various plugins. Here are some things that are making me happy:Honest to goodness, real tabs.Auto-completion and built-in documentation lookup for many different programming languages.Editing files and browsing directories remotely over scp works.Subversion integration via the vcscommand plugin is helpful.Vim is still charityware which makes me proud to use it.Vim is still my favorite editor because I truly believe that its style of keybindings is faster for experts. Furthermore, it has one of the strongest and most flexible syntax highlighting systems:It supports a ton of languages by default.It does well with files that mix languages like HTML, CSS, and JavaScript.It doesn't get confused by Python strings such as """He said, "hi"!""" ;)I code in a lot of languages, and I love that Vim is consistent and helpful.

Books: Thank God for Editors!

Thank God for editors in general, and O'Reilly editors especially!

As I was reading an O'Reilly book on the train today, I realized how grateful I am for all of the hard work editors put into improving the quality of technical books. Let's face it, technical topics are tough, and programmers aren't always the best writers. As programmers, there's a monumental amount of learning we need to do in very little time using books written by other programmers who also have very little time. Editors help by making the text more uniform. Uniform text can be ingested more quickly. Without the painstaking effort that editors put in, I would have a much harder time reading what I need to read. In fact, every time I come across glaring typos or grammar mistakes, it distracts me from the technical material I'm trying to learn. Editors enable me to focus on the topic at hand.

I know that authors always thank their editors, and that this post might seem a little silly. Ho…

Python: Modifying a Counter in a Closure

I helped a fellow Pythonista with a problem today, and it reminded me that a lot of people might not know about the trick of using a list to box variables within a closure. If that doesn't make sense, read the code below:def counter(start):

"""Create a counter starting at ``start``."""

# The value "curr" needs to be wrapped in a list. Otherwise, when
# "+=" is used in "inc", Python binds the variable at that scope
# instead of at this scope. We don't want to redefine a variable at
# the inner scope. We want to modify the variable at this outer
# scope. Java programmers would call this "boxing", but they would
# use an Integer instance instead of a list.

curr = [start]

def inc():
"""Increment the counter and return the new value."""
curr[0] += 1
return curr[0]

return inc


if __name__ == '__main__':
c = counter(5)

Python: Greenlets

Someone pointed me at Greenlets the other day, and I'm really quite excited about them. This fully addresses the Limitations of Coroutines via Enhanced Generators I spoke of earlier. I see that "some very smart people" have gone down the path of tying it together with kqueue and select.poll along with an IO-based scheduler.

Greenlets look polished enough, but I sure wish the other stuff was polished and documented so that I could use it in production. The pragmatist in me (which doesn't come out very often) is still insisting that Twisted is still the safer route in the near term even if it is more irritating to code because of its asynchronous nature.

Hacking: Yahoo Hack Day

I attended Yahoo Hack Day. It was a lot of fun. They put on a concert by Beck, which I unfortunately didn't get to see. They also loaded us up with plenty of swag, including a T-shirt, a copy of Yahoo Hacks, and a 256 mb non-branded USB flash drive, which was one of the weirdest but most useful bits of swag ever. I attended talks all day long. Here are some of the takeaways:Yahoo! UI Library: Fonts CSS is a CSS library that completely levels the playing field concerning fonts across all of the browsers. I'm not that great a CSS developer, so I wasn't all that excited about this, but my friends explained to me how hard cross-browser uniformity is to achieve.
Yahoo! UI Library: Grids CSS is a CSS library that lets you do standardized layout in a cross-browser way that works now. I wasn't so thrilled about this either since I knew that even though CSS layout isn't ready for prime time, tables still do the trick. However, once again, my friends set me straight b…

Databases: More Atomic Cluster Commits

I'm currently reading the book Scalable Internet Architectures, and I'm enjoying it.

On page 141, he describes two-phase commits:The basic idea is that the node attempting the transaction will notify its peers that it is about to commit, and they will react by preparing the transaction and notifying the originating node that they are ready to commit. The second phase is noticing any aborts in the process and then possibly following through on the commit (hopefully everywhere)...The two-phase commit is not perfect, but it is considered sufficient for applications such as stock trading and banking...Despite its shortcomings, the only common "correct" multimaster replication technique used today is the 2PC, and, due to its overhead costs, it is not widely used for geographic replications.I didn't catch the phrase "not perfect" the first time I read that section, so I spent the day wondering how the hell they implemented fully atomic transactions across a c…

Python: I Love Genshi!

I’ve totally fallen in love with Genshi! It's an XML templating engine for Python. I learned it between midnight and 2AM one night. By the next day, I was totally productive and totally loving it! I like the fact that template inheritance works so easily, and I love the XPath stuff. It's nice to be free of XSS vulnerabilities to some extent. I really didn't like Tal, so I was surprised to find that Genshi was so nice. It’s weird--Genshi is like a superset of all the templating engines, but in a way that is conceptually simple and elegant.

More about Genshi

A Summary of Talks I've Attended Recently

I've been to a lot of talks and a conference recently. These included:The Future of Web AppsWeb 3.0: Mashing Virtual Worlds and the WebI thought I would blog about ideas that were either:New and interesting.Not new, but came up a lot.AttitudeBe passionate or go home.Be a pain killer, not a vitamin.Be pragmatic; working code is better than beautiful code.What's in it for the user?Startups Should Keep in MindBig, bloated companies are good targets.There is lots of room for passion-centric communities.We consistently see the pattern of boom, correction, lasting change.Amateurs are becoming really powerful.Getting StartedKeep talking to real users, not just your techie friends.Don't go beta with something that sucks.Raise less money, spend less money, hire slowly, fire quickly.Developers should be in the same timezone.Use specialists; for instance, don't waste a good engineer fighting XHTML/CSS browser issues.Don't cut corners; take care of the details.Attracting and…

Erlang: Toying with Erlang

I'm really interested in distributed computing and concurrency right now. Given that I've been playing with Haskell so much, I thought I'd give Erlang a try since it's all about distributed computing, concurrency, and scalability.

I must admit that it already seems easier for me to read than Haskell. I'm not sure why. As I mentioned before, I do like Erlang-style concurrency, since strangely enough, that's how I had always thought things should work.

I'm fascinated by Mnesia, Erlang's distributed database. Unfortunately, according to this:Mnesia is not perfect, of course, and its biggest downside at the moment is that its disc storage engine isn't suited for storing large volumes of data (Mnesia was designed for soft real-time applications where the data is stored mostly in RAM), but I hope this will be resolved in the not-too-distant future.This is a major downer for me because I'm currently interested in terabyte-sized data sets. Nor is the…

Erlang: Erlang Style Concurrency

I'm lovin' this article: http://www.defmacro.org/ramblings/concurrency.html.

It meshes nicely with my earlier post here. Erlang is like stackless Python with coroutines in that it's a lightweight threading system built on top of asynchronous IO. However, it's different in that there is no data shared between threads (i.e. a shared heap protected by locks). Instead, to share data, you must use message passing. This part matches my earlier post. Of course, the benefit is that it's trivial to do distributed computing with such systems.

Anyway, Erlang has been around a long time and is incredibly robust. I'd love to get a chance to use it.

Linux: On-the-fly BASH Aliases with Cntl-R

If you use BASH, I hope you make use of Cntl-R to search for commands you've already executed. Even though I know about and use Cntl-R, even I underuse it. For instance, you can use Cntl-R to create on-the-fly, short-lived aliases. Start with:cd /some/long/path # cdlongpathThen later:<Cntl-R>cdlongpathIt will autocomplete to your earlier command. If you happen to forget an alias, no big deal :)

Python: Limitations of Coroutines via Enhanced Generators

I've been thinking a lot about tricks such as the coroutine system in this article. PEP 342 improves the situation for Python 2.5. In fact, Example 3 in the PEP is exactly what was on my mind. I came to the same conclusion as the PEP:In effect, this example emulates simple tasklets as are used in Stackless Python, as long as you use a yield expression to invoke routines that would otherwise "block". However, what happens if you can't use a yield expression to invoke routines that would otherwise block?

For instance, say coro() is a coroutine that calls third_party_1() that calls third_party_2() that calls blocker() where blocker() blocks. If third_party_1() and third_party_2() are intermediary functions that exist in third-party code, they won't know how to "do the right" thing using yield. If third_party_1() and third_party_2() don't do the right thing with yield, there's no way for blocker() to yield back to the scheduler.

Ideally, I'd…

Python: Stunning News: Django isn't Perfect!

Concerning http://www.cmlenz.net/blog/2006/08/the_python_web_.html:

Although I have a ton of respect for what the Django guys have accomplished (I really do!), I couldn't agree more with this post based on my own experience and the experience of many of my co-workers.

By the way, when he mentions, "There was a comment by someone in the audience at the Google TechTalk on Django along the lines of...or scale down to teams where the programmers are also those who write the templates," that was me! :)

It's not that our team wasn't large enough for separate template authors. Quite the opposite; we had 169,000 lines of code. It's that I generally don't trust template authors because I fear they write redundant code. Compared to Cheetah or Myghty, Django makes it hard to write quick little template functions that take keyword arguments, thus I suspect that a lot of people put up with redundant templates because, after all, (tongue in cheek) it's HTML, not co…

Haskell: Translating C to English Using Haskell

I've written a two-part series for "Linux Journal" called "Translating C to English Using Haskell". Here are links to the two parts:http://www.linuxjournal.com/article/9096
http://www.linuxjournal.com/article/9242The catchline is:Write a program in Haskell that translates C type declarations into English. Manually translate the Haskell into English.I've tried very hard to make it an entertaining article for Haskell newbies, so if your head exploded when you tried to read "A Gentle Introduction to Haskell", give my article a shot!

Python: Don't Mix Wing IDE and sshfs

Wing IDE Professional is awesome. sshfs is awesome. Massively large codes bases are, well, sometimes you're stuck with them.

But note, Wing IDE, sshfs, and massively large code bases don't mix; it's slooooowwwww. Use NFS instead.

By the way, the ability to run Wing IDE on my Linux laptop in order to debug a process running on a remote FreeBSD server (using stackless Python no less!) is fickin' awesome!

Linux: Twin

Twin is a text-mode window environment. It turns a text terminal into a X11-style display with window manager, terminal windows, and can also serve as display for remote applications. Each terminal window provides the functions of a text-mode Linux console. Twin runs on X11, libggi, itself, the Linux console, and any termcap/ncurses-compatible tty. It supports multiple simultaneous displays, and can attach/detach each display on the fly. [from freshmeat.net]

I do most of my development on a remote server. Since I'm a bash + vim type guy, that suits me just fine. I usually use screen. This allows me to create multiple virtual terminals as well as detach from the session and reattach later, perhaps from a different computer. Twin can do all this and more, but in a user friendly way! I'm just getting started, but it sure does look neat!

Haskell: Microsoft Haskell PDF

I'm not sure where I got this or how it ended up on my "to read" list, but I'm really quite blown away by it. It amazes me to know that some hardcore Haskell guy somewhere is busy shoving ideas like monads into commonplace languages like Visual Basic. I had also never stopped to consider that Visual Basic is indeed interesting because it embraces the idea "static typing where possible, dynamic typing where needed."

The Career Programmer: Guerilla Tactics for an Imperfect World

I'm currently reading The Career Programmer: Guerilla Tactics for an Imperfect World. It's fantastic! It's as entertaining as Expert C Programming: Deep C Secrets but as important to read as The Mythical Man-Month.

Simply put, this is a must read, especially if you've been coding professionally for a while, and you're tired of getting kicked around by unreasonable deadlines, politics, etc. This book has taught me that ignoring politics is like thinking you can walk across a freeway just because you have your eyes closed. In between the non-stop entertainment is a fully-developed, practical plan for dealing with work when things don't go according to plan.

I'm not quite done with it yet, but so far, it's a godsend.

Linux: Ubuntu 6.06 on Dell Latitude D610

I just installed Ubuntu 6.06 on my Dell Latitude D610. I love it! You start with a live CD. Hence, you can "try before you buy". Then, when you're ready, you double-click the "Install" icon; you don't even have to burn another CD.

Compared to Ubuntu 5.10, a lot of polish has been added. Since I came from a Fedora background, I was impressed to see that Ubuntu has caught up with all the polish that Fedora has (graphical installer, graphical boot, etc.). Furthermore, despite the fact that I installed it the day after it came out, the Wiki had already been updated with instructions on how to get deal with proprietary formats such as MP3s, Windows video, Flash, etc.

As far as hardware goes, everything pretty much just worked--even hibernate and suspend! To support the builtin wireless, I had to use NDIS. Here are my abbreviated instructions:Add the ndiswrapper-utils package.
Download the driver from ftp://ftp.us.dell.com/network/R102320.EXE.
mkdir driver
cd …

Computer Science: More Threads = Less Contention?

Have you read The Next Mainstream Programming Language? The original PDF was written by Tim Sweeney, the founder of Epic, the video game company that created Unreal. He really got me thinking about the problems he was facing.

Let's suppose you have 10,000-100,000 objects. Let's suppose that at any moment any one of them might need to "touch" 50 other objects. That's the setup.

Now, let's suppose that you also have a super-lightweight threading system that can handle 100,000 threads. Yeah, sounds far-fetched, but you'd be surprised. Consider allocating a thread for each object. Along with its own thread, each object should have an input queue into which you can post new events. Naturally, this input queue should be protected by a mutex.

The interesting result is that because there are so many threads trying to access so many mutexes, the chances of any two threads trying to access the same mutex to push a new event is relatively small is you assume a …

Python: Protecting UTF-8 Strings from Naive Code

"""Temporarily convert a UTF-8 string to Unicode to prevent breakage.

BASIC IDEA: protect_utf8 is a function decorator that can prevent naive
functions from breaking UTF-8.

"""


def protect_utf8(wrapped_function, encoding='UTF-8'):

"""Temporarily convert a UTF-8 string to Unicode to prevent breakage.

protect_utf8 is a function decorator that can prevent naive
functions from breaking UTF-8.

If the wrapped function takes a string, and that string happens to be valid
UTF-8, convert it to a unicode object and call the wrapped function. If a
conversion was done and if a unicode object was returned, convert it back
to a UTF-8 string.

The wrapped function should take a string as its first parameter and it may
return an object of the same type. Anything else is optional. For
example:

def truncate(s):
return s[:1]

Pass "encoding" if you want to protect something other than UTF-8.

Humor: bash-3.00$ jj < coffee.cup > code.py

This is my second all-nighter this week (well, technically, I slept for a couple hours the other day). I had two double espressos yesterday, a cup of coffee last night at 10:30 PM, and I got one this morning at 5:00 AM. I think I realized I had a problem when I discovered that I was irritated that Star Bucks wasn't open between 11:00 PM and 4:30 AM.

UNIX: ssh + tar + gzip -q = goodness

To retrieve a hierarchy of files from a remote server (or to copy it back to a remote server), I often do something like:ssh servername "tar cvzf - dirname" | tar xvfz -However, I usually get the following error message:gzip: stdin: decompression OK, trailing garbage ignored
tar: Child returned status 2
tar: Error exit delayed from previous errorsStrangely enough, as I write this, I get the error message copying something from one FreeBSD system to another FreeBSD system, but I don't get it when copying something from one FreeBSD system to my Ubuntu system. Weird.

I put up with this problem for years. However, I recently needed to use it in a Makefile. Having an error like that is fine when you're a human, but a non-zero return code is a deal-breaker in a Makefile. I needed to clean up my act.

One easy way to make the problem go away is to not use the "z" flag for both instances of tar. This is somewhat icky, because it really would be nice to have the con…

Hardware: Smarter Memory

I'm not a hardware guy, but it seems to me that it would be really nice if RAM could be a little smarter and implement a few simple commands:memcpy - Copy one area of memory to another.memcmp - Are the given two strings of memory equal?memzero - Zero out an area of memory.Now naturally, these commands can't directly be used by applications because of the difficulties of virtual memory. I also wouldn't expect them to be as smart as their C counterparts. However, given some support in the standard library and the kernel, these commands could be very useful optimizations.

Emacs: Syntax Highlighting

It's that time again! Whether it's because I'm drinking coffee and that's causing my compulsive obsessive nature to do crazy things, or because I'm inspired by other smart programmers who use Emacs, I'm getting "must use Emacs" cravings again. However, as soon as I started it up, the syntax highlighting irritations hit me like a stop sign over the head. The time, it's just a normal Python file. Notice how Emacs doesn't understand that double quotes can be embedded in triple double quotes. By the way, this isn't my code, so don't send me hate mail because there's HTML embedded in Python ;)

Linux: Verizon Yahoo DSL

I got Verizon Yahoo DSL working on my Dad's Fedora Core 4 box. His modem is a Westell 6100. These directions were very help (which is half the point of this post). Here are some notes:The default username and password for the modem are admin and password. It prompts you to change these once you login.When I called Verizon, they gave me some userid and password, but I don't remember ever needing to use them.The tech support at Verizon was from Alabama and spoke English well.I had problems with the DSL not syncing. The DSL light was just blinking. It turns out my dad plugged the modem into a wall jack that wasn't actually connected to anything. It's strange that they can't work around problems like that in software ;)Since I was helping my dad over the phone, I was really pleased to find out he could give me remote access to the modem. He logged into the modem at 192.168.1.1. He navigated to Maintenance > Remote Access. Once there, he picked a password a…

HTML: Escaping &'s in URLs in HTML

Warning: Failure to ignore the following validation warning may result in lost productivity!Concerning Ampersands (&'s) in URLs, the following is what I wrote in the Aquarium documentation:

The short answer is, if you have a URL with more than one parameter, you should wrap it with $htmlent when you embed it in HTML if you want to pass DTD validation. If you don't care, then it really won't matter. What follows is an explanation of why I can't make it any easier on you.You must escape &'s in URLs in order to pass DTD validation. Per the spec, a browser could look at http://a.com/?a=b&copy;=2 and interpret the ©= as part of value of the a variable instead of a new variable named copy; because &copy; is an HTML entity.
To handle #1, Aquarium use to escape the &'s in every URL automatically.
However, #2 broke redirects if you redirected to a URL with more than one parameter. I so rarely did this, that I didn't know about the bug for a good ye…

Python: Fun with Classes

#!/usr/bin/python

#
# Author: Shannon -jj Behrens
# Date: Fri Mar 3 16:43:43 PST 2006
#
# In response to: http://secretartofscience.com/blog/?p=8
#
# Although Python isn't a prototype-based language, it's possible to do a lot
# of these same wacky ideas in Python.
#
# By the way, Io is a cool, new prototype based language. I've blogged about
# it before. There was also a knockoff of Python that was prototype based, but
# I don't remember the name--email me if you must know.
#


# Ok, let's start by changing our class on the fly.

class Draws(object):

def draw(self):
print "draw"


class DrawsSmall(Draws):

def draw(self):
print "small:",
Draws.draw(self)


obj = Draws()
obj.draw()
obj.__class__ = DrawsSmall
obj.draw()
print


# This time, let's mixin something on the fly.

class DrawsBig(Draws):

def draw(self):
print "big:",
Draws.draw(self)


obj = Draws()
obj.draw()
class MixedIn(DrawsBig, Draws): pass
obj.__class__ = M…

Python: Django Custom Tags

In my last post, I complained that code like the following is redundant:<tr class="fieldrow">
<th><label for="id_subject">Subject:</label></th>
<td>
{{ form.subject }}<br>
{% if form.subject.errors %}
<div class="error">{{ form.subject.errors|join:", " }}</div>
{% endif %}
</td>
</tr>

<tr class="fieldrow">
<th><label for="id_name">
Poster's Name:
</label></th>
<td>
{{ form.name }}<br>
{% if form.name.errors %}
<div class="error">{{ form.name.errors|join:", " }}</div>
{% endif %}
</td>
</tr>

<tr class="fieldrow">
<th><label for="id_email">
Poster's Email:
</label></th>
<td>
{{ form.email }}<br>
{% if form.email.errors %}
<div class="error">{{ …

Python: Django-palooza

I think the Django guys have written some really nice software. It's good stuff. No, it won't cure cancer; it's not a CMS; it's not a shopping cart; but it does what it does well.

In fact, I must admit that I felt really at home using Django. Django + WSGI reminds me a lot of how Aquarium works. In many subtle places, the designs are very similar. There are some things I feel Aquarium does better, but I can readily admit there are some things that Django does better. Despite the fact that I too am a perfectionist, I think Django may be more polished--apparently, one perfectionist just can't code as fast as two perfectionists ;) Actually, I wish it was closer to meeting my needs (stackless Python, coroutines, a custom data store instead of an RDBMS, etc.), but I can appreciate it for what it is.

Since Django can't possibly meet everyone's needs--for instance, it doesn't make a good replacement for Linux or Vim (yes, that's a joke)--let me state some of…

Linux: Ubuntu 5.10 on Dell Inspiron B130

If you read my last post, you may be relieved to hear that I did not set my laptop on fire. Ubuntu is working great! It even supported suspend to disk out of the box! I haven't been able to do this in a good five years. The only mildly tricky thing was that I needed to follow the instructions on this forum in order to get it to support WXGA resolutions (i.e. 1280x800). I'll probably need to use NDIS to get the wireless card to work, but I haven't gotten to that yet.

I guess I should go write a Linux on Laptops page now.

Linux: Fedora Core 4 on Dell Inspiron B130

Rant warning:

If you're thinking about buying a Dell Inspiron B130 for use with Fedora Core 4, my initial assessment is don't:If you use the automatic partitioning, you'll get an exception during install. This may be Fedora's fault, though, because I've seen this problem before.
After the installation actually started installing RPMSs, it just froze and died. It may have been display related, but I'm not sure.
I installed in text mode (HTTP install) with the bare minimal number of packages. But then, when it tried to boot, it froze on the line, "Initializing hardware... storage network".
I know that the display is hard to get working, but I've heard it just comes down to getting the right mode line, "Modeline "1280x800" 80.58 1280 1344 1480 1680 800 801 804 827".Well, I will continue the battle tomorrow. It's too late for me to return this laptop. I'm not a happy camper at this moment. Apparently, very few people have…

Python: Recursion in Django Templates

Whenever learning a new Web technology, I like to write a bulletin board application. It's easy, I have it memorized, and it gives me a chance to compare and contrast the new technology with what I already know. See here for the application written in Aquarium.

The thing that was hardest about using Django templates to write this application was the lack of functions and recursion in the templating engine. Recursion is really suitable for generating a hierarchy of messages. This post is about how I had to work around the problem. I got it to work, but it wasn't what I'd call elegant.

To use Django to generate a page that looks like this, you break it up into a few steps. First, you create a template that has everything other than the hierarchy of messages. I called it "index.html":{% comment %}
Output the messages, and output a message input form.
{% endcomment %}

{% extends "bulletinboard/vertical" %}

{% block vertical_body %}
<div class="c…

Python: Django Templates

"As simple as possible, but no simpler."

I have a lot of respect for what the Django guys have done. I actually really like a lot of Django. However, having tried it, I find the templating engine to be elegant, but too simple. What frustrates me most is the lack of functions. In my first programming class, I learned how to use functions for code reuse. DRY applies even to HTML. At my company, even the "template authors" know how to create a function to avoid code duplication. Nor is the "include" or "block" statement a suitable replacement--functions have parameters. Different arguments lead to different results. This is necessary functionality. Also, functions should support recursion. I learned in my second programming class how to think recursively, and every once in a while it really comes in handy (for instance, when you're writing a bulletin board application with a hierarchy of messages).

When I was using Django templates, I …

Python: Clearing sys.modules of Stale Modules

I'm posting this here in case someone might find it useful. I also submitted it to the Cookbook.
"""Clear ``sys.modules`` of specific types of modules if one is stale.

BASIC IDEA: Clear ``sys.modules`` of stale code without having to restart your
server. It's a hell of a lot harder to do right then it sounds.

"""

__docformat__ = "restructuredtext"


_lastModuleUpdate = time.time()
def clearModules():
"""Clear ``sys.modules`` of specific types of modules if one is stale.

See ``properties.CLEAR_MODULES``.

I took this method out of the ``InternalLibrary`` class so that you can
call it *really* early, even before you create a ``Context`` to pass to
``InternalLibrary``.

History
-------

The problem that this method solves is simple: if I change a file, I don't
want to have to restart the server. It's a simple problem, but it's tough
to implement right. To prevent repeating mistakes, here'…