Resurrecting an Apple Lisa

I own three Apple Lisas, collected in the early 1990s from the closets of people and organizations that no longer wanted them. The collection includes a Lisa 2, a Lisa 2/5 and a Lisa 2/10 (slash Mac XL, the hardware was identical). At one time all three worked, but the Lisa 2 broke down about 15 years ago and I haven’t used any of them since. David Pogue recently published a piece commenting on the tenth anniversary of his technology column in The New York Times, saying that we should “forget about forever, nothing lasts a year.” Allowing for a certain amount of hyperbole, this may be true in a commercial sense — technology and standards are quickly replaced. However, we have nothing to celebrate in this constant obsolescence.

I refer not only to the waste associated with constant upgrading, but to the lack of character associated with new gadgets. People think they define themselves by their purchases, but anybody with a credit card can get an iPhone. The only objects that really express our characters are the ones we make ourselves, or have made for us. And while not quite so distinctive as something you’ve made yourself, objects abandoned or unappreciated by others, but kept vital through your efforts, say a lot more than any new portable computer/laptop/notebook/netbook/handheld/tablet/whatever.

I sometimes print with a 1983-vintage “letter quality” printer. I doesn’t have a sheet feeder, so I’m forced to keep letters short. And last night, I decided to try to bring the Lisas back to life. In an initial survey, it looks like one of the three power supplies still works (1.8 amp, luckily; the 1.2 amp models were never great even at their best). The dual parallel port card works. One of the internal hard drives works (10Mb), as does the external profile drive (5Mb). The third drive fails with “error 82.” Unfortunately, I have no application software on the working internal drive, just the Lisa “office system” operating system, and the external profile is blank. So I either need to bring the third hard drive back to life, or create Lisa floppies for reinstalling the “7/7” application suite and hope I have a working floppy drive, or use an x/profile drive replacer. I have not yet been able to get a keyboard to work with the one working machine, so I either have bad keyboards or something wrong inside the box where keyboard input is processed.

Apple Lisa

Apple Lisa 2/10, November 2010

If I can install LisaTerm, get a keyboard working, and secure the appropriate cables, I will bring the Lisa online as a terminal. Pogue may say nothing lasts a year, but it will soon be 28 years for this machine and I think I can make it work.

Mental defectives, part ii

I did on a previous occasion write about the seemingly powerful relationship between the number of radios in the U.K, and the number of registered mental defectives in that country. In Google books, I recently found a 1958 book titled Principles of Statistical Techniques, which contains examples based on that remarkable dataset, the number of mental defectives in England and Wales.

The passage in question uses the “mental defectives” data from 1935 through 1946 to illustrate the ability to mislead through the use of graphs and charts. The graphs below are courtesy of Mathematica but closely replicate those in the original text.

In[]:= mentalDefectives = {{1935, 86086}, {1936, 88060}, {1938,
92299}, {1939, 99144}, {1940, 101364}, {1941, 100876}, {1942,
98125}, {1943, 98434}, {1944, 99608}, {1945, 102225}, {1946,
102390}};

In[]:= ListPlot[mentalDefectives, PlotRange -> {86000, 102500},
AxesOrigin -> {1934, 86000},
AxesLabel -> {"Year", "Number of\nmental defectives"},
AspectRatio -> 2, PlotMarkers -> {Automatic, Small}]

tall skinny graph

In[]:= ListPlot[mentalDefectives, PlotRange -> {0, 120000},
AxesOrigin -> {1935, 0},
AxesLabel -> {"Year", "Number of\nmental defectives"},
PlotMarkers -> {Automatic, Small}]

wider graph

As explained in the original text, “The impression obtained from the first graph is that there was a staggering rise in the number of mental defectives in little more than a decade, whereas the second graph gives the impression of a much slower and more gradual increase. These rather different impressions are obtained, of course, by tampering with the horizontal and vertical scales used. . . . it is essential to recognize the importance of supplying graphs, as well as tables, with full and clear labelling and if possible, the source of the information.”

Frankly, their efforts seem pretty basic. We could further steepen the first graph through population adjustment, adjustment for number of doctors, and other techniques.

In googling for more on this remarkable dataset, I found letters to the editor of The British Medical Journal in which one R.A. Gibbons of London, S.W., argues that forced sterilization of mental defectives is not sufficient to protect “the race,” and that it is necessary to sterilize also those people who “from pronounced family history” are certain to “produce idiots.” Dr. Gibbons apparent delivered a paper on this topic to the Obstetrical Section of the Royal Society of Medicine and had in published in the Journal on March 18, 1922. In this letter, he refers to “over 12,000 registered mental defectives for whom [British citizens] are taxed.”

The reference to taxation feels terribly modern (“certainly their plight tugs at the heartstrings, but you just can’t care for everybody and it wouldn’t be fiscally prudent to allow them to run amok.”)

Germany is most famous for eugenics programs, but similar sterilizations of mental defectives were taking place in the United States in the early and mid 20th century. I’ll leave that for another post.

clock hands, part ii

I posted a request to mathgroup asking for guidance on why Solve[] and its brethren failed on the puzzle of the opposing clock hands. Two people have already responded with working versions from which we can draw the following conclusions,

1. We have to unwind the linedupedness[], unitTimeToHourAngle[], and unitTimeToMinuteAngle[] functions, and

2. We need to restrict the domain of the solution to the range from 0 to 1.

When we do this, we go from

In[]:= Reduce[unstraightness[unitTime] == 0 && 0 < unitTime < 1]
to
In[]:= Solve[Abs[Abs[4320 Mod[unitTime, 1/12] - unitTime*360] - 180] == 0 &&
0 < unitTime < 1, unitTime]

