Wandering Thoughts archives

2013-07-31

The problem with a custom laptop environment: designing it

For reasons beyond the scope of this entry I was recently irritated into putting my custom laptop environment plans into action (I do a surprising number of things due to irritation). In the interests of avoiding analysis paralysis I'm basing the first attempt on my existing fvwm-based desktop configuration (with an ever increasing number of changes). Somewhat to my surprise, the difficult part so far has not turned out to be what I expected.

My two biggest problems are related. The first one is simply designing things, in the sense of what goes where and how things will actually work (and also how I will avoid everything looking hideously ugly, which is so far being harder than I'd like). My usual desktop layout doesn't really work on a 1024 by 768 screen (there just aren't enough pixels) and I'm pretty sure I'm going to need a collection of new launchers and widgets.

(I'm basing this partly on my experience with my current Gnome 2 environment on Fedora 14, where the Gnome taskbar has launchers for several things and I use them frequently.)

The second problem is that there seem to be a huge collection of choices for the various pieces of such an environment (and some of them even work). Since I need some stuff beyond what I already have in my existing desktop fvwm configuration I've been forced into picking my way through this field of options. Many of the programs seem very powerful but their documentation is mostly focused on people who already know what they do and what they're good for; sadly this doesn't describe me right now.

(What I dream of finding is a guide to assembling your own custom desktop, laying out the options for application launcher bars, system trays, status monitors, essential applets, and so on. Given the huge amount of work it would take to assemble such a thing, this is crazy talk.)

On a closely related issue, I will note that there is nothing like trying to copy bits and pieces of your personal environment to another machine to rub one's nose in just how intertwined, baroque, and encrusted with various relics of history the whole mess is. I'm getting very tempted to conduct a slash and burn expedition through $HOME/bin in order to clean up a bunch of things.

(I should not have just looked at how many files I have in there, because the answer is 'too many'.)

PS: part of my uncertainty is that I haven't tried my in progress environment on the actual laptop yet. So far I've only been working in a VM (at the right resolution) since I wanted to have the basics there before I reinstalled the laptop.

Update: all my grand plans fell through spectacularly when I tried my in-progress environment on the actual laptop. See here for the depressing update and reversal of plans.

Sidebar: on the matter of alternate window managers

Most of the popular modern window managers for minimal desktops seem to be primarily or entirely tiling ones. From current experience with my laptop, a 1024 by 768 resolution is simply too small to not have plenty of overlapping windows (and thus a whole bunch of support for moving, restacking, and resizing windows). I also like using some amount of the mouse and don't want to have to memorize a big list of keyboard sequences for a machine that I only use infrequently.

I've looked briefly at awesome but the idea of writing Lua to configure my window manager is even more extreme that fvwm's elaborate configuration language. Maybe I'll try it some time for a (strictly hypothetical) version two of my custom laptop environment.

linux/CustomLaptopEnvironmentII written at 23:28:37; Add Comment

A Python code structure problem: exception handling with flags

Here's a Python (2.x) code structure puzzle that I don't have a good answer for yet, except that maybe the answer is that my overall design is a bad fit for what I'm doing. To start with, suppose that you have a multi-level, multi-step process of processing lines from an input file. Any number of things can go wrong during the processing; when it does, you need to bubble this information up to the top level but keep on going to process the next line (if only so you can report all of the errors in the file in one pass). The obvious fit for this is to have errors communicated by raising exceptions which are then trapped at the top level.

Now let's suppose there are several different sorts of errors and you want to treat some of them specially based on command line flags. For example normally all errors are fatal and show error messages, but some can be suppressed entirely with a flag (they just cause the record to be silently skipped) and some can be made into warnings. How do you structure this in the code?

My first version looked something like this:

try:
   data = crunch(line)
   ....
except A, e:
   report(e)
   commit = False
except B, e:
   report(e)
   if not option.skipempty:
      commit = False
except C, e:
   if not option.skipdups:
      report(e)
      commit = False

All of the duplication here made me unhappy because it obscured the actual logic and makes it easy for one exception to drift out of sync with the handling for the others. I can aggregate everything together with 'except (A, B, C), e:' but then the question is how to write the single exception handler so that it's both clean and does everything necessary; so far I've thought of two approaches. The first approach is to use isinstance() on e to tell what sort of exception we have and then write out the conditions in if's, except that trying to do that makes for ugly long conditions.

(I started to write out the example above and basically exploded in irritation when I got to the commit logic, which I decided was a bad sign. It also looked like the result would be very hard to read, which means that errors would be easy to add.)

The second solution I've come up with is to add attributes to each exception class, call them report and nocommit. Then at the start of the code we do:

if options.skipempty:
   B.nocommit = False
if options.skipdups:
   C.report = False
   C.nocommit = False

In the main code we do:

try:
   ....
except (A, B, C), e:
   if e.report:
      report(e)
   if e.nocommit:
      commit = False

This avoids both duplication and lack of clarity at the expense of, well, kind of being a hack.

(You can also code a variant of this where report and nocommit are functions that are passed the options object; this puts all of the 'what turns this off' logic into the exceptions themselves instead of reaching into the exception classes to (re)set attributes. That might be somewhat cleaner although it's more verbose.)

Given that all of the options have drawbacks I feel that there ought to be a clever Python code design trick that I'm missing here.

python/ExceptionHandlingWithFlags written at 00:38:13; Add Comment


Page tools: See As Normal.
Search:
Login: Password:
Atom Syndication: Recent Pages, Recent Comments.

This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.