It looks like my 2011 iMac might be on the way out. I’ve been having odd graphical problems today and yesterday, and I think that it might be the graphics card overheating. Running Apple Diagnostics (Hardware Test as was) reports an error with the hard drive (the fan specifically) which I’ve seen before. My working theory at this point is that a failed or obstructed fan coupled with dust build-up and the fairly hot room has led to this point.

Photo of an iMac where part of the right-hand section of the screen image is displayed physically on the left

I’m going to get some compressed air and see if that helps matters at all, and then see if I can get it serviced. Unfortunately Apple now lists the 2011-model iMac as obsolete (or “vintage”) so we’ll see how that goes.

Funnily enough, this is not the original graphics card but a replacement installed by Apple when something similar (but not quite the same) happened several years ago, sorted out just before their replacement period ended (it was an acknowledged, somewhat widespread problem with the cards).

Honestly it’s happened at a bit of a naff time. The machine is otherwise fine, and it still feels incredibly fast (which I put down to the SSD). I was hoping it would last as long as many of the machines we have at work, almost all of which are from 2008 (despite what other press reports claim), though they do feel sluggish — particularly the couple that I (foolishly) upgraded past OS X 10.6. I was certainly not planning to replace it yet.

It would be an expense that I could do without too — having just bought a real chair and weird keyboard in anticipation of having to do much more work at home from October when I start an evening Masters in Computer Science at Birkbeck.

Which brings us neatly to the real annoyance about this: I was planning to buy a laptop to use on the course. I’ve bought a couple of bottom-end MacBook Airs for reporters at work, and they seem like decent enough machines. This idea was on the assumption that it would not be my main computer, so it could be less capable as I would be using it for focused tasks and leaving everything else — including much of the academic work of the course — to be done on my giant iMac at home.

But if the iMac isn’t in the picture anymore, what should I do? As I see it, I have two feasible options:

  • Buy a more capable laptop as my main computer.
  • Buy a basic laptop and a new iMac.

I spent a lot of money on the 27" iMac in October 2011, buying more than I needed really (partly because I was still playing computer games then). I wouldn’t replace it with something as high-end now as I know that I just don’t need the power, and I want to minimise the hit to my savings.

Part of me thinks that I should buy a MacBook Air now, according to plan but sooner than planned. Then I have something to tide me over other than a six-year-old iPad (running iOS 9!) and a five-year-old iPhone 5S, and then I can try to get the iMac fixed or replace it at a later date. (I’m also a bit anxious to buy the Air sooner rather than later, even though it’s still basically an old design, as I don’t really want to risk having to buy a laptop with a dodgy keyboard and only a couple of those odd USB-C sockets.)

Then the other option is to shelve completely the idea of buying another desktop and just buy a more powerful laptop. This appeals to me less, because I do want a bigger screen and I do want more storage.

I’ve been throwing the storage matter around in my head today and I can’t decide on a position. Backblaze tells me I have 530GB backed up, most of which is my iTunes library, so I don’t know if it’s a bit of a distraction — if I only had a laptop I’d have to keep it on an external drive at home, and is that so different from keeping it only in an iMac on my desk?

It’s difficult to know what to do. My gut feeling is to rush out and buy a basic Air immediately so as to not interrupt my life too much (particularly, I need to change jobs before the course starts as the hours don’t fit; this is not a secret to my boss or colleagues).

But my head says that I should see if I can crack on using my iPad for now, enquire about getting the iMac serviced as soon as possible, and then make a more considered decision at a later time.

It’s not a comfortable position for me, since this machine has been a fixture in my life for over six-and-a-half years. When the graphics card went last time, it was calming to know that it was a problem that Apple had committed to take care of (even if I almost missed the cutoff and had to drag the heavy thing all the way to Chafford Hundred on the train). No such luck this time.

(On a, er, positive note, I guess this will finally force me to work out a way of blogging from my iPad that isn’t as painful as I’m sure it will be to get this post up. [Later: It took some faffing about and too much manual work, but having (an old version of) Coda and shell access to my Linode server did the trick fine.])

My post detailing a Keyboard Maestro macro to open Jupyter notebooks had a dumb bug in the second shell pipeline, which fetches the URL of the desired notebook.

You’d hit it if:

  • You have more than one notebook server running.
  • The working directory of one is beneath another.
  • The subdirectory server was started more recently.
  • You tried to open the parent server with the macro.

The shorter path of the parent would match part of the child’s path.

The original grep pattern was:

grep "$KMVAR_dir"

And is now:

grep ":: $KMVAR_dir$"

So that it only matches the exact directory chosen in the list prompt, and not one of its children.

I’ve updated the Keyboard Maestro macro file too.

When I use images here, I tend to give ones without any transparency a border, which is done using CSS and applied to img tags unless they have a no-border class.

Like a good web citizen, I also specify image dimensions in HTML:

“The image’s rendered size is given in the width and height attributes, which allows the user agent to allocate space for the image before it is downloaded.”

In fact my BBEdit image snippet makes it a doddle:

<p <#* class="full-width"#>>
    <img
        src="/images/#SELECTIONORINSERTION#"
        alt="<#alt text#>"
        <#* class="no-border"#>
        width=<#width#>
        height=<#height#>
        />
</p>

But this causes a problem, which I’ve spotted in a couple of my recent posts.

If you specify the image dimensions, and use a CSS border, and have your CSS box-sizing set to border-box, then the CSS border shrinks the amount of space available to the image to its specified dimensions − 2 × the border width.

So if you specify your img dimensions to match the dimensions of the file, then the image itself will be shrunk within the element.

