Sat, 27 Feb 2021
Fuckin' user interface design, I swear
I'm so old I can remember when forms were introducted to the web; as you can imagine it was a big advance. The initial spec included the usual text boxes, radio buttons, and so forth, two types of “submit” buttons, and a “reset” button. Clicking “reset” would reset the form contents to a defined initial state, normally empty.
So you'd have a bunch of form widgets, and then, at the bottom, a Submit button, and next to it, a Reset button.
Even as an innocent youth, I realized this was a bad design. It is just setting people up for failure. They might get the form all filled out, be about to submit it, but click a few pixels off, hit the Reset button by mistake, and have to start all over again.
Obviously, the Submit button should be over on the left, just under the main form, where the user will visit it in due course after dealing with the other widgets, and the Reset button should be way over on the right, where it is less likely to be hit by accident.
(Or, more likely, it shouldn't be anywhere; in most cases it is nothing but an attractive nuisance. How often does someone need to reset the form anyway? How badly would they have to screw it up to decide that it would be quicker to start over than to simply correct their errors?)
Does my “obviously” come across as superior and condescending? Honestly, it comes from a place of humility. My thinking is like this:
- The field of user inteface design is skilled work
- I have no training or experience in this field
- Also, I have no talent in design generally (Just look at this page!)
- Experience has proved that I am very stupid about this whole area
- But this particular problem is apparent even to a blockhead like me
- So it must be extremely obvious
But maybe I'm not giving myself enough credit. I said “obviously” but it sure wasn't obvious to many people at the time. I remember 90% of the forms I encountered having that Reset button at the bottom, at least into the late 1990s.
And it's on my mind because my co-workers had a discussion about it at work last week: don't put the Cancel button right next to the Submit button. If this was obvious to dumbass me in 1994, why isn't it common knowledge by now?
Don't put the Yes button right next to the No button. That encourages mistakes. Obviously.
Don't put the commonly-used "close this window" keyboard shortcut right next to the infrequently-used and irreversible "quit this application" shortcut. In particular, don't put "close this window" on control-W and "quit this application" on control-Q. I'm looking at you, Firefox.
And that brings me to my real point. Can we talk about Google Meet?
These three buttons are at the bottom of the Google Meet videoconferencing app. The left one temporarily mutes and unmutes the microphone. The right one controls the camera similarly.

And if you click the button in between, you immediately leave the meeting and quit the app.
Now, as I said I'm pretty damn stupid when it comes to design, but geez, louise. Couldn't Google find someone less stupid than me?
[ Addendum 20210228: Google fucks up again. ]
[Other articles in category /tech] permanent link
Tue, 16 Feb 2021Katara is toiling through A.P. Chemistry this year. I never took A.P. Chemistry but I did take regular high school chemistry and two semesters of university chemistry so it falls to me to help her out when things get too confusing. Lately she has been studying gas equilibria and thermodynamics, in which the so-called ideal gas law plays a central role: $$ PV=nRT$$
This is when you have a gas confined in a container of volume !!V!!. !!P!! is the pressure exerted by the gas on the walls of the container, the !!n!! is the number of gas particles, and the !!T!! is the absolute temperature. !!R!! is a constant, called the “ideal gas constant”. Most real gases do obey this law pretty closely, at least at reasonably low pressures.
The law implies all sorts of interesting things. For example, if you have gas in a container and heat it up so as to double the (absolute) temperature, the gas would like to expand into twice the original volume. If the container is rigid the pressure will double, but if the gas is in a balloon, the balloon will double in size instead. Then if you take the balloon up in an airplane so that the ambient pressure is half as much, the balloon will double in size again.
I had seen this many times and while it all seems reasonable and makes sense, I had never really thought about what it means. Sometimes stuff in physics doesn't mean anything, but sometimes you can relate it to a more fundamental law. For example, in The Character of Physical Law, Feynman points out that the Archimedean lever law is just an expression of the law of conservation of energy, as applied to the potential energy of the weights on the arms of the lever. Thinking about the ideal gas law carefully, for the first time in my life, I realized that it is also a special case of the law of conservation of energy!
The gas molecules are zipping around with various energies, and this kinetic energy manifests on the macro scale as as pressure (when they bump into the walls of the container) and as volume (when they bump into other molecules, forcing the other particles away.)
The pressure is measured in units of dimension !!\frac{\rm force}{\rm area}!!, say newtons per square meter. The product !!PV!! of pressure and volume is $$ \frac{\rm force}{\rm area}\cdot{\rm volume} = \frac{\rm force}{{\rm distance}^2}\cdot{\rm distance}^3 = {\rm force}\cdot{\rm distance} = {\rm energy}. $$ So the equation is equating two ways to measure the same total energy of the gas.
Over on the right-hand side, we also have energy. The absolute temperature !!T!! is the average energy per molecule and the !!n!! counts the number of molecules; multiply them and you get the total energy in a different way.
The !!R!! is nothing mysterious; it's just a proportionality constant required to get the units to match up when we measure temperature in kelvins and count molecules in moles. It's analogous to the mysterious Cookie Constant that relates energy you have to expend on the treadmill with energy you gain from eating cookies. The Cookie Constant is !!1043 \frac{\rm sec}{\rm cookie}!!. !!R!! happens to be around 8.3 joules per mole per kelvin.
(Actually I think there might be a bit more to !!R!! than I said, something about the Boltzmann distribution in there.)
Somehow this got me and Katara thinking about what a mole of chocolate chips would look like. “Better use those mini chips,” said Katara.
[Other articles in category /physics] permanent link
Mon, 15 Feb 2021Today someone tweeted about an earlier blog article of mine, saying
10° bir kvadratda ən böyük şəhərləri görə biləcəyiniz bir xəritə olan bir sayt.
I looked at that and frowned, and said “What language is that? … is it Azerbaijani?” And it is Azerbaijani! Last time I encountered Azerbaijani I did not recognize it. So I not only learned something last April, I remembered it the following February when it came up again. Yay me!
[Other articles in category /lang] permanent link
Sat, 13 Feb 2021Yesterday I wondered who Robert Altman had cast as Bluto in his 1980 live-action film Popeye. The answer turned out to be Paul L. Smith, who seemingly was born to play the part:
I have thought for years about how Shelley Duval was seemingly born to play the part of Olive Oyl. (I remember the Mad magazine parody making this observation at the time, and it wasn't funny because it was so obvious.) I have somtimes wondered if Altman got the idea to make a Popeye movie specifically so that he could cast Duval as Olive Oyl.
Anyway, Paul L. Smith, who already looked like Bluto. He was in a fair number of TV productions in the 70s and 80s, and I think it's possible that I saw him in one or another one. But the only other role of his that I remember clearly is from David Lynch's 1984 Dune. He plays Glossu “the Beast” Rabban. Who in many ways is not that different from Bluto: Large, violent, dangerous for his brutality but not his cunning.
Obviously the Baron wanted to cast Feyd-Rautha as Popeye, but events got away from him and Paul became Popeye instead. In a Dune-Popeye crossover I can see Alia as Swee'Pea. That means that Chani has to be Olive, which I can live with.
The correspondence isn't perfect, of course. There is nobody in Popeye like Lady Jessica or Stilgar. (Leto is obviously Poopdeck Pappy.) On the other side, where is J. Wellington Wimpy? It's been a while since I read the book, but I don't remember him appearing. Reverend Mother Gaius Helen Mohiam is clearly the Sea Hag.
Me spinach musk flow! If ya controlsk the spinach, ya controlsk the uni-voice! Ag-ag-ag-ag-ag!
[Other articles in category /misc] permanent link
Mon, 08 Feb 2021I was reading The Life and Prankes of Long Meg of Westminster (1655), which opens with the story of how Long Meg first came to London with a posse of three or four girlfriends. After long travel they came within sight of London, “which joyed their hearts greatly.” But as they got closer, Meg's friends became less cheerful, and she said to them:
What Lasses in a dumpe, and we so nigh London?
If someone had asked me to guess when “in a dump” or “in the dumps” had been coined, I think I would have guessed sometime in the early 20th century. Nope! The Big Dictionary has cites back to 1535, which is when Long Meg takes place. It also cites a 1785 dictionary for “down in the dumps” specifically. The phrase is not connected with the dump where you dump a load of trash, which is of much later coinage.
It transpires that the lasses are in a dumpe because they realize that time has come to pay the carrier who has helped transport them to London, and believe he is likely to try to cheat them and take everything they have. Meg says she will reason sweetly with the carrier, and if that doesn't work, she will beat the crap out of him.
The carrier does try to take everything they have, but becomes much more helpful after Meg has beaten him with a cudgel.
Here it is if you would like to read it yourself.
[Other articles in category /lang] permanent link
Sun, 07 Feb 2021
More things that changed in later editions of Snow White
As you know, I've recently been looking into the original version of Snow White from 1812. ([1] [2]) I knew that the 1812 version of the Grimm stories was a lot rougher and more gruesome than the later editions, but I missed many of the details. For example, in the later versions, the evil queen orders her hunter to bring back Snow White's liver and lungs as proof that he has murdered her. In the first edition, she wants the liver and lungs so that she can eat them.
After Snow White is poisoned with the apple, the dwarfs put her in a glass coffin. A prince happens by and begs them to give it to him, which they do. In the later versions, the servants carrying away the coffin stumble, the apple is dislodged from Snow White's throat, and she returns to life.
In the original version, they get the coffin back to the prince's palace without mishap. There the prince has the servants carry it from room to room so that he can gaze at it always. (Ugh.)
Finally, the servants are so fed up with this that one of them takes Snow White out of the coffin, stands her up, and, saying
We are plagued the whole day long, just because of such a dead girl
he clouts her in the back from pure spite.
The apple is dislodged, and Snow White marries the prince.
[Other articles in category /book] permanent link
Sat, 06 Feb 2021Git comes with
a very complicated shell function,, called
__git_ps1,
for interpolating Git information into your shell prompt. A typical
use would be:
PS1='>>> $(__git_ps1) :) '
PS1 is the variable that contains the shell's main prompt. Before
printing the prompt, the shell does variable and command interpolation
on this string. This means that if PS1 contains something like $(command
args...), the shell replaces that string with the output from running
command args…. Here, it runs __git_ps1 and inserts the output into the
prompt. In the simplest case, __git_ps1 emits the name of the
currently-checked-out branch, so that the shell will actually print
this prompt:
>>> the-branch :)
But __git_ps1 has many other features besides. If you are in the middle
of a rebase or cherry-pick operation, it will emit something
like
the-branch|REBASE-i 1/5
or
the-branch|CHERRY-PICKING
instead. If HEAD is detached, it can still display the head
location in several formats. There are options to have the emitted string
indicate when the working tree is dirty and other things. My own
PS1 looks like this:
PS1='[$(_path) $(__git_ps1 "(%s)" )]> '
The _path command is something I
wrote to emit the path of the current working directory, abbreviated
in a contextually dependent way. It makes my prompt look like this:
[lib/app (the-branch)]>
Here lib/app is the path relative to the root of the repository.
The %s thing is an additional formatting instruction to __git_ps1.
After it computes the description string, __git_ps1 inserts it into
"(%s)" in place of the %s, and emits the result of that
replacement. If you don't give __git_ps1 an argument, it uses "(%s) "
as a default, which has an extra space compared with what I have.
Lately I have been experimenting with appending .mjd.yyyymmdd to my
public branch names, to help me remember to delete my old dead
branches from the shared repository. This makes the branch names
annoyingly long:
gh1067-sort-dates-chronologically.mjd.20210103
gh1067-sort-dates-no-test.mjd.20210112
gh1088-cache-analysis-list.mjd.20210105
and these annoyingly long names appear in the output of __git_ps1 that is
inserted into my shell prompts.
One way to deal with this is to have the local branch names be
abbreviated and configure their upstream names to the long versions.
And that does work: I now have a little program called new-branch
that creates a new branch with the local short name, pushes it to the
long remote name, and sets the upstream. But I also wanted a generic
mechanism for abbreviating or transforming the branch name in the
prompt.
The supplied __git_ps1 function didn't seem to have an option
for that, or a callback for modifying the branch name before inserting
it into the prompt. I could have copied the function, modified the
parts I wanted, and used the modified version in place of the supplied
version, but it is 243 lines long, so I preferred not to do that.
But __git_ps1 does have one hook. Under the right circumstances,
it will attempt to colorize the prompt by inserting terminal
escape codes. To do this it invokes __git_ps_colorize_gitstring to
insert the escape codes into the various prompt components before it
assembles them. I can work with that!
The goal is now:
- Figure out how to tell
__git_ps1to call__git_ps_colorize_gitstring - Figure out how
__git_ps1and__git_ps_colorize_gitstringcommunicate prompt components - Write my own
__git_ps_colorize_gitstringto do something else
How to tell __git_ps1 to call __git_ps_colorize_gitstring
You have to do two things to get __git_ps1 to call the hook:
Set
GIT_PS1_SHOWCOLORHINTSto some nonempty string. I set it totrue, which is a little deceptive, becausefalsewould have worked as well.Invoke
__git_ps1with two or more arguments.
Unfortunately, invoking the __git_ps1 with two or more arguments changes
its behavior in another way. It still computes a string, but it no
longer prints the string. Instead, it computes the string and
assigns it to PS1. This means that
PS1="$(__git_ps arg arg….)"
won't work properly: the next time the shell wants to prompt, it will
evaluate PS1, which will call __git_ps arg arg…, which will set
PS1 to some string like (the-branch). Then the next time the
shell wants to print the prompt, it will evaluate PS1, which will be
just some dead string like (the-branch), with nothing in it to call
__git_ps1 again.
So we need to use a different shell feature. Instead of setting PS1
directly, we set PROMPT_COMMAND. This command is run before the
prompt is printed. Although this doesn't have anything to do directly
with the prompt, the command can change the prompt. If we set
PROMPT_COMMAND to invoke __git_ps1, and if __git_ps1 modifies PS1, the
prompt will change.
Formerly I had had this:
PS1='[$(_path) $(__git_ps1 "(%s)")]> '
but instead I needed to use:
GIT_PS1_SHOWCOLORHINTS=true
PROMPT_COMMAND='__git_ps1 "[$(_path) " " ] "' "(%s)"
Here __git_ps1 is getting three arguments:
"[$(_path) "" ] ""(%s)"
__git_ps1 computes its description of the Git state and inserts it into
the third argument in place of the %s. Then it takes the result of
this replacement, appends the first argument on the front and the
second on the back, and sets the prompt to the result. The shell will
still invoke _path in the course of evaluating the first string,
before passing it to __git_ps1 as an argument. Whew.
How __git_ps1 communicates prompt components to __git_ps_colorize_gitstring
The end result of all this rigamarole is that __git_ps1 is now being
called before every prompt, as before, but now it will also invoke
__git_ps_colorize_gitstring along the way. What does that actually get us?
The internals of __git_ps_colorize_gitstring aren't documented because I don't think this
is a planned use case, and __git_ps_colorize_gitstring isn't an advertised part of the
interface. __git_ps1 does something to construct the prompt, possibly
colorizing it in the process, but how it does the colorizing is
forbidden knowledge. From looking at the code I can see that the
colorizing is done by __git_ps_colorize_gitstring, and I needed to know what was going in
inside.
The (current) interface is that __git_ps1 puts the various components of
the prompts into a family of single-letter variables, which __git_ps_colorize_gitstring
modifies. Here's what these variables do, as best as I have been able
to ascertain:
bcontains a description of the current HEAD, either the current branch name or some other description
cindicates if you are in a bare repository
iindicates if changes have been recorded to the index
pcontains information about whether the current head is behind or ahead of its upstream branch
rdescribes the rebase / merge / cherry-pick state
sindicates if there is something in the stash
uindicates whether there are untracked files
windicates whether the working tree is dirty
zis the separator between the branch name and the other indicators
Oddly, the one thing I wanted to change is the only one that __git_ps_colorize_gitstring
doesn't modify: the b variable that contains the name or
description of the current branch. Fortunately, it does exist and
there's nothing stopping me from writing a replacement __git_ps_colorize_gitstring that
does modify it.
Write a replacement for __git_ps_colorize_gitstring to do something else
So in the end all I needed was:
GIT_PS1_SHOWCOLORHINTS=true
PROMPT_COMMAND='__git_ps1 "[$(_path) " " ] "' "(%s)"
__git_ps1_colorize_gitstring () {
b=${b%%.[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]}
b=${b%%.mjd}
}
The ${b%%PAT} thing produces the value of the variable b, except
that if the value ends with something matching the pattern PAT, that
part is removed. So the first assignment trims a trailing
.20210206 from the branch name, if there is one, and the second
trims off a trailing .mjd. If I wanted to trim off the leading gh
also I could use b=${b##gh}.
There's probably some way to use this in addition to the standard
__git_ps_colorize_gitstring, rather than in place of it. But I don't know how.
In conclusion
This was way harder to figure out than it should have been.
[Other articles in category /prog] permanent link
Wed, 03 Feb 2021Katara and I went to visit the town of Gap, PA. In Gap there are so many eagles that they have these special bins for getting rid of the extras.
[Other articles in category /misc] permanent link
Tue, 02 Feb 2021This is the famous self-portrait of Hildebert, a 12th century scribe in what is now the Czech Republic. In this picture, Hildebert is shaking his fist at a mouse, which is eating his lunch.

There is quite a lot going on here! First off, Hildebert is carrying one of his quill pens behind his ear. This seems to me like a good way to get ink in your hair, and I wonder if medieval scribes often had smudges on their forheads.
I think the thing in his hand is a piece of bread. But what is on the table? I think the mouse is eating Hildebert's cheese (we can see the already-cut piece under the mouse's butt) and there seems to have been a small roast bird of some type, which the mouse has upset but which has not yet hit the floor. The table with the mouse is labeled Mensa hildeberti, “Hildebert's table”, in case it was unclear just whose lunch was being stolen.
Hildebert seems to be wearing a long garment with fancy matching sleeves and collar, and over that what looks like a chiton. I wonder if Hildebert really wore a chiton?
On the left of the picture is a really interesting piece of equipment. Until I saw this picture, it had never occurred to me that the lap desk had been invented before I was born. But here it is, almost nine hundred years ago. And it certainly is a lap desk, having no legs. In this picture the lap desk is supported by a backward-headed lion, but in actual practice such luxuries are probably hard to come by, so Hildebert would have put the desk on his lap.
The two long curvy things on the left edge of the lap desk are not legs. They are inkhorns: sawn-off animal horns, filled with ink. When you need to get more ink on your quill, you dip the end in the inkhorn. I had heard of inkhorns but until I saw this picture I had never understood how you used them: they won't stand up, and if you lay them down the ink will spill. But Hildebert's picture makes it perfectly clear: the lap desk has a couple of round holes in it, and you slide the inkhorns into the holes until they stop. Very nice! Next to the inkhorns are two extra quills, and along the bottom edge of the lap desk there is a ridge to keep the paper or parchment from sliding into your lap. I am pretty sure that the lion is holding the desk by the bottom edge, so that it is presented to Hildebert sideways. Hildebert is too enraged by the mouse to care about this.
Also on the desk is a booklet, in which (according to Wikipedia) Hildebert has written:
Pessime mus, saepius me provocas ad iram. Ut te deus perdat
I think I can make this out. (Medieval scribes used a great many abbreviations. For example, iram is written as “irã”. Similarly, the hildeberti above the table is abbreviated to “hildebti”. If you are interested, I discussed scribal abbreviations a couple of years ago.)
Wikipedia's translation of this is:
Most wicked mouse, you incite me to anger once too often. May God destroy you.
I think the phrasing and the fist-shaking, directed at a mouse, are meant by Hildebert to be a humorous overreaction.
Underneath Hildebert is a drawing of his colleague Everwin (EVERWINVS). Everwin seems to be painting some sort of decoration with a brush. Check out his fancy sleeves and matching socks!
I am not sure what Hildebert is holding in his left hand or whether it intersects the lion's arm. My best guess is that it is Hildebert's table knife, and that the picture means to show it passing in front of the lion, not intersecting the lion.
Many thanks to Marnanel Thurman for bringing this to my attention.
[Other articles in category /art] permanent link
Mon, 01 Feb 2021
The magic mirror in Snow White
A few weeks ago I was thinking about Snow White and in the course of doing that I looked up the original German version of 1812. (Snow White herself is story #53, on page 238.)
The magic mirror is introduced this way:
Die Königin … hatte auch einen Spiegel, vor trat sie alle Morgen und fragte: …
(“The queen… also had a mirror, before which she stood every morning and asked…”)
The mirror is simply einen Spiegel, a mirror, not a specifically magic mirror. That seems to have been a later interpolation. In the 1857 edition, it says Sie hatte einen wunderbaren Spiegel…. There is no wunderbaren in the original.
I prefer the original. The mirror recites poetry; to say it is a magic mirror is superfluous.
But on second thought, is it? There is another explanation: in the original version, perhaps the mirror is an ordinary one, and the queen is psychotic.
Certainly nobody else hears the mirror speaking. And the queen tells the hunter not only to kill Snow White in the forest, but to bring back Snow White's lungs and liver, so that the she may eat them. With salt! (die will ich mit Salz kochen und essen.) Now I prefer the original even more. The later version, which unequivocally states that the mirror is magic, is much less terrifying.
I suppose the argument against this reading is that the mirror also provides the queen with real information: Snow White is still alive, and living with the seven dwarfs. I think the original text does imply that the queen was aware of the seven dwarfs, but how might she have known that Snow White was still alive? Well, she did eat the lungs and liver, which had actually come from a young wild boar (junger Frischling). Perhaps she was satisfied at first, but then there was something about the taste, or the texture, not quite what she expected… it gnawed at her for hours, and then in a flash of rage she realized what she had actually eaten…
[ Addendum 20210202: In case you wanted to see it,

Note, by the way, that in 1812 the umlaut marks in Königin etc. still looked like small letter ‘e’; they had not yet been reduced to diareses. ]
[ Addendum 20210207: another startling detail that was revised in the later editions. ]
[ Addendum 20210321: The more I think about the queen's psychosis, the more obvious it seems that this is the correct explanation. ]
[Other articles in category /book] permanent link






