A time to gain, a time to lose

Yesterday I ran into an unusual problem that I managed to solve with a little script. The script itself is of such specific application that it’ll be of no value to anyone else—it isn’t even of value to me anymore. But it does illustrate that scripting can be worthwhile even for one-off problems because it ensures consistency and accuracy in the results.

A client sent me a set of photos of a damaged building that I was going to inspect a few days later. Along with the photos, I got a plan drawing of the damaged part of the building, drawn by the same guy who had taken the photos.

Why was I being asked to reinspect a building that had already been visited and photographed? Because the guy who inspected it first was an insurance adjuster, not an engineer, and he wasn’t there to answer the same questions I was going to answer. And I needed his photos because the site had been altered since his inspection—his photos had information that I’d never see otherwise. This sort of thing happens often in my business.

Before I did my inspection, I went through all of his photos and made notes on where the photo was taken and where the camera was pointed. I typed these notes into a text file that ended up looking like this:

Photo001|Laundry Room|looking NW
Photo002|Laundry Room|looking NW
Photo003|Storage Room|looking W
Photo004|Storage Room|looking SW ?
Photo005|Laundry Room|looking N
Photo006|Hallway 1|looking W
Photo007|Hallway 1|looking SW
Photo008|Hallway 1|looking W
Photo009|Boiler Room|looking N
Photo010|Boiler Room|looking NW
Photo011|Electrical Room
Photo012|Electrical Room
Photo013
Photo014

Ideally, each line would have three fields: the file name (without extension) for the photo, the room in which the photo was taken, and the direction in which the photo was taken. As you can see, though, I wasn’t always sure about the location or the direction. The file was about a hundred lines long.

It is, by the way, a long habit of mine to separate fields with pipe characters. If I later need to manipulate the file, pipes are easy to search for and they almost never appear in the fields themselves. And unlike tabs, they’re not invisible.

After I did my own inspection, I realized that these photo notes had a consistent error in the direction. The drawing I was given had a north arrow that was actually pointing east. I’d based my notes on the drawing, so all my directions were 90° off.

I could, of course, go through the file line by line and change every direction. This isn’t a terrible burden, but it’s the kind of dull task that’s easy to screw up.

A 90° shift from SW is SE—or is it NW? Wait a minute, which way am I turning? I’d better go back and check the last few lines.

So I wrote this little script to make the changes for me:

python:
 1:  #!/usr/bin/python
 2:  
 3:  from sys import stdin
 4:  
 5:  oldDirs = "N NE E SE S SW W NW".split()
 6:  newDirs = "E SE S SW W NW N NE".split()
 7:  changeDir = dict(zip(oldDirs, newDirs))
 8:  
 9:  captions = stdin.readlines()
10:  for c in captions:
11:    c = c.rstrip()
12:    fields = c.split('|')
13:    try:
14:      words = set(fields[2].split())
15:      dir = words.intersection(oldDirs).pop()
16:      f2 = fields[2].replace(dir, changeDir[dir])
17:      fields[2] = f2
18:    except IndexError:
19:      pass
20:    print "|".join(fields)

As you can see, the conversion between the old (wrong) directions and the new (correct) directions is accomplished through the changeDir dictionary that’s defined in Lines 5–7. The oldDirs and newDirs lists were built by using the same clockwise cycle of directions, with newDirs shifted by two positions. Because of the vertical alignment of Lines 5 and 6, it was easy to check that I had the conversion going the right way: North on the drawing is really east. East on the drawing is really south…

The most time-consuming part of the script was dealing with the fact that some lines didn’t all have three fields and that the direction might not be the last word on the line. There are probably more efficient ways of handling these exceptions than what I used in Lines 10–19, but that’s what I came up with on the spot. This is not the kind of script you pore over to improve.

The script produced this output:

Photo001|Laundry Room|looking NE
Photo002|Laundry Room|looking NE
Photo003|Storage Room|looking N
Photo004|Storage Room|looking NW ?
Photo005|Laundry Room|looking E
Photo006|Hallway 1|looking N
Photo007|Hallway 1|looking NW
Photo008|Hallway 1|looking N
Photo009|Boiler Room|looking E
Photo010|Boiler Room|looking NE
Photo011|Electrical Room
Photo012|Electrical Room
Photo013
Photo014

I kept the original file (with a note indicating that its directions were wrong), the corrected file, and the script so I can reproduce my work if that ever becomes necessary.

People often cite this cartoon by Randall Munroe to point out that automation doesn’t always save time.

XKCD automation cartoon

But automation is just as much about consistency and accuracy as it is about time. I feel more confident in my corrected directions because they were done by a script instead of by hand.