This animation shows this situation, and what happens when you toggle the CSS border. Watch what happens to the image itself.

An animation showing an image being squeezed within the space it has been allocated, causing distortion.

(It’s got a slight offset from the text because it’s a screenshot of this blog and includes some of the background on each side.)

In contrast, this animation shows what happens when the dimensions are not specified, and so the image is free to grow when the border is applied:

An animation showing an image growing when a CSS border is applied, with no distortion to the image itself.

Really the culprit here is box-sizing: border-box, forcing the border to remain within the size of the img element itself. This is a behaviour you actually want, as it solves the old CSS problem of juggling widths, borders and padding within a parent element. Check out MDN’s box-sizing page to see what I mean.

What are my options, then?

  • Change box-sizing.

    I’m not touching this because the potential sizing headaches are not worth it, even just for img elements.

  • Apply a border to the image files themselves.

    No, because if I change my mind about the CSS, previously posted images are stuck with the old style forever. CSS borders should also work correctly across high-density displays, whereas a 1px border in the file may not.

  • Don’t specify dimensions in the HTML.

    I don’t like the idea of making pages of this site slower to render, but I think this is the least bad option, particularly given that this site is already pretty fast.

It’s not ideal, but that BBEdit snippet is now just:

<p <#* class="full-width"#>>
    <img
        src="/images/#SELECTIONORINSERTION#"
        alt="<#alt text#>"
        <#* class="no-border"#>
        />
</p>

Hey, at least it makes images quicker to include in posts!

I have a startup item that launches a Jupyter notebook so that the server is always running in the background. It’s an attempt to reduce the friction of using the notebooks.

By default, Jupyter starts the server on port 8888 on localhost, but expects a token (a long hexadecimal string) before it’ll let you in. If you list the currently running servers in the terminal you can see the token and also the server’s working directory.

% jupyter-notebook list
Currently running servers:
http://localhost:8889/?token=…hex… :: /Users/robjwells
http://localhost:8888/?token=…hex… :: /Users/robjwells/jupyter-notebooks

We can use this to make finding and opening the particular notebook server you want a bit easier, using Keyboard Maestro.

A screenshot showing the (minimised) Keyboard Maestro steps

The macro uses the jupyter-notebook command, so that’ll need to be in your $PATH as Keyboard Maestro sees it.

The first and third steps both execute jupyter-notebook list and use Unix tools to extract parts from it.

In between, if there’s more than one notebook server running, the macro prompts the user to choose one from a list of their working directories.

A Keyboard Maestro list selection dialogue

Here’s the first step, where we fetch the list of working directories.

jupyter-notebook list | tail -n +2 | awk '{print $3}'

Our +2 argument to tail gets the output from the second line, chopping off the “Currently running servers:” bit. Then awk prints the third field, which contains the directory. (The first is the URL, the second the double-colon separator.)

The third step fetches the corresponding URL for a directory:

jupyter-notebook list | grep ":: $KMVAR_dir$" | awk '{ print $1 }'

Since the user has specified a directory already, we use grep with the Keyboard Maestro variable to find just that one line, and use awk again to extract the URL field.

Update:

There was a bug in the original version of this snippet of shell script, where a parent path could match a child path (as it was only looking for the path itself without an anchor on either side). It was only luck that had me miss this with my example, with the more recently started home directory notebook server being listed ahead of one in a subdirectory, which grep would have also matched. The code above and the macro file have been fixed.

Obviously, this won’t work if you have more than one notebook server running from the same directory. (But you wouldn’t do that, right?)

Here’s the macro file if you’d like to try it out.

After I published my post about manipulating tables (of data) in R, I noticed that there was something amiss with the HTML table in that post showing an example section of our newsroom rota.

A screenshot showing a table laid out with table-layout: fixed in CSS, with many cells wrapping with scrollbars in an unreadable fashion.

When I first wrote the CSS for this site, roughly five years ago, I had HTML tables set so that the whole table would scroll were it to be too wide for its containing column. At least, I’m pretty sure it worked like that.

Anyway, as you can see above, it doesn’t work like that now. The table there is laid out with the following CSS:

table {
  table-layout: fixed;
  width: 100%;
}

Which has the effect of restricting the table size to 100%, and doing odd things to the cells if there’s too much to fit in whatever width 100% happens to be.

As an attempted quick fix, I removed the table-layout property so that it would inherit the default, auto. The width is still 100% to provide some consistency, rather than having an odd assortment of table widths.

So the CSS is now this:

table {
  width: 100%;
}

This has the effect of having the table overflow the container horizontally if the content is too wide, like so:

A screenshot showing a table laid out with table-layout: auto in CSS, with the table overflowing its container horizontally.

Which is perhaps more readable if pretty ugly. And not what I wanted: to scroll the entire table within its container.

I said attempted earlier because I, er, never deployed the change on the site (it’s been a busy couple of weeks, contrary to the post tempo).

In the meantime, I stumbled across a fix by opening Safari’s reader mode, in which tables scroll horizontally within their container! The secret? The table is wrapped in an enclosing div, which has its overflow-x property set to auto, and then the table scrolls within the div.

Here’s what that looks like when rendered:

A screenshot showing a table laid out and scrolling within a containing div with its overflow-x property set to auto.

Here’s the HTML:

<div class="table-container">
  <table>
  …
  </table>
</div>

And here’s the CSS:

table {
  width: 100%;
}

.table-container {
  overflow-x: auto;
}

You want auto instead of scroll as the latter shows the scrollbar all the time.