Customer service

Level One

I put my mom on a plane this afternoon to fly back home after a visit. She’s been having cognitive problems for a while and airports—especially one as big as O’Hare—are not a familiar environment for her, so I wanted to make sure I could take her to the gate and see her off. Other relatives would be picking her up at the other end—a very small airport that’s only a few steps from gate to baggage claim.

To be allowed through security without a ticket or boarding pass requires something called a gate pass. The airline’s website said that gate passes were available for people accompanying travelers who need assistance, and I called the airline a few days ago to confirm that I’d be able to get one at the ticket desk when we checked her bag.

You will not be surprised to hear that the people at the ticket desk—both our initial agent and his superior—had no idea how to issue me a gate pass. Curiously, the agent did ask for my photo ID, even though he had no idea what to do with it. Force of habit, I guess. Eventually, the supervisor hit upon the idea of sending us to the Special Services desk, where we would become someone else’s problem.

The agent at the Special Services desk knew everything about gate passes and told me right away that I wouldn’t be able to get one. “They’re being very tight with those.”

When I explained to the agent that I’d been told by the airline that I could get a gate pass, she told me with great confidence that the people manning the airline’s 800 number didn’t know anything. But she took my driver’s license, typed my information into her computer, and my gate pass printed out immediately.

“Do you know which gate you’re going to?” she asked sharply as she handed it over.

“No, I haven’t checked yet. I wasn’t sure until just now that I was going to get in.”

“Well, it’s F6A. It’s right on the pass.” There was a note of triumph in her voice, as it was clear she had bested me.

The rest of our visit to O’Hare went smoothly. We didn’t even use up all the extra “snafu time” I’d put into our schedule, so we were able to walk slowly to the gate. Most important, Mom got home safely and wasn’t stressed.

Level Two

Once Mom was on the plane, I drove to my office to knock off a few todos before leaving tomorrow morning on a weeklong business trip. One of the items on my list was to write down our network’s new IP numbers.

Earlier in the week, our company’s service provider had reworked our connections and installed a new router and interface hardware. In the process, our block of IP numbers was changed. I asked the installer why we couldn’t keep the old numbers—they are, after all, under the control of the provider, and we weren’t switching providers. He gave one of those syntactically convoluted answers that’s easily translated to “I don’t know, but I don’t want you to know that I don’t know.” I didn’t pursue it because

  1. it wouldn’t do any good; and
  2. it’s not a big deal to work with the new numbers.

I’d probably want access to company network while I was out of town, so I needed to write down the new numbers to take with me. But doubt—partly from the installer’s word jumble, partly from my still-fresh experience at O’Hare, but mostly from too many disappointing experiences with IT professionals—made me decide to test the new IP numbers before I left the office.

None of them worked. Not a single one.

After some network inquiry, diagnosis, and testing, I learned what the new numbers really were. They weren’t even close to what the installer had given us. Not a single octet was the same, nor was there any chance that digits had been transposed. What we’d been given was just thoroughly wrong, as if it had come from a random number generator.

Upshot

As I sit here typing and enjoying a beverage, I don’t feel angry or outraged, nor am I disheartened by the sad state of the world. I’m just happy I planned for these mistakes and for others that didn’t happen. It’s something I wouldn’t have done when I was younger, and I would have ended this day upset. Now I see my interactions with customer service as a sort of strategy game: can I plan my way around the obstacles the game will put in my way? Today I came out on top. Tomorrow is another round.


Quicker Markdown linking with TextExpander

I listened to the Mac Power Users TextExpander episode today and noticed that I come off as a bit of a dick, always correcting others. This was surprising only inasmuch as I wasn’t on the show. Normally, I have to be present to demonstrate my dickishness, but David and Katie have dealt with me enough to limn my essence without me. Still, as Marvin and Tammi say, ain’t nothing like the real thing, baby. Let me demonstrate by explaining why I think David’s Markdown link snippet could use some improvement.

He describes it starting at about 38:30. The snippet uses the Mac clipboard to paste a URL into the proper spot in a Markdown link structure. To use it, David

  1. Switches to Safari, presumably through ⌘-Tab.
  2. Selects the URL of the current page with ⌘L.
  3. Copies it to the clipboard with ⌘C.
  4. Switches to his text editor with ⌘-Tab again.
  5. Invokes his snippet by typing its abbreviation.

He saves a little time by keeping the ⌘ key pressed through some of the steps, but there’s still too much context shifting and too many repeated keystrokes. With a little AppleScript, all he’d need is Step 5.

Here’s my first attempt,

Markdown link TE snippet

and here’s the AppleScript it uses:

applescript:
 1:  tell application "System Events"
 2:    set numSafari to count (every process whose name is "Safari")
 3:    set numChrome to count (every process whose name is "Google Chrome")
 4:  end tell
 5:  
 6:  if numSafari > 0 then
 7:    tell application "Safari" to set fURL to URL of front document
 8:  else
 9:    if numChrome > 0 then