which does indeed produce the right answer. There are other ways to get there too; unwinding and restricting the solution to Reals or Rationals will work, though we get some redundant solutions that way.

Wolfram tech support had an even nicer solution, pointing out that my wrapper function (unstraightness[]) could take any kind of input, while the internal functions (unitTimeToHourAngle[] and unitTimeToMinuteAngle[]) are restricted to real numbers. This means that when these functions are introduced into the Reduce function, unitTime is not defined as a number, so the function is never evaluated. The simplest solution is just to change the definition of the internal functions to

In[]:= minuteAngle[unitTime_] := 4320 Mod[unitTime, 1/12]
and
In[]:= hourAngle[unitTime_] := unitTime*360 // N

whereupon

In[]:=Reduce[Abs[minuteAngle[unitTime] - hourAngle[unitTime]] == 0 &&
0 < unitTime < 1]

works like a charm.

Opposing clock hands

I was recently sitting in a poorly produced play called That Hopey Changey Thing when, looking wistfully at my watch, I noticed that the hour hand and the minute hand were perfectly lined up, pointing in opposite directions. I stayed awake for the rest of the show in part thanks to the thought puzzle of how many times a day this happens, and how best to determine exactly when.

Here’s an answer using Mathematica.

First, I found it useful to think of time in terms of a unit clock cycle — the hands on our theoretical clock run from 0 to 1, rather than to 12. The following Manipulate[] command draws a clock, allowing the user to set the unit time, and translating it into both conventional time and the angle of the minute and hour hands.

In[]:= Manipulate[ Graphics[{{Opacity[0], Disk[{0, 0}, .9]}, {Opacity[.8], Thickness[.02], Line[{{0, 0}, .65 {Sin[2 Pi m], Cos[2 Pi m]}}]}, Line[{{0, 0}, .85 {Sin[12*2 Pi m], Cos[12*2 Pi m]}}]}, PlotLabel -> ToString[Floor[Mod[11 + m*12, 12] + 1]] <> " hours, " <> ToString[360.*m] <> "\[Degree]\n" <> ToString[Floor[Mod[m, 1/12]*720]] <> " minutes, " <> ToString[4320 Mod[m, 1/12]] <> "\[Degree]"], {{m, 0, "time of day"}, 0, 1}]

The code when running looks like
manipulate[] clock
This was useful when debugging the formulae for the conversions; any error was immediately apparent.

Breaking out the conversions explicitly, we have

In[]:= unitTimeToListTime[unitTime_Real] := Module[{hour, minute, seconds}, hour = Floor[Mod[11 + unitTime*12, 12] + 1]; minute = Floor[Mod[unitTime, 1/12]*720]; seconds = Mod[unitTime, 1/720]*60*720; {hour, minute, seconds} ]
In[]:= unitTimeToMinuteAngle[unitTime_Real] := 4320 Mod[unitTime, 1/12]

and

In[]:= unitTimeToHourAngle[unitTime_Real] := unitTime*360 // N

These in hand, I naively thought the problem was as good as solved. I defined my problem in functional form,

In[]:= unstraightness[unitTime_] := Abs[Abs[unitTimeToMinuteAngle[unitTime] - unitTimeToHourAngle[unitTime]] - 180]

checked it with

Plot[unstraightness[unitTime], {unitTime, 0, .999999}]

and we see as expected a periodic function. There are 11 solutions when “unstraightness” == 0 per day, which makes perfectly good sense when you think about it.

I thought I could determine these with NSolve[unstraightness[unitTime] == 0, unitTime]

but sadly, this yields nothing but error messages.
NSolve::nsmet: This system cannot be solved with the methods available to NSolve. >>

What to do? I decided on brute force. Slice the day into 1,000,000 pieces and identify the 11 times which produce the most opposed clock hands.

In[]:= handangle = Table[{unitTime, Abs[unitTimeToMinuteAngle[unitTime] - unitTimeToHourAngle[unitTime]]}, {unitTime, 0, .999999, .000001}];

In[]:= closeFits = Select[handangle, Abs[#[[2]] - 180] < .002 &];

In[]:= TableForm[
Map[{#, ToString[unitTimeToListTime[#]], unitTimeToHourAngle[#],
unitTimeToMinuteAngle[#]} &, Transpose[closeFits][[1]]],
TableHeadings -> {None, {"unit time", "clock time", "hour angle",
"minute angle"}}]

Ah-hah!

As looked to be the case from the graph, these solutions are clearly spaced exactly 1/11 of the clock apart from each other. This means that we can get a more perfect solution more quickly with

In[]:= Table[ToString[unitTimeToListTime[i // N][[1]]] <> ":" <> ToString[unitTimeToListTime[i // N][[2]]] <> ":" <> ToString[unitTimeToListTime[i // N][[3]]], {i, 1/22, .9999, 1/11}] // TableForm

which returns

12:32:43.6364
1:38:10.9091
2:43:38.1818
3:49:5.45455
4:54:32.7273
6:00:00.
7:5:27.2727
8:10:54.5455
9:16:21.8182
10:21:49.0909
11:27:16.3636

Clearly, my bored glance at my watch had been at 8:10:54 pm.

One of the nice things about this solution method is that it easily generalizes to solve other “clock face” problems. For example, in a second we can determine that the hands of a clock are perfectly lined up, facing the same direction, at the following times:
12:00:00.
1:5:27.2727
2:10:54.5455
3:16:21.8182
4:21:49.0909
5:27:16.3636
6:32:43.6364
7:38:10.9091
8:43:38.1818
9:49:5.45455
10:54:32.7273