Python’s for/else construct

I’ve been a Python program for a few years now, but I’ve only just encountered the ‘for/else’ construct. I was changing a conditional to a for loop, but accidentally left behind the else block. My initial reaction after looking back at the code was, “Oh, the else must run if the ‘for’ block never executes,” because that would actually make sense. That’s not what it does though, I thought, because the code in the ‘for’ does execute. I wrote some test code, just be sure I’m not crazy:

def test(l):
    for x in l:
test([1, 2])
# else
# 1
# 2
# else 

And lo, both blocks execute — the loop body and the else block. At this point, I took to the interwebs, and, naturally, someone has described this bizarre python behavior. The else will not execute if you break before the iterator is exhausted. Even knowing this construct exists and knowing I’ve been is situations where it would be usable, I don’t think I would use it. Considering that I introduce loops on many occasions where before I was checking for None, an ‘else: …’ like that in the code above would always initially look like a programming error, and I’d have to spend precious seconds of my time unpacking the intent of that code.

I’m not the first to express surprise at the behavior of this feature of Python, and one helpful redditor linked to one of Raymond Hettinger‘s[1] lecture videos which gives historical context for why the construct exists and why it’s named the way it is. The explanation is cogent and helps me to see for/else less as a misfeature and more as an unfortunately named, but effective construct, much like the ‘try/else’ which I had encountered in some FOSS code about a year back.

1: Fun fact: Raymond Hettinger also wrote my favorite and most-referred-to Python article on the super() construct. It helped open up my thinking on mix-in types, which I now use readily to graft functionality onto my Python objects and classes.

system admin log entries

When I’m doing maintenance on my computer systems, I sometimes find myself wondering what I was thinking when I made a configuration change, (un-)installed a package, etc. At one point, I attempted to keep a log in a text file that I could refer to later so that, in case there was an undesirable behavior observed, I could correlate the timing of the disturbance with intentional system changes. My attempt failed due, in part, to lack of discipline, but in many cases the changes I make are so incremental and sometimes arbitrary that it seems like overkill to record the change at all. The issue is really one of convenience though: If I got prompted to enter a message when I installed or removed packages, it would make it far more likely that the messages were actually recorded for my future self’s benefit. I think for the use-case of package management, at least, it should be simple to add hooks or wrappers on command line tools I already use for package management to issue a “log entry” prompt.

I should emphasize, that I’m not talking about a declarative configuration and change management system like with, say Ansible + Git . My system is, effectively, single-user and otherwise not volatile enough to justify such detailed records — a log in my own words generally describing what I did along with key details would suffice.

Teriyaki Flounder

Fillets of skinless flounder, a white meat, brown in some areas from the teriyaki sauce, overlaid with black flecks of pepper. Crowning the fish is a pile of golden-brown onion slices. Bright green cilantro garnish nestles up against the fish on the right. A fork lies in wait in the background.
The first time I cooked flounder, it was alongside salmon, which I already knew I liked. I was struck by how unpleasantly fishy it was and delayed cooking the rest of what I had. Now, however, I’ve found a preparation of flounder that I like. The fillets are placed in a baking pan, lined with foil, atop one half of a sliced onion in a thin pool (about the height of the onions) of teriyaki sauce. These are sprinkled with garlic salt and pepper, then another layer of foil is placed over the top. The fish cooks at 350-400 degrees Fahrenheit for about 40 minutes, then it’s ready to serve, topped with the sliced onions.

The fish had good flavor with a bit of spice and the fishy taste from before was virtually gone. It may be possible to cook for a shorter period of time, but I err on the side of caution for fear of food-borne illness.

Streaming audio with long reconnect timeouts is fun. It’s like having ghosts in my computers. I’m writing, sitting on the couch, and an unexpected burst of audio pops out from the corner of the room. Experientially, there’s no difference between a disembodied voice and a voice from a body you don’t imagine, and for the split second before I the NPR reporter’s voice, I get slight a thrill.