10:      tell application "Google Chrome"
11:        set frontIndex to active tab index of front window
12:        set fURL to URL of tab frontIndex of front window
13:      end tell
14:      
15:    end if
16:  end if
17:  
18:  get "[%|](" & fURL & ")"

Lines 1-16 get the URL of the current page in either Safari or Chrome. These lines were stolen directly from my trusty ;furl snippet, whose history can be traced back to this old AppleScript I used to invoke through Quicksilver.

Line 18 does something pretty cool. It returns a string that looks something like this

[%|](http://macsparky.com/tesnippets/)

where what’s inside the parentheses is the URL of the current page. The cool part, though, is the %| inside the brackets. This is the TextExpander code for “put the cursor here after the expansion,” which is exactly what happens when this snippet is run. So this snippet gets the URL, creates the Markdown inline link and positions the cursor right where you want it to type the link text. No context shifting, no fiddling with the clipboard.

This, by the way, is why TextExpander is such a great tool. Not only can you use it to run scripts, but the output of those scripts will then be interpreted as TextExpander variables.

In fact, that last line could be written this way,

applescript:
18: get "[%filltext:name=link text:default=link text:width=32%](" & fURL & ")"

which would use a single-line TextExpander fill-in to get the link text. Unfortunately, TextExpander shows you the whole script while you’re doing the fill-in:

Fill-in in AppleScript

This works, but… blech. There’s a better way.

If you look through the popup menu that shows the TextExpander variables you can embed in a snippet, you’ll notice that all of your previously defined snippets are available, which means you can nest one snippet inside another. The best way to use a fill-in for the link text is this way:

Nested snippet for Markdown link

The content of this snippet is

[%filltext:name=link text:default=link text:width=32%](%snippet:;furl%)

where the thing in the parentheses is a call to my ;furl snippet.

When this is invoked, you see a much cleaner interface with the desired URL already in place:

Fill-in and nested snippet

Now we’re talkin’. No context shifting, no fiddling with the clipboard, and a clean fill-in interface. All you need to type is the abbreviation and the link text.

Maybe you don’t want to link to the current tab. No problem. Similar snippets can use the URLs of other tabs. I have snippets that will get the URLs of the first through the sixth tabs (counting left to right) of the frontmost Safari or Chrome window. Those could be nested just like ;furl:

[%filltext:name=link text:default=link text:width=32%](%snippet:;1url%)

What would be really nice is if these could be put into a popup menu, but TextExpander doesn’t allow that much magic yet.

I should mention that despite my love of script-driven snippets, David and Katie are exactly right when they say that TextExpander’s greatest value comes from simple, text-only snippets. There is so much repetition in business writing, especially correspondence, you’ll get your money’s worth from TextExpander even if you never exercise the AppleScript parts. (But you’ll have more fun if you do.)


Path Finder trial

I’ve tried out Path Finder a half-dozen times over the years, but I’ve always gone back to the Finder, mainly because Cocoatech never seemed to be able to prevent the Finder from worming its way back onto my screen. I started another Path Finder trial at the beginning of this week, and I’m surprised to say that I’m still using it on both of my machines. This is longer than any attempt. But that doesn’t mean I’m completely sold on it.1

The most frustrating part of Path Finder is the behavior of its bottom drawer—a feature I both love and hate. I have it set to act as a terminal, which is the default behavior, and I’ve set up a keyboard shortcut, ⌃⌥⌘B, to toggle it. It’s nice to have instant access to shell commands in the directory I’m viewing.

PathFinder Terminal drawer

Which is the first problem: the terminal access isn’t quite instant. When the bottom drawer appears, focus is not switched from the file browser to the terminal. This is inexplicable. I open the drawer because I want to type a shell command right now, and I have to believe that’s the common use case. By not handling the focus correctly, Cocoatech is creating an inefficiency in a feature that should be all about efficiency.

The aesthetics of the drawer are weird, too. The bottom edge of the file browser casts a deep shadow on the drawer, as if the drawer were far behind the browser—even when the drawer has focus. Worse, the shadow falls on the top two or three lines of the drawer, reducing the contrast between the text and the background. If I wanted to read gray on gray, I’d visit Daring Fireball.

Path Finder also seems to think that what I’m doing in one window is what I want to do from now on. I’m used to certain Finder window characteristics, like the size and the sorting order, being “sticky,” but Path Finder takes that too far. If, for example, I have the drawer open on the current window, every subsequent window I create will start with the drawer open. I don’t understand why anyone would want that.

Today I ran into the worst example of Path Finder’s drawer/terminal behavior. A USB thumb drive was attached to my iMac and a Path Finder window was showing its root directory. I needed to run a couple of shell commands in that directory, so I opened the bottom drawer and typed them in.2 Some time later I closed the window and tried to eject the drive. No dice.

PathFinder fuckup

The instance of bash that was still using that directory was the one that had been running in the bottom drawer of the window I’d closed. It should have been killed by Path Finder when I closed the window, but because it wasn’t, I was stuck with an unejectable drive. I opened Activity Monitor and rummaged through the list of processes until I found the instance of bash that was causing the trouble. I had to Force Quit it to be able to eject the thumb drive.

After some experimenting tonight, I’ve learned that in some cases I can eject the thumb drive after opening a Path Finder terminal drawer in it. It depends, bizarrely enough, on whether I close the drawer before closing the window: if I close the window without closing the drawer first, I can eject the drive; but if I close the drawer first, I can’t. This is the kind of bug that should have been wrung out of a program before it gets to version 6.5.

So I’m torn. Path Finder has become quite good at fending off the Finder, but now that I’m able to use it for an extended period, I’m running into annoyances I’d never seen in my earlier, shorter tests. On the other hand, the Finder has plenty of annoyances and limitations that Path Finder doesn’t. I’ll probably give Path Finder another week of continuous use and then return to the Finder. If the Finder seems unusable to me, I’ll know that Path Finder has won me over.


  1. Strictly speaking, I am sold. I bought it as part of some bundle last year. But you know what I mean. 

  2. After changing the focus, of course. 


Evaluating LaTeX with Eddie and Alpha

If you work in LaTeX and write numerical equations,1 this post by Eddie Smith will cause all sorts of bells to go off in your head. He shows how Wolfram Alpha will evaluate an expression given to it in LaTeX form. In other words, you can paste something like this into the Alpha expression field

\frac{\sin{\pi/4} + \sqrt{2}}{1.625^2}

and Alpha will calculate it for you.

Alpha evaluating LaTeX

Unfortunately, the Result is presented as an image rather than text,2 so you can’t just select and copy it, but you can click the “Copyable plaintext” link to have Alpha pop up a text field that you can copy the answer out of.

As Eddie says, the advantage of this is that you don’t have to keep track of two parallel sets of equations: one in LaTeX for typesetting and the other in your calculator for getting the answers. The opportunities for a typo to sneak in are greatly reduced.

Even better than copying and pasting LaTeX expressions into a web page is to use some form of automation to do it for you. Eddie shows a simple Alfred workflow that cuts out a few steps, but I don’t use Alfred. Because I do all of my LaTeX writing in BBEdit, I wanted a way to jump to the computed answer straight from there.

The key is to recognize that the URL of Alpha page looks like this

http://www.wolframalpha.com/input/?i=%5Cfrac%7B%5Csin%7B%5Cpi%2F4%7D+%2B+%5Csqrt%7B2%7D%7D%7B1.625%5E2%7D

where everything after the ?i= is a URL-encoded version of the LaTeX expression you want to calculate. With that bit of information in hand, I wrote the following Python script to use as a BBEdit Text Filter:

python:
 1:  #!/usr/bin/python
 2:  
 3:  from urllib import quote_plus
 4:  from sys import stdin
 5:  from subprocess import call
 6:  
 7:  latex = stdin.read()
 8:  alphaURL = "http://www.wolframalpha.com/input/?i=%s" % quote_plus(latex)
 9:  print latex + ' = '
10:  call(['open', alphaURL])

The URL encoding is handled by the quote_plus function of the urllib module, and the web page is opened in the default browser through the magic of Apple’s open command.

I called the script Alpha Evaluate.py and saved it in BBEdit’s Text Filters folder. The Text‣Apply Text Filter submenu is kind of clumsy to negotiate, so I assigned it the keyboard shortcut ⌃=.

BBEdit keyboard shortcut for Text Filter

Now when I’m writing an equation, I can select it (which usually means hitting ⌘⇧← to select back to the beginning of the line) and type ⌃=. This puts an equals sign after the expression and opens Alpha in my browser. Within a second or two—and with no further work on my part—the expression is evaluated and waiting for me to copy and paste into my document.

I am, of course, not entirely satisfied with this solution. What I’d really like is to automate the copying and pasting of the answer. Wolfram’s page structure doesn’t make that easy, but it’s something I want to explore.

In the meantime, I have a new tool that will save me time and frustration. Thanks, Eddie!

Update 7/11/14
It’s nice to go to bed with an unfinished problem and wake up with solutions in your Twitter feed and inbox. The solution I found most appealing was Alex Chan’s. He used the Wolfram Alpha API to get an XML version of the Alpha output and extracted the plain text answer from that.

I can think of a couple of tweaks to Alex’s script that I’m going to try:

  1. Including the lines from my script that open the Alpha web page. Seeing the page will allow me to check that Alpha interpreted the LaTeX expression the way I expected.
  2. Passing a couple of extra query parameters to the API that will limit the mass of XML output to just the results I want. This isn’t strictly necessary, but I feel bad using bandwidth for results I discard.

Thanks, Alex!

Updated update 7/11/14
My tweak of Alex’s code can be found in this Gist. Turns out™ I had a Wolfram Alpha developer ID from some time ago but had completely forgotten about it. Your memory is the second thing to go.


  1. As opposed to symbolic. Lots of people do math with no numbers. 

  2. It’s an image because, in general, the result will be an equation or a graph or something else that isn’t normally expressed as plain text.