<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>And now it’s all this</title>
	<atom:link href="https://leancrew.com/all-this/feed/" rel="self" type="application/rss+xml" />
	<link>https://leancrew.com/all-this/</link>
	<description>I just said what I said and it was wrong. Or was taken wrong.</description>
	<lastBuildDate>Sat, 17 Oct 2026 02:42:51 +0000</lastBuildDate>
	<language>en-US</language>
		<sy:updatePeriod>hourly</sy:updatePeriod>
		<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=4.0</generator>
  <atom:link rel="hub" href="http://pubsubhubbub.appspot.com"/>
  <atom:link rel="hub" href="http://aniat.superfeedr.com"/>

<item>
<title>TextEdit vs. Pages</title>
<link>https://leancrew.com/all-this/2026/10/textedit-vs-pages/</link>
<pubDate>Sat, 17 Oct 2026 02:42:51 +0000</pubDate>
<dc:creator>
  <![CDATA[Dr. Drang]]>
</dc:creator>
<guid>https://leancrew.com/all-this/2026/10/textedit-vs-pages/</guid>
<description>
  <![CDATA[A few days ago, Allison Sheridan wrote <a href="https://www.podfeet.com/blog/2026/10/textedit/">a very persuasive article</a> about using TextEdit, the “unsung hero of macOS,” as a simple word processor. I’ve been trying it out and… I’m going to stick with Pages. Let me explain why.]]>
</description>
<content:encoded>
  <![CDATA[<p>A few days ago, Allison Sheridan wrote <a href="https://www.podfeet.com/blog/2026/10/textedit/">a very persuasive article</a> about using TextEdit, the “unsung hero of macOS,” as a simple word processor. I’ve been trying it out and… I’m going to stick with Pages. Let me explain why.</p>
<p>First, you should know that I almost never use a word processor. The overwhelming majority of my writing over the past 30 years has been done in a text editor, and its plain text is then fed to some sort of formatting software—Markdown or LaTeX, typically—to set the styles for all the parts. But with one-off documents, the styles I use for blog posts and technical reports don’t make sense. A note for someone who’s coming over to water my plants while I’m out of town shouldn’t look like an analysis of a mobile crane tipover accident. That’s where a word processor comes in handy. It’s much faster to change fonts, sizes, and margins in a word processor than in a LaTeX preamble.</p>
<p>Allison got on my good side early in the article when she complained about the ribbon in Microsoft Word. I think toolbars are way overused in apps nowadays, and Microsoft Office apps are probably the worst offenders. Their ribbons are overloaded with functions that should be in a menu, and they just take up too much space. Fundamentally, I see Microsoft’s ribbons as a user interface cop-out—it’s easier to load up a ribbon with buttons than it is to think carefully about how to make features available when needed without adding visual clutter.</p>
<p>Unfortunately, TextEdit has a toolbar that can’t be hidden. It’s a compact toolbar, to be sure, but almost everything in it could be done through menu commands—as <a href="https://en.wikipedia.org/wiki/MacWrite">MacWrite</a> and <a href="https://en.wikipedia.org/wiki/WriteNow">WriteNow</a> managed to do 40 years ago—without taking up any space in the document window. Honestly, who needs buttons for bold and italic? Or left, center, and right justification? This is no better than Word’s buttons for cut, copy, and paste. I really thought TextEdit would have a setting for hiding the toolbar, but I haven’t found one. Control-clicking the toolbar doesn’t let you customize it, either.</p>
<p><img alt="TextEdit example" class="ss" src="https://leancrew.com/all-this/images2026/20261016-TextEdit%20example.png" title="TextEdit example" width="63%"/></p>
<p>Now it’s true that Pages has a toolbar, but it’s tucked up in the title bar where it doesn’t take away space from the document. And you can customize it to include only the buttons you find useful.</p>
<p><img alt="Pages example" class="ss" src="https://leancrew.com/all-this/images2026/20261016-Pages%20example.png" title="Pages example" width="80%"/></p>
<p>Allison is right that the Format sidebar in Pages could use a rethink. <span class="menu">Style</span>, <span class="menu">Layout</span>, and <span class="menu">More</span> are pretty useless names for the settings they expose—calling them <span class="menu">One</span>, <span class="menu">Two</span>, and <span class="menu">Three</span> would be just about as informative. But at least the sidebar can be hidden until you need it.</p>
<p><img alt="Pages example with formatting sidebar" class="ss" src="https://leancrew.com/all-this/images2026/20261016-Pages%20example%20with%20formatting%20sidebar.png" title="Pages example with formatting sidebar" width="80%"/></p>
<p>Another TextEdit deficiency that bothers me is the lack of a sensible zoom control. There are <span class="menu">Zoom In</span> and <span class="menu">Zoom Out</span> commands in the <span class="menu">View</span> menu, but they double and halve the displayed size of the document, which isn’t fine enough control. Would it be so bad to have 25% increments for your users with decaying eyesight?</p>
<div class="update">
<p><strong>Update 18 Oct 2026 4:19 PM</strong><br/>
Andrew Kemp pointed out <a href="https://mastodon.social/@ajwk/117456364364874807">on Mastodon</a> that you <em>can</em> zoom in TextEdit using pinch and reverse pinch gestures on your trackpad. I should’ve tested that before writing the previous paragraph. Pages still has a zoom advantage because you can set a starting zoom level for every new document, but it’s not as big of an advantage as I thought. Thanks, Andrew!</p>
</div>
<p>I mentioned earlier that it’s nice to be able to quickly change styles within a document. It’s also nice to have some standard styles to start with. Pages uses templates, a longstanding Mac feature that may have come over from NeXT, for creating documents with standard styles. It comes with lots of templates that I would never use, but it also lets users create their own. I have a simple one called Big Note, which uses 16-point Helvetica Neue for body text, centered 18-point bold Helvetica Neue for headings, and a 0.75″ indentation for bulleted lists. This works without changes for most of my printed notes to myself and others. While you can create new styles in TextEdit, you can’t save templates.</p>
<p>An advantage of TextEdit that Allison points out and which I concede: TextEdit uses much less memory than Pages. I wish that weren’t the case, but I have a 48 GB MacBook Pro, so I can afford to be profligate with RAM.</p>
<p>Price is not an advantage of TextEdit for me, as I’m using the free version of Pages. If Apple ever forces Pages users to sign up for Creator Studio—which I doubt will happen—I’ll be revisiting TextEdit.</p>]]>
</content:encoded>
</item>

<item>
<title>Randomizing array indices</title>
<link>https://leancrew.com/all-this/2026/10/randomizing-array-indices/</link>
<pubDate>Tue, 13 Oct 2026 02:15:04 +0000</pubDate>
<dc:creator>
  <![CDATA[Dr. Drang]]>
</dc:creator>
<guid>https://leancrew.com/all-this/2026/10/randomizing-array-indices/</guid>
<description>
  <![CDATA[I mentioned in <a href="https://leancrew.com/all-this/2026/10/mean-vs-mean/">my last post</a> that I’m working my way through <a href="https://learning-oreilly-com.ezproxy.naperville-lib.org/library/view/practical-deep-learning/9798341655119/"><em>Practical Deep Learning</em></a> by Ronald Kneusel. The math so far has been straightforward, and the code is written in Python, which I find easy to follow.]]>
</description>
<content:encoded>
  <![CDATA[<p>I mentioned in <a href="https://leancrew.com/all-this/2026/10/mean-vs-mean/">my last post</a> that I’m working my way through <a href="https://learning-oreilly-com.ezproxy.naperville-lib.org/library/view/practical-deep-learning/9798341655119/"><em>Practical Deep Learning</em></a> by Ronald Kneusel. The math so far has been straightforward, and the code is written in Python, which I find easy to follow.</p>
<p>“Easy to follow” does not mean “correct” or “to my liking.” Some of the code in the book simply doesn’t work, and I’ve had to make changes here and there to get it to run. It’s possible that some of the APIs the book relies on have changed their calling conventions, but I also found a pretty obvious off-by-one error. And I’m only three chapters in.</p>
<p>This post, though, is about the “not to my liking” aspect of the code. I feel a little uncomfortable doing this, but I’ve been reading and writing data analysis code in Python for 15–20 years, so I’m going to put my discomfort to the side.</p>
<p>One of the examples used in the book is the well-known <a href="https://en.wikipedia.org/wiki/Iris_flower_data_set">iris measurement dataset</a>. There are 150 records in the dataset; here are the first ten:</p>
<table style="font-size: 80%">
<thead>
<tr>
<th align="center">Index</th>
<th align="center">Sepal<br/>length</th>
<th align="center">Sepal<br/>width</th>
<th align="center">Petal<br/>length</th>
<th align="center">Petal<br/>width</th>
<th align="center">Class</th>
</tr>
</thead>
<tbody>
<tr>
<td align="center">0</td>
<td align="center">5.1</td>
<td align="center">3.5</td>
<td align="center">1.4</td>
<td align="center">0.2</td>
<td align="center">Iris-setosa</td>
</tr>
<tr>
<td align="center">1</td>
<td align="center">4.9</td>
<td align="center">3.0</td>
<td align="center">1.4</td>
<td align="center">0.2</td>
<td align="center">Iris-setosa</td>
</tr>
<tr>
<td align="center">2</td>
<td align="center">4.7</td>
<td align="center">3.2</td>
<td align="center">1.3</td>
<td align="center">0.2</td>
<td align="center">Iris-setosa</td>
</tr>
<tr>
<td align="center">3</td>
<td align="center">4.6</td>
<td align="center">3.1</td>
<td align="center">1.5</td>
<td align="center">0.2</td>
<td align="center">Iris-setosa</td>
</tr>
<tr>
<td align="center">4</td>
<td align="center">5.0</td>
<td align="center">3.6</td>
<td align="center">1.4</td>
<td align="center">0.2</td>
<td align="center">Iris-setosa</td>
</tr>
<tr>
<td align="center">5</td>
<td align="center">5.4</td>
<td align="center">3.9</td>
<td align="center">1.7</td>
<td align="center">0.4</td>
<td align="center">Iris-setosa</td>
</tr>
<tr>
<td align="center">6</td>
<td align="center">4.6</td>
<td align="center">3.4</td>
<td align="center">1.4</td>
<td align="center">0.3</td>
<td align="center">Iris-setosa</td>
</tr>
<tr>
<td align="center">7</td>
<td align="center">5.0</td>
<td align="center">3.4</td>
<td align="center">1.5</td>
<td align="center">0.2</td>
<td align="center">Iris-setosa</td>
</tr>
<tr>
<td align="center">8</td>
<td align="center">4.4</td>
<td align="center">2.9</td>
<td align="center">1.4</td>
<td align="center">0.2</td>
<td align="center">Iris-setosa</td>
</tr>
<tr>
<td align="center">9</td>
<td align="center">4.9</td>
<td align="center">3.1</td>
<td align="center">1.5</td>
<td align="center">0.1</td>
<td align="center">Iris-setosa</td>
</tr>
</tbody>
</table>
<p>There are three species of iris in the dataset: <em>setosa</em>, <em>versicolor</em>, and <em>virginica</em>. The records, which are <a href="https://archive.ics.uci.edu/dataset/53/iris">easy to find</a>, are sorted according to class, and it’s necessary to randomize the records for certain operations.</p>
<p>Let’s say the measurements are in a 2D (150×4) NumPy array called <code>x</code>, and the classes, which have been reduced to the integers 0, 1, and 2 for <em>setosa</em>, <em>versicolor</em>, and <em>virginica</em>, respectively, are in a 1D NumPy array called <code>y</code>. Here they are in an interactive Python session:</p>
<pre><code>&gt;&gt;&gt; x
array([[5.1, 3.5, 1.4, 0.2],
       [4.9, 3. , 1.4, 0.2],
       [4.7, 3.2, 1.3, 0.2],
       [4.6, 3.1, 1.5, 0.2],
       [5. , 3.6, 1.4, 0.2],

       [140 other rows],

       [6.7, 3. , 5.2, 2.3],
       [6.3, 2.5, 5. , 1.9],
       [6.5, 3. , 5.2, 2. ],
       [6.2, 3.4, 5.4, 2.3],
       [5.9, 3. , 5.1, 1.8]])
&gt;&gt;&gt; y
array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
       0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
       2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
       2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2])
</code></pre>
<p>Kneusel uses NumPy’s <a href="https://numpy.org/doc/stable/user/basics.indexing.html#integer-array-indexing">integer array indexing</a> to randomize <code>y</code> and the rows of <code>x</code> using the same rearrangement in each. Here’s what he does:</p>
<pre><code>&gt;&gt;&gt; idx = np.argsort(np.random.random(x.shape[0]))
&gt;&gt;&gt; x = x[idx, :]
&gt;&gt;&gt; y = y[idx]
</code></pre>
<p>The first line starts by generating an array of 150 (<code>x.shape[0]</code> is 150) random numbers between 0 and 1 via <a href="https://numpy.org/doc/stable/reference/random/generated/numpy.random.random.html"><code>random.random</code></a>; <a href="https://numpy.org/doc/2.5/reference/generated/numpy.argsort.html"><code>argsort</code></a> then returns an array of the indices of the sorted version of that array. So <code>idx</code> is an array of the integers from 0 through 149 in random order. The two lines after that rearrange <code>x</code> and <code>y</code> in that same random order.</p>
<p>I don’t know about you, but I see this as a weird way to go about randomization. I realize you can’t just shuffle <code>x</code> and <code>y</code> individually, as that would break the connection between an iris’s measurements and its class. But why go through two steps when you can create the <code>idx</code> array directly?</p>
<pre><code>&gt;&gt;&gt; idx = np.random.permutation(x.shape[0])
</code></pre>
<p>Maybe Kneusel’s method is faster, even though it seems like it should be slower. This won’t matter for the small iris dataset, but he may be preparing his readers for huge datasets to come.</p>
<p>I tested the two methods using <a href="https://ipython.readthedocs.io/en/stable/interactive/magics.html#magic-timeit">IPython’s <code>%timeit</code> magic command</a>. Here’s what I found, with 1,000,000 indices instead of 150:</p>
<pre><code>&gt;&gt;&gt; %timeit np.argsort(np.random.random(1_000_000))
63.8 ms ± 434 μs per loop (mean ± std. dev. of 7 runs, 10 loops each)

&gt;&gt;&gt; %timeit np.random.permutation(1_000_000)
5.98 ms ± 17.8 μs per loop (mean ± std. dev. of 7 runs, 100 loops each)
</code></pre>
<p>So the simple code is both more direct <em>and</em> about an order of magnitude faster. I’ll be looking at the code in the book with a more critical eye as I proceed—assuming I don’t bail out and look for another machine learning reference.</p>
<hr/>
<p>You may have noticed that the code above uses NumPy’s older random number system. The current approach would be to create a <a href="https://numpy.org/doc/stable/reference/random/generator.html#permutations"><code>Generator</code></a> instance and use that as the basis for later function calls. Would this have any effect on the timing results? Let’s see.</p>
<pre><code>&gt;&gt;&gt; rng = np.random.default_rng()
&gt;&gt;&gt; %timeit np.argsort(rng.random(1_000_000))
65 ms ± 188 μs per loop (mean ± std. dev. of 7 runs, 10 loops each)

&gt;&gt;&gt; %timeit rng.permutation(1_000_000)
4.91 ms ± 10.9 μs per loop (mean ± std. dev. of 7 runs, 100 loops each)
</code></pre>
<p>No, the runtimes are about the same.</p>]]>
</content:encoded>
</item>

<item>
<title>Mean vs mean</title>
<link>https://leancrew.com/all-this/2026/10/mean-vs-mean/</link>
<pubDate>Fri, 09 Oct 2026 22:55:47 +0000</pubDate>
<dc:creator>
  <![CDATA[Dr. Drang]]>
</dc:creator>
<guid>https://leancrew.com/all-this/2026/10/mean-vs-mean/</guid>
<description>
  <![CDATA[I decided to start learning about machine learning a couple of weeks ago. Partly because it sounds interesting, partly because I think I have enough math to handle it, and partly because I felt it was important to have a deeper knowledge if I want to criticize AI.]]>
</description>
<content:encoded>
  <![CDATA[<p>[Equations in this post may not look right (or appear at all) in your RSS reader. Go to <a href="https://leancrew.com/all-this/2026/10/mean-vs-mean/">the original article</a> to see them rendered properly.]</p>
  <hr />
  <p>I decided to start learning about machine learning a couple of weeks ago. Partly because it sounds interesting, partly because I think I have enough math to handle it, and partly because I felt it was important to have a deeper knowledge if I want to criticize AI.</p>
<p>I started with a library copy of Friedman and Mendhekar’s <a href="https://lccn.loc.gov/2022045341"><em>The Little Learner</em></a> but decided to drop it after I was about halfway through. Although I was following along reasonably well, I kept struggling with the book’s notation—after 200 pages, I shouldn’t have to keep returning to the front of the book to see what things like <!-- $t|_i$ --><math xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mi>t</mi><msub><mo form="prefix" stretchy="false">|</mo><mi>i</mi></msub></mrow></math> mean. If the book’s Scheme code were actually written in Scheme, I might have stuck with it, but its mixture of Scheme with math was too frustrating.</p>
<p>Yesterday I started Kneusel’s <a href="https://www.oreilly.com/library/view/practical-deep-learning/9798341655119/"><em>Practical Deep Learning</em></a>. My library gives me free access to O’Reilly ebooks, so it’s easy to have the book open on my iPad while I work through example code on my MacBook. And yes, I certainly feel more comfortable working in Python. But I was surprised by a result pretty early on.</p>
<p>It had to do with calculating the mean values of the columns of a 2D array. The book is explaining a way to normalize (or standardize) a set of data whose features are on vastly different scales. Here’s the code (in an interactive Python session) that does it using the book’s example data:</p>
<pre><code>python:
&gt;&gt;&gt; import numpy as np
&gt;&gt;&gt; x = np.array([
...  [6998, 0.1361, 0.3408, 0.00007350, 78596048],
...  [6580, 0.4908, 3.0150, 0.00004484, 38462706],
...  [7563, 0.9349, 4.3465, 0.00001003,  6700340],
...  [8355, 0.6529, 2.1271, 0.00002966, 51430391],
...  [2393, 0.4605, 2.7561, 0.00003395, 27284192],
...  [9498, 0.0244, 2.7887, 0.00008880, 78543394],
...  [4030, 0.6467, 4.8231, 0.00000403, 19101443],
...  [5275, 0.3560, 0.0705, 0.00000899, 96029352],
...  [8094, 0.7979, 3.9897, 0.00006691,  7307156],
...  [ 843, 0.7892, 0.9804, 0.00005798, 10179751],
...  [1221, 0.9564, 2.3944, 0.00007815, 14241835],
...  [5879, 0.0329, 2.0085, 0.00009564, 34243070],
...  [ 923, 0.4159, 1.7821, 0.00002467, 52404615],
...  [5882, 0.0002, 1.5362, 0.00005066, 18728752],
...  [1796, 0.7247, 2.3190, 0.00001332, 96703562],
... ])
...
&gt;&gt;&gt; xs = (x - x.mean(axis=0)) / x.std(axis=0)
&gt;&gt;&gt; xs
array([[ 0.69308862, -1.12598999, -1.53184967,  0.95258185,  1.18240196],
       [ 0.54647372, -0.01203876,  0.50510857, -0.01928358, -0.1141859 ],
       [ 0.89126426,  1.38267719,  1.51932212, -1.19969655, -1.14033263],
       [ 1.16906091,  0.49704356, -0.17121154, -0.53403994,  0.3047611 ],
       [-0.92213055, -0.10719726,  0.30790249, -0.38856532, -0.47533014],
       [ 1.56997199, -1.47678885,  0.33273415,  1.47140742,  1.18070086],
       [-0.34794732,  0.47757218,  1.88235192, -1.40315756, -0.73969021],
       [ 0.0887406 , -0.43538419, -1.73773921, -1.23496312,  1.7456197 ],
       [ 1.07751429,  0.95242255,  1.24754488,  0.72911384, -1.12072823],
       [-1.46579825,  0.92509981, -1.04466154,  0.42629603, -1.0279233 ],
       [-1.33321348,  1.4501989 ,  0.03239288,  1.11026413, -0.89668956],
       [ 0.30059562, -1.45009422, -0.26155005,  1.70335297, -0.25050967],
       [-1.43773798, -0.24726556, -0.43400063, -0.70325168,  0.33623535],
       [ 0.30164788, -1.55279003, -0.62130451,  0.1780736 , -0.75173073],
       [-1.1315303 ,  0.72253467, -0.02503987, -1.08813209,  1.7674014 ]])
</code></pre>
<p>The example data consists of 15 samples, each of which has 5 features. The third command rescales each feature by subtracting its mean and dividing by its standard deviation.</p>
<p>In the book, Kneusel checks the mean of the fourth column of rescaled data to confirm that it’s basically zero. He gets <!-- $-1.33 \times 10^{-16}$ --><math xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mi>−</mi><mn>1.33</mn><mo>×</mo><msup><mn>10</mn><mrow><mi>−</mi><mn>16</mn></mrow></msup></mrow></math>, which is effectively zero for 64-bit floating point values.</p>
<p>To make sure I was doing things right, I ran this:</p>
<pre><code>python:
&gt;&gt;&gt; xs.mean(axis=0)
array([ 1.48029737e-17, -8.88178420e-17,  6.77698638e-17, -1.62832710e-16,
        4.44089210e-17])
</code></pre>
<p>While the fourth mean, <!-- $-1.63 \times 10^{-16}$ --><math xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mi>−</mi><mn>1.63</mn><mo>×</mo><msup><mn>10</mn><mrow><mi>−</mi><mn>16</mn></mrow></msup></mrow></math>, is certainly as good a zero as the book’s answer, it isn’t the same. To double-check my work, I ran this:</p>
<pre><code>python:
&gt;&gt;&gt; xs[:, 3].mean()
-1.3322676295501878e-16
</code></pre>
<p>This <em>is</em> the book’s value. What’s going on?</p>
<p>You may think this is perfectly normal. Floating point numbers are inherently inexact, and as long as I get a result that’s effectively zero, there’s nothing to be bothered about. But I was bothered.</p>
<p>I’m using the same function, <a href="https://numpy.org/doc/stable/reference/generated/numpy.mean.html"><code>mean</code></a>, from the same library, NumPy, on the same set of data, and I get different answers depending on how I invoke that function. Or maybe I do get the same answers. Here’s another command and its output:</p>
<pre><code>python:
&gt;&gt;&gt; for i in range(xs.shape[1]):
...     print(f'Column {i}: {xs.mean(axis=0)[i] == xs[:, i].mean()}')
...
Column 0: True
Column 1: True
Column 2: True
Column 3: False
Column 4: False
</code></pre>
<p>For the first three columns, it doesn’t matter which way I use <code>mean</code>; for the last two, it does.</p>
<p>I should mention here that while the different results are obvious when the mean is close to zero, this behavior is present when operating on any 2D array. I’ve tried it out on several 2D arrays made from randomly generated floating point numbers.</p>
<p>During these experiments with randomly generated arrays, I got the sense that the likelihood of getting the same mean both ways got smaller as the number of rows in the array got larger. I decided to check that out with this script:</p>
<pre><code>python:
 1:  #!/usr/bin/env python3
 2:  
 3:  import numpy as np
 4:  
 5:  rng = np.random.default_rng()
 6:  
 7:  N = 5000
 8:  
 9:  for n in (10, 100, 1000, 10_000, 100_000):
10:    count = 0
11:    for i in range(N):
12:      x0 = rng.uniform(low=0, high=100, size=n)
13:      x1 = rng.uniform(low=100, high=200, size=n)
14:      x = np.column_stack((x0, x1))
15:      if x.mean(axis=0)[0] == x[:, 0].mean():
16:        count += 1
17:      if x.mean(axis=0)[1] == x[:, 1].mean():
18:        count += 1
19:    print(f'n = {n:,d}')
20:    print(f'  Same means: {count/(2*N):.2%}')
</code></pre>
<p>The results were</p>
<pre><code>n = 10
  Same means: 73.97%
n = 100
  Same means: 28.47%
n = 1,000
  Same means:  7.47%
n = 10,000
  Same means:  2.50%
n = 100,000
  Same means:  1.03%
</code></pre>
<p>So arrays with more rows <em>are</em> less likely to yield the same mean values when the <code>mean</code> function is used in these two different ways.</p>
<p>My working theory is that when I use <code>mean()</code> on a 1D array extracted from a 2D array, the computations are done differently than when I use <code>mean(axis=0)</code> on the 2D array. Mathematically the same, but computationally different. Maybe it’s as simple as the summation being done in a different order so the partial sums round off in slightly different ways. The more partial sums, the greater the likelihood of a different answer.</p>
<p>Ultimately, <!-- $-1.33 \times 10^{-16}$ --><math xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mi>−</mi><mn>1.33</mn><mo>×</mo><msup><mn>10</mn><mrow><mi>−</mi><mn>16</mn></mrow></msup></mrow></math> and <!-- $-1.63 \times 10^{-16}$ --><math xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mi>−</mi><mn>1.63</mn><mo>×</mo><msup><mn>10</mn><mrow><mi>−</mi><mn>16</mn></mrow></msup></mrow></math> are both zero, so this was mainly an exercise in satisfying my curiosity. I worry when computer results that ought to be exactly the same are only nearly the same. It usually means I’ve done something wrong, but apparently not in this case.</p>
<div class="update">
<p><strong>Update 9 Oct 2026 9:41 PM</strong><br/>
<a href="https://nathangrigg.com/">Nathan Grigg</a>, who has set me straight too many times to count, <a href="https://mastodon.social/@nathangrigg/117413516387160372">pointed out</a> that the <a href="https://numpy.org/doc/stable/reference/generated/numpy.sum.html">NumPy docs for <code>sum</code></a> explain how that function uses algorithms with different precision depending on</p>
<ol>
<li>whether the <code>axis</code> parameter is used or not; and</li>
<li>which axis is chosen if the parameter is used.</li>
</ol>
<p>There’s basically a speed/precision tradeoff at work. While it’s true that <a href="https://numpy.org/doc/stable/reference/generated/numpy.mean.html">the docs for <code>mean</code></a> don’t include this explanation, <code>sum</code> and <code>mean</code> are so alike that it must be the reason for the different answers.</p>
<p>Thanks, Nathan!</p>
</div>
  ]]>
</content:encoded>
</item>

<item>
<title>I’m pissed at the Library of Congress</title>
<link>https://leancrew.com/all-this/2026/10/im-pissed-at-the-library-of-congress/</link>
<pubDate>Fri, 09 Oct 2026 02:27:19 +0000</pubDate>
<dc:creator>
  <![CDATA[Dr. Drang]]>
</dc:creator>
<guid>https://leancrew.com/all-this/2026/10/im-pissed-at-the-library-of-congress/</guid>
<description>
  <![CDATA[Today I tried to add a couple of recently purchased books to my library database using <a href="https://leancrew.com/all-this/2025/04/adding-books-to-my-library-database/">my <code>lccn2library</code> script</a>. It failed because the Library of Congress has either moved or deleted the files <code>lccn2library</code> relies on.]]>
</description>
<content:encoded>
  <![CDATA[<p>Today I tried to add a couple of recently purchased books to my library database using <a href="https://leancrew.com/all-this/2025/04/adding-books-to-my-library-database/">my <code>lccn2library</code> script</a>. It failed because the Library of Congress has either moved or deleted the files <code>lccn2library</code> relies on.</p>
<p>Let’s say I was trying to add <a href="https://lccn.loc.gov/26010978"><em>Applied Elasticity</em></a> by Timoshenko and Lessells.<sup id="fnref:westinghouse"><a href="#fn:westinghouse" rel="footnote">1</a></sup> If you go to the LoC’s MARC record for the book and click on the Download link, you’ll see a popup that looks like this:</p>
<p><img alt="LoC downloads popup" class="ss" src="https://leancrew.com/all-this/images2026/20261008-LoC%20downloads%20popup.png" title="LoC downloads popup" width="60%"/></p>
<p>So it looks like you can click the MODS link to get the <a href="https://www.loc.gov/standards/mods/">MODS file</a> for the book. That’s the file my script parses to get the information to add to the database. The MODS link for this book is</p>
<pre><code>https://lccn.loc.gov/26010978/mods
</code></pre>
<p>which is the URL form that <code>lccn2library</code> expects. Unfortunately, that link returns an empty file. And not just for that book, but for every book I tried. What does the little northeast-pointing arrow mean? Beats me. You’d think it was an indication that the MODS link was pointing to some external site, but that’s not the case.</p>
<p>Maybe I’ve caught the LoC in the middle of a transition to a new system for storing records in various formats. Maybe I’ll return in a month or two to find that everything is working again—perhaps with new URLs for the different formats. I hope so.</p>
<p>But until that hoped-for day, I’m pissed at the LoC because I have to add books to my database by hand using the <a href="https://www.sqlite.org/"><code>sqlite3</code></a> interactive command-line tool. Which is slow but not terrible, especially since I’m adding only a book or two at a time.</p>
<p>The command to add a new book to the database is</p>
<pre><code>INSERT INTO book(title, subtitle, volume, edition, publisher, published, lccn, loc, added)
VALUES(&lt;list of values separated by commas&gt;);
</code></pre>
<p>The book will be assigned an ID automatically. To get it, I run</p>
<pre><code>SELECT id,title FROM book WHERE added IS "2026-10-08";
</code></pre>
<p>The first field in the output will be the ID. The date must be a string with the current date in yyyy-mm-dd format.</p>
<div class="update">
<p><strong>Update 9 Oct 2026 10:12 AM</strong><br/>
On Mastodon, <a href="https://mastodon.gamedev.place/@enno/117408775161902954">Enno Rehling suggested</a> a shorter command to get the ID of the book just entered:</p>
<pre><code>SELECT last_insert_rowid();
</code></pre>
<p>After looking at the SQLite documentation for <a href="https://www.sqlite.org/lang_corefunc.html#last_insert_rowid"><code>last_insert_row</code></a>, I noticed that a similar thing could be done with the <a href="https://www.sqlite.org/lang_corefunc.html#max_scalar"><code>max</code> function</a>:</p>
<pre><code>SELECT max(id) from book;
</code></pre>
<p>This works because the <code>id</code> field is automatically incremented with each insertion. Commands like these can also be used below to get the ID of the most recently added author.</p>
<p>Thanks, Enno!</p>
</div>
<p>The new book may be written by an author already in the database. To check if that’s the case, I run</p>
<pre><code>SELECT * FROM author WHERE name LIKE "%&lt;portion of name&gt;%";
</code></pre>
<p>If the author’s already in the database, that command will return their ID. If not, it returns nothing. I then run</p>
<pre><code>INSERT INTO author(name) VALUES("&lt;full name&gt;");
</code></pre>
<p>and then the <code>SELECT</code> command above to get the author’s ID.</p>
<p>The final step is to add a record to the <code>book_author</code> table to tie the book and author together. That’s</p>
<pre><code>INSERT INTO book_author(book_id, author_id) VALUES(&lt;book ID&gt;, &lt;author ID&gt;);
</code></pre>
<p>As I said, this is slow because it’s several steps, but none of the steps are difficult.</p>
<p>What will I do if the LoC never fixes the problem of the missing MODS files? I suppose I could parse the <a href="https://www.loc.gov/marc/umb/um01to06.html">MARC records</a>, which are still accessible, but that would be a pain in the ass. Maybe I’ll build a little interactive script where I can just type in the necessary information and have the script generate and run the SQL commands. I hope it doesn’t come to that.</p>
<div class="footnotes">
<hr/>
<ol>
<li id="fn:westinghouse">
<p>It’d be so cool to have this book. It was written when Timoshenko had just come to the US and was working at Westinghouse before landing a teaching gig at the University of Michigan. Sadly, this was not one of the books I was adding to my library. <a href="#fnref:westinghouse" rev="footnote">↩</a></p>
</li>
</ol>
</div>]]>
</content:encoded>
</item>

<item>
<title>Making a tall, skinny plot in Mathematica</title>
<link>https://leancrew.com/all-this/2026/10/making-a-tall-skinny-plot-in-mathematica/</link>
<pubDate>Wed, 07 Oct 2026 17:12:51 +0000</pubDate>
<dc:creator>
  <![CDATA[Dr. Drang]]>
</dc:creator>
<guid>https://leancrew.com/all-this/2026/10/making-a-tall-skinny-plot-in-mathematica/</guid>
<description>
  <![CDATA[<a href="https://leancrew.com/all-this/2026/10/distorted-plots/">Yesterday’s post</a> included this plot:]]>
</description>
<content:encoded>
  <![CDATA[<p><a href="https://leancrew.com/all-this/2026/10/distorted-plots/">Yesterday’s post</a> included this plot:</p>
<p><img alt="Rescaled Moon and Earth orbit" class="ss" src="https://leancrew.com/all-this/images2026/20261006-Rescaled%20Moon%20and%20Earth%20orbit.svg" title="Rescaled Moon and Earth orbit" width="40%"/></p>
<p>I figured it was worth a quick post to show how I made it.</p>
<p>I had already done most of the work back in 2022 in a Mathematica notebook I made to support <a href="https://leancrew.com/all-this/2022/10/orbital-curvature/">my original orbital curvature post</a>. So I copied the pertinent calculations from that notebook, pasted them into a new one, and made the adjustments necessary to produce the plot. Here’s the new notebook:</p>
<iframe height="800" src="https://www.wolframcloud.com/obj/mark80/Published/allain-replot.nb?_embed=iframe" width="550"></iframe>
<p>The bottom half of the notebook is where the plotting commands are. The key items are:</p>
<ul>
<li>The definitions of <code>xGrid</code>, <code>xTicks</code>, <code>yGrid</code>, and <code>yTicks</code>. These produce lists of values used to lay out the grid spacing and tick mark labels. Most of this is self-explanatory, but I do want to call out the use of <a href="http://reference.wolfram.com/language/ref/NumberForm.html"><code>NumberForm</code></a> to format the tick labels with two decimal places. <code>NumberForm[x, {3, 2}]</code> is very much like Python’s <code>{x:3.2f}</code> in an f-string. Like most things in Mathematica, it’s kind of verbose, but it is readable.</li>
<li><p>The call to <a href="http://reference.wolfram.com/language/ref/ParametricPlot.html"><code>ParametricPlot</code></a> includes the option</p>
<pre><code>AspectRatio -&gt; .25/.05
</code></pre>
<p><a href="http://reference.wolfram.com/language/ref/AspectRatio.html"><code>AspectRatio</code></a> sets the ratio of height to width for the plot as a whole, so the value I set it to was based on the ratio of the values given in the <a href="http://reference.wolfram.com/language/ref/PlotRange.html"><code>PlotRange</code></a> option. The overall plot is 0.25 units high and 0.05 units wide, so to make the <em>x</em> and <em>y</em> units the same size, <code>AspectRatio</code> is set to that ratio. I entered it as a division instead of as the number 5 because I wanted the reasoning behind it to be clear. I suppose I could have been even more explicit by saying</p>
<pre><code>AspectRatio -&gt; (.25 - 0)/(1.01 - .96)
</code></pre>
<p>but there are limits to my verbosity, even when using Mathematica.</p></li>
</ul>
<p>To get the image out of the notebook, I right-clicked on it, selected <span class="menu">Save Graphic As…</span> from the popup menu, and chose SVG as the format. That’s why the plot stays smooth if you zoom in on it.</p>]]>
</content:encoded>
</item>

<item>
<title>Distorted plots</title>
<link>https://leancrew.com/all-this/2026/10/distorted-plots/</link>
<pubDate>Wed, 07 Oct 2026 02:08:33 +0000</pubDate>
<dc:creator>
  <![CDATA[Dr. Drang]]>
</dc:creator>
<guid>https://leancrew.com/all-this/2026/10/distorted-plots/</guid>
<description>
  <![CDATA[Rhett Allain, physics professor and blogger, published <a href="https://rjallain.medium.com/why-do-textbooks-lie-about-the-moons-orbit-around-the-earth-7e29f9810aa9?sk=7cf9fbcc5f1f235461c6dc8d04367fa6">a nice article today</a> about the Moon’s orbit. It follows largely the same line of reasoning as <a href="https://leancrew.com/all-this/2022/10/orbital-curvature/">my post on the same topic</a> (and the various write-ups I linked to in that post) from a few years ago. I nodded my head as I read through it, until I got to a plot at the end of the article.]]>
</description>
<content:encoded>
  <![CDATA[<p>Rhett Allain, physics professor and blogger, published <a href="https://rjallain.medium.com/why-do-textbooks-lie-about-the-moons-orbit-around-the-earth-7e29f9810aa9?sk=7cf9fbcc5f1f235461c6dc8d04367fa6">a nice article today</a> about the Moon’s orbit. It follows largely the same line of reasoning as <a href="https://leancrew.com/all-this/2022/10/orbital-curvature/">my post on the same topic</a> (and the various write-ups I linked to in that post) from a few years ago. I nodded my head as I read through it, until I got to a plot at the end of the article.</p>
<p>For much of the article, Allain complains about how the orbit of the Moon as it and the Earth make their way around the Sun is often distorted in textbooks. Like this, which is a frame from an animated GIF in the article.</p>
<p><img alt="Distorted orbits around the Sun" class="ss" src="https://leancrew.com/all-this/images2026/20261006-Distorted%20orbits%20around%20the%20Sun.png" title="Distorted orbits around the Sun" width="80%"/></p>
<p>In this image, the Earth-Moon distance is exaggerated, and it looks like the Moon curves away from the Sun when it’s between the Earth and the Sun. To show that this is wrong, he plots portions of the Moon and Earth orbits without exaggerating the Moon-Earth distance:</p>
<p><img alt="Allain plot of Moon and Earth orbits" class="ss" src="https://leancrew.com/all-this/images2026/20261006-Allain%20plot%20of%20Moon%20and%20Earth%20orbits.png" title="Allain plot of Moon and Earth orbits" width="100%"/></p>
<p>Forgive me, but what the actual fuck? How can you spend over 1000 words complaining about graphical distortions and then produce this? Sure, it’s not the same distortion he was complaining about, but still. The whole point of the article was to show that the Moon’s path over the course of an Earth year is a sort of wobbly circle around the Sun. The arcs in this plot are nowhere near circular.</p>
<p>Here’s a properly scaled version of Allain’s plot:</p>
<p><img alt="Rescaled Moon and Earth orbit" class="ss" src="https://leancrew.com/all-this/images2026/20261006-Rescaled%20Moon%20and%20Earth%20orbit.svg" title="Rescaled Moon and Earth orbit" width="35%"/></p>
<p>Yes, the plot is really tall and skinny. It has to be to avoid distorting the paths. Note that the grids are square and represent the same distance in each direction.</p>
<p>We all know how this happened. The range of the <em>x</em> data is very small compared to the range of the <em>y</em> data, but because the plotting software defaults to a landscape-style graph, the paths come out looking like arcs of very wide ellipses. Unless the person running the software steps in to make sure <em>x</em> and <em>y</em> distances are drawn to the same scale.</p>
<p>I could write a post like this almost every day. So many people accept the defaults of their graphing software without thinking about how one or two small tweaks could make their plots so much better.</p>]]>
</content:encoded>
</item>

<item>
<title>Too dumb for AI</title>
<link>https://leancrew.com/all-this/2026/09/too-dumb-for-ai/</link>
<pubDate>Wed, 30 Sep 2026 21:13:17 +0000</pubDate>
<dc:creator>
  <![CDATA[Dr. Drang]]>
</dc:creator>
<guid>https://leancrew.com/all-this/2026/09/too-dumb-for-ai/</guid>
<description>
  <![CDATA[I’ll admit that the first thing I looked into regarding <a href="https://www.reuters.com/world/us/trump-tech-executives-sign-morally-binding-ai-document-2026-09-29/">yesterday’s “Super Intelligence” meeting</a> at the White House was whether Tim Cook was there. He wasn’t, which was probably a relief to Tim, even though it’s also an admission that Apple isn’t considered a player in AI. By anyone, not even the idiots in the Trump administration.]]>
</description>
<content:encoded>
  <![CDATA[<p>I’ll admit that the first thing I looked into regarding <a href="https://www.reuters.com/world/us/trump-tech-executives-sign-morally-binding-ai-document-2026-09-29/">yesterday’s “Super Intelligence” meeting</a> at the White House was whether Tim Cook was there. He wasn’t, which was probably a relief to Tim, even though it’s also an admission that Apple isn’t considered a player in AI. By anyone, not even the idiots in the Trump administration.</p>
<p>You’ve probably seen the stupid misspelling above Trump’s signature on the “morally binding” agreement that came out of the meeting.</p>
<p><img alt="Signature page" class="ss" src="https://leancrew.com/all-this/images2026/20260930-Signature%20page.jpg" title="Signature page" width="80%"/></p>
<p>Yes, he signed it as the “President of the Unites States” and then proudly <a href="https://truthsocial.com/@realDonaldTrump/posts/117356435739432952">posted it to Truth Social</a>. I can’t imagine the agreement means anything, as you’d be hard-pressed to find a single moral shared among the people in the meeting. I will say, though, that Jensen Huang’s signature is pretty spiffy.</p>
<p>As for who was at the meeting, Trump <a href="https://truthsocial.com/@realDonaldTrump/posts/117355137125519227">also posted</a> this seating chart, which hurts to look at:</p>
<p><a href="https://leancrew.com/all-this/images2026/20260930-Seating%20chart.jpg"><img alt="Seating chart" class="ss" src="https://leancrew.com/all-this/images2026/20260930-Seating%20chart.jpg" title="Seating chart" width="80%"/></a></p>
<p>Click the image to see it at full size, if you dare. Also, don’t feel obligated to follow either of the Truth Social links; I’m including them only because I feel an obligation to give credit—or in this case blame.</p>
<p>Lots of the images Trump posts are AI-generated, but I find it hard to believe that any AI system would produce something with this many graphical errors:</p>
<ul>
<li>The chairs on the left side of the table are vertically offset from those on the right side, even though there are the same number on each side. Poor Will Scharf is nearly off the end.</li>
<li>The chairs on the left are distinctly farther from the table than the chairs on the right.</li>
<li>The vertical spaces between chairs on a given side aren’t equal. The seats near the ends are closer to one another than the seats near the center.</li>
<li>The two lines of chairs aren’t horizontally aligned. This was perhaps the smallest mistake, and you probably can’t see it unless you zoom in, but what drawing app wouldn’t automatically align the items?</li>
<li>The names and chairs aren’t aligned vertically. You’d expect the names to be centered vertically with the chairs, and many of them are at least close to that, but once you see Alex Karp and Andrew Ferguson you’ll notice several similar misalignments.</li>
<li>The names on the left side should be right-aligned but aren’t. Susie Wiles is way out of her chair, while David Sacks has nearly crashed into his.</li>
<li>Similarly, the names on the right side should be left-aligned but aren’t. See Richard Walters and Sanjay Mehrotra for the most extreme misalignments.</li>
</ul>
<p>And then there’s the best one:</p>
<ul>
<li>The chairs are facing away from the table.</li>
</ul>
<p>The meeting probably would have been better for all of us if this had been so.</p>]]>
</content:encoded>
</item>

<item>
<title>A small probability correction</title>
<link>https://leancrew.com/all-this/2026/09/a-small-probability-correction/</link>
<pubDate>Tue, 29 Sep 2026 15:35:09 +0000</pubDate>
<dc:creator>
  <![CDATA[Dr. Drang]]>
</dc:creator>
<guid>https://leancrew.com/all-this/2026/09/a-small-probability-correction/</guid>
<description>
  <![CDATA[<a href="https://youtube.com/shorts/2xw2d46fwYc">This short video</a> appeared in my YouTube feed last week. It’s from <a href="https://hannahfry.co.uk/">Hannah Fry</a>, whom you probably know from her appearances on <a href="https://www.youtube.com/numberphile">Numberphile</a> and other STEM-oriented stuff. If you’re in the UK, you’ve may have seen her on the BBC, too.]]>
</description>
<content:encoded>
  <![CDATA[<p>[Equations in this post may not look right (or appear at all) in your RSS reader. Go to <a href="https://leancrew.com/all-this/2026/09/a-small-probability-correction/">the original article</a> to see them rendered properly.]</p>
  <hr />
  <p><a href="https://youtube.com/shorts/2xw2d46fwYc">This short video</a> appeared in my YouTube feed last week. It’s from <a href="https://hannahfry.co.uk/">Hannah Fry</a>, whom you probably know from her appearances on <a href="https://www.youtube.com/numberphile">Numberphile</a> and other STEM-oriented stuff. If you’re in the UK, you’ve may have seen her on the BBC, too.</p>
<p>The short presents a classic problem in conditional probability, but the answer she comes up with is wrong. It’s a good estimate, and it’s the same answer I got when I stopped the video and tried to work it out in my head, but it’s still wrong. By just a little bit.</p>
<iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="" frameborder="0" height="720" src="https://www.youtube.com/embed/2xw2d46fwYc" title="YouTube video player" width="405"></iframe>
<p>Here’s the problem: There’s a disease that affects 1 in 1,000 people. A test for the disease is perfect in one sense but imperfect in another. If you have the disease, the test will return a positive result 100% of the time. If you don’t have the disease, the test will return a negative result 95% of the time but a positive result 5% of the time. If you have the test and the result is positive, what is the probability you have the disease?</p>
<p>What makes this a classic problem is that it presents you with conditional probability in one sense (the probability of a positive test given that you have the disease) and asks for a conditional probability in the opposite sense (the probability that you have the disease given that your test was positive). The solution combines <a href="https://en.wikipedia.org/wiki/Conditional_probability">the definition of conditional probability</a>, the <a href="https://en.wikipedia.org/wiki/Commutative_property#Commutative_operations">commutative property of intersections</a>, and <a href="https://en.wikipedia.org/wiki/Law_of_total_probability">the law of total probability</a>.</p>
<p>Let’s define some events. <!-- $D$ --><math xmlns="http://www.w3.org/1998/Math/MathML"><mi>D</mi></math> is you having the disease, and <!-- $T$ --><math xmlns="http://www.w3.org/1998/Math/MathML"><mi>T</mi></math> is you getting a positive test result. Putting a horizontal bar over these indicates <em>not</em> having the disease and <em>not</em> testing positive (i.e., testing negative), respectively. Therefore</p>
<p><!-- $$ \begin{align*}
P(D) &= 0.001 \\
P(\overline{D}) &= 0.999 \\
P(T \mid D) &= 1 \\
P(\overline{T} \mid \overline{D}) &= 0.95 \\
P(T \mid \overline{D}) &= 0.05
\end{align*} $$ -->
<math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><mtable><mtr><mtd columnalign="right" style="text-align: right; padding-right: 0"><mi>P</mi><mo form="prefix" stretchy="false">(</mo><mi>D</mi><mo form="postfix" stretchy="false">)</mo></mtd><mtd columnalign="left" style="text-align: left; padding-left: 0"><mo>=</mo><mn>0.001</mn></mtd></mtr><mtr><mtd columnalign="right" style="text-align: right; padding-right: 0"><mi>P</mi><mo form="prefix" stretchy="false">(</mo><mover><mi>D</mi><mo accent="true">—</mo></mover><mo form="postfix" stretchy="false">)</mo></mtd><mtd columnalign="left" style="text-align: left; padding-left: 0"><mo>=</mo><mn>0.999</mn></mtd></mtr><mtr><mtd columnalign="right" style="text-align: right; padding-right: 0"><mi>P</mi><mo form="prefix" stretchy="false">(</mo><mi>T</mi><mo>∣</mo><mi>D</mi><mo form="postfix" stretchy="false">)</mo></mtd><mtd columnalign="left" style="text-align: left; padding-left: 0"><mo>=</mo><mn>1</mn></mtd></mtr><mtr><mtd columnalign="right" style="text-align: right; padding-right: 0"><mi>P</mi><mo form="prefix" stretchy="false">(</mo><mover><mi>T</mi><mo accent="true">—</mo></mover><mo>∣</mo><mover><mi>D</mi><mo accent="true">—</mo></mover><mo form="postfix" stretchy="false">)</mo><mspace width=".25em"></mspace></mtd><mtd columnalign="left" style="text-align: left; padding-left: 0"><mo>=</mo><mn>0.95</mn></mtd></mtr><mtr><mtd columnalign="right" style="text-align: right; padding-right: 0"><mi>P</mi><mo form="prefix" stretchy="false">(</mo><mi>T</mi><mo>∣</mo><mover><mi>D</mi><mo accent="true">—</mo></mover><mo form="postfix" stretchy="false">)</mo></mtd><mtd columnalign="left" style="text-align: left; padding-left: 0"><mo>=</mo><mn>0.05</mn></mtd></mtr></mtable></math></p>
<p>The vertical bars are read as “given,” meaning the event after the bar is the condition. What we’ve been asked to find is <!-- $P(D \mid T)$ --><math xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mi>P</mi><mo form="prefix" stretchy="false">(</mo><mi>D</mi><mo>∣</mo><mi>T</mi><mo form="postfix" stretchy="false">)</mo></mrow></math>. Let’s work it out.</p>
<p>By the definition of conditional probability, we can say</p>
<p><!-- $$ P(D \cap T) = P(D \mid T) \, P(T) $$ -->
<math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mi>P</mi><mo form="prefix" stretchy="false">(</mo><mi>D</mi><mo>∩</mo><mi>T</mi><mo form="postfix" stretchy="false">)</mo><mo>=</mo><mi>P</mi><mo form="prefix" stretchy="false">(</mo><mi>D</mi><mo>∣</mo><mi>T</mi><mo form="postfix" stretchy="false">)</mo><mspace width="0.167em"></mspace><mi>P</mi><mo form="prefix" stretchy="false">(</mo><mi>T</mi><mo form="postfix" stretchy="false">)</mo></mrow></math></p>
<p>where <!-- $\cap$ --><math xmlns="http://www.w3.org/1998/Math/MathML"><mi>∩</mi></math> means the intersection of the two events. So</p>
<p><!-- $$ P(D \mid T) = \frac{P(D \cap T)}{P(T)} $$ -->
<math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mi>P</mi><mo form="prefix" stretchy="false">(</mo><mi>D</mi><mo>∣</mo><mi>T</mi><mo form="postfix" stretchy="false">)</mo><mo>=</mo><mfrac><mrow><mi>P</mi><mo form="prefix" stretchy="false">(</mo><mi>D</mi><mo>∩</mo><mi>T</mi><mo form="postfix" stretchy="false">)</mo></mrow><mrow><mi>P</mi><mo form="prefix" stretchy="false">(</mo><mi>T</mi><mo form="postfix" stretchy="false">)</mo></mrow></mfrac></mrow></math></p>
<p>Because the intersection of events is commutative</p>
<p><!-- $$ P(D \cap T) = P(T \cap D) = P(T \mid D) \, P(D) $$ -->
<math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mi>P</mi><mo form="prefix" stretchy="false">(</mo><mi>D</mi><mo>∩</mo><mi>T</mi><mo form="postfix" stretchy="false">)</mo><mo>=</mo><mi>P</mi><mo form="prefix" stretchy="false">(</mo><mi>T</mi><mo>∩</mo><mi>D</mi><mo form="postfix" stretchy="false">)</mo><mo>=</mo><mi>P</mi><mo form="prefix" stretchy="false">(</mo><mi>T</mi><mo>∣</mo><mi>D</mi><mo form="postfix" stretchy="false">)</mo><mspace width="0.167em"></mspace><mi>P</mi><mo form="prefix" stretchy="false">(</mo><mi>D</mi><mo form="postfix" stretchy="false">)</mo></mrow></math></p>
<p>Both terms on the right-hand side of this equation are known, so we can say</p>
<p><!-- $$ P(D \mid T) = \frac{(1)(0.001)}{P(T)} $$ -->
<math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mi>P</mi><mo form="prefix" stretchy="false">(</mo><mi>D</mi><mo>∣</mo><mi>T</mi><mo form="postfix" stretchy="false">)</mo><mo>=</mo><mfrac><mrow><mo form="prefix" stretchy="false">(</mo><mn>1</mn><mo form="postfix" stretchy="false">)</mo><mo form="prefix" stretchy="false">(</mo><mn>0.001</mn><mo form="postfix" stretchy="false">)</mo></mrow><mrow><mi>P</mi><mo form="prefix" stretchy="false">(</mo><mi>T</mi><mo form="postfix" stretchy="false">)</mo></mrow></mfrac></mrow></math></p>
<p>Since <!-- $D$ --><math xmlns="http://www.w3.org/1998/Math/MathML"><mi>D</mi></math> and <!-- $\overline{D}$ --><math xmlns="http://www.w3.org/1998/Math/MathML"><mover><mi>D</mi><mo accent="true">—</mo></mover></math> are mutually exclusive and collectively exhaustive, the law of total probability says</p>
<p><!-- $$ \begin{align}
P(T) &= P(T \mid D) \, P(D) + P(T \mid \overline{D}) \, P(\overline{D}) \\
 &= (1)(0.001) + (0.05)(0.999) \\
 &= 0.05095
\end{align} $$ -->
<math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><mtable><mtr><mtd columnalign="right" style="text-align: right; padding-right: 0"><mi>P</mi><mo form="prefix" stretchy="false">(</mo><mi>T</mi><mo form="postfix" stretchy="false">)</mo></mtd><mtd columnalign="left" style="text-align: left; padding-left: 0"><mo>=</mo><mi>P</mi><mo form="prefix" stretchy="false">(</mo><mi>T</mi><mo>∣</mo><mi>D</mi><mo form="postfix" stretchy="false">)</mo><mspace width="0.167em"></mspace><mi>P</mi><mo form="prefix" stretchy="false">(</mo><mi>D</mi><mo form="postfix" stretchy="false">)</mo><mo>+</mo><mi>P</mi><mo form="prefix" stretchy="false">(</mo><mi>T</mi><mo>∣</mo><mover><mi>D</mi><mo accent="true">—</mo></mover><mo form="postfix" stretchy="false">)</mo><mspace width="0.167em"></mspace><mi>P</mi><mo form="prefix" stretchy="false">(</mo><mover><mi>D</mi><mo accent="true">—</mo></mover><mo form="postfix" stretchy="false">)</mo></mtd></mtr><mtr><mtd columnalign="right" style="text-align: right; padding-right: 0"></mtd><mtd columnalign="left" style="text-align: left; padding-left: 0"><mo>=</mo><mo form="prefix" stretchy="false">(</mo><mn>1</mn><mo form="postfix" stretchy="false">)</mo><mo form="prefix" stretchy="false">(</mo><mn>0.001</mn><mo form="postfix" stretchy="false">)</mo><mo>+</mo><mo form="prefix" stretchy="false">(</mo><mn>0.05</mn><mo form="postfix" stretchy="false">)</mo><mo form="prefix" stretchy="false">(</mo><mn>0.999</mn><mo form="postfix" stretchy="false">)</mo></mtd></mtr><mtr><mtd columnalign="right" style="text-align: right; padding-right: 0"></mtd><mtd columnalign="left" style="text-align: left; padding-left: 0"><mo>=</mo><mn>0.05095</mn></mtd></mtr></mtable></math></p>
<p>So</p>
<p><!-- $$ P(D \mid T) = \frac{0.001}{0.05095} = 0.019627 $$ -->
<math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mi>P</mi><mo form="prefix" stretchy="false">(</mo><mi>D</mi><mo>∣</mo><mi>T</mi><mo form="postfix" stretchy="false">)</mo><mo>=</mo><mfrac><mn>0.001</mn><mn>0.05095</mn></mfrac><mo>=</mo><mn>0.019627</mn></mrow></math></p>
<p>which is, as I said, pretty close to the 2% answer in the video but not exactly.</p>
<p>This formal approach is how you’re taught to solve problems like this in an introductory probability class, but Dr. Fry and I used a more concrete method to get our nearly correct answers. Here’s what we did:</p>
<p>Imagine 1,000 typical people. Of these, 1 should have the disease (correct) and 50 should test positive (incorrect). That tells us that 1 in 50, or 2%, of the people who test positive will have the disease. Here’s a screenshot from the video that matches this calculation:</p>
<p><img alt="Illustration using 1000 people" class="ss" src="https://leancrew.com/all-this/images2026/20260929-Illustration%20using%201000%20people.jpg" title="Illustration using 1000 people" width="65%"/></p>
<p>What makes this calculation wrong is that it implicitly assumes that 5% of <em>everyone</em> will test positive, not 5% of only those who don’t have the disease. The number who will test positive should be 5% of 999, which is 49.95, plus the 1 who does have the disease. So 1 in 50.95, or 1.9627%, of those who test positive will have the disease. This answer matches that of the formal approach.</p>
<p>This is somewhat unsatisfying, though, as the purpose of this “imagine a bunch of typical people” method is to have all the people counts be integers. Although the numbers work out when you get to the end, it’s distracting to litter the discussion with fractional people. You can get around this by imagining more people—a million, say—but then all the numbers get bigger: 1,000 people with the disease and 49,950 false positives. This isn’t a problem for the kind of people who read this blog but isn’t so great for the more general audience Dr. Fry is addressing.</p>
<p>Personally, I would have been OK with her saying that 5% of 999 is almost 50, so the number who test positive is nearly 51. And 1 out of 51 is just under 2%—call it 2% in round figures. You still make the point that it’s way less than 95% and that problems like this require some care.</p>
  ]]>
</content:encoded>
</item>

<item>
<title>Equinox</title>
<link>https://leancrew.com/all-this/2026/09/equinox/</link>
<pubDate>Wed, 23 Sep 2026 00:05:13 +0000</pubDate>
<dc:creator>
  <![CDATA[Dr. Drang]]>
</dc:creator>
<guid>https://leancrew.com/all-this/2026/09/equinox/</guid>
<description>
  <![CDATA[The episode of <em>The West Wing</em> that’s always bothered me is “Evidence of Things Not Seen,” which is <a href="https://westwing.fandom.com/wiki/Evidence_of_Things_Not_Seen">Episode 20 of Season 4</a>. It takes place on the day of the equinox (in March, not September, but I remembered it because today is an equinox), and one of the continuing subplots is C.J. trying to convince the others that you can stand an egg on its end at the exact moment of the equinox and only at that moment. Oh, and it has to be the vernal equinox, not the autumnal one.<sup id="fnref:south"><a href="#fn:south" rel="footnote">1</a></sup>]]>
</description>
<content:encoded>
  <![CDATA[<p>The episode of <em>The West Wing</em> that’s always bothered me is “Evidence of Things Not Seen,” which is <a href="https://westwing.fandom.com/wiki/Evidence_of_Things_Not_Seen">Episode 20 of Season 4</a>. It takes place on the day of the equinox (in March, not September, but I remembered it because today is an equinox), and one of the continuing subplots is C.J. trying to convince the others that you can stand an egg on its end at the exact moment of the equinox and only at that moment. Oh, and it has to be the vernal equinox, not the autumnal one.<sup id="fnref:south"><a href="#fn:south" rel="footnote">1</a></sup></p>
<p>That someone in the glorious Bartlet White House believes in nonsense isn’t what bothers me. Lots of smart people believe silly things. What’s wrong is that it’s C.J., the primary female character, who believes in superstition while the men around her are pooh-poohing it. I’m sure plenty of women will tell me that’s par for the course for Aaron Sorkin, but it still bothers me.</p>
<p>There are two small counters to the general sexism of the egg subplot. First, the men who tell C.J. she’s full of it are themselves wrong. They think you can’t balance an egg on its end, even though it’s not really that hard.</p>
<p><img alt="Egg balanced on its end" class="ss" src="https://leancrew.com/all-this/images2026/20260922-Egg%20balanced%20on%20its%20end.jpg" title="Egg balanced on its end" width="80%"/></p>
<p>This photo was taken today (yes, on the equinox but not the vernal equinox and not at the exact moment) on my back patio. I didn’t do any tricks like slightly crack the shell or put it on a bit of salt and then blow the salt away. I just kept adjusting its position again and again until it stood. The plain fact is that it just takes a little time to balance an egg on its end, time that most people aren’t willing to spend. (And yes, it helps to have a rough surface.)</p>
<p>The second counter is that Jed seems willing to believe the egg story. He doesn’t defend C.J., but he does try to stand an egg on end in his office. In some ways, this is worse. For all his faults, Jed is supposed to know at least a bit about science. Remember the episode in which C.J. has to remind him to let the NASA experts handle the science questions coming in from schoolkids? If anyone should be instantly dismissive of the standing egg myth, it should be Jed.</p>
<p>At the very end of the show, C.J.’s alone and manages to balance an egg on its end, justifying her faith. The title comes from Hebrews 11:1, which she recites earlier in the episode. I guess this is supposed to get us to think that she hasn’t been spouting nonsense all this time, but what it really means is that she can do what anyone can do if they take their time.</p>
<p>What bothers me the most is the setup for her balancing act. Before trying, she looks pointedly at the clock, which shows midnight. Recall that the balancing is supposed to work only at the exact moment of the equinox. Does Sorkin think equinoxes always occur at midnight? Does he think the audience is dumb enough to believe that? The episode aired in April 2003, so I guess its events take place on March 20 of that year. In Washington, <a href="https://www.windom.org/mycog.com/equinox.htm">the 2003 vernal equinox</a> occurred at about 8:00 pm, not four hours later. Was the show set a year or two earlier? No midnight spring equinoxes those years, either.</p>
<p>If you’re interested in the history of the egg balancing myth, Martin Gardner wrote an article about it in 1996. You can see the text on the <a href="https://web.archive.org/web/20070221082438/http://www.findarticles.com/p/articles/mi_m2843/is_n3_v20/ai_18372128">Wayback Machine</a>.</p>
<div class="footnotes">
<hr/>
<ol>
<li id="fn:south">
<p>No one ever asks whether the egg balancing would work if they were in Buenos Aires instead of Washington. <a href="#fnref:south" rev="footnote">↩</a></p>
</li>
</ol>
</div>]]>
</content:encoded>
</item>

<item>
<title>Cleaning up after Matt Parker</title>
<link>https://leancrew.com/all-this/2026/09/cleaning-up-after-matt-parker/</link>
<pubDate>Thu, 17 Sep 2026 04:36:43 +0000</pubDate>
<dc:creator>
  <![CDATA[Dr. Drang]]>
</dc:creator>
<guid>https://leancrew.com/all-this/2026/09/cleaning-up-after-matt-parker/</guid>
<description>
  <![CDATA[<a href="https://www.youtube.com/watch?v=k3sIHbj-TUI">This video</a> Matt Parker posted a couple of days ago really pissed me off:]]>
</description>
<content:encoded>
  <![CDATA[<p>[Equations in this post may not look right (or appear at all) in your RSS reader. Go to <a href="https://leancrew.com/all-this/2026/09/cleaning-up-after-matt-parker/">the original article</a> to see them rendered properly.]</p>
  <hr />
  <p><a href="https://www.youtube.com/watch?v=k3sIHbj-TUI">This video</a> Matt Parker posted a couple of days ago really pissed me off:</p>
<iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="" frameborder="0" height="315" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube.com/embed/k3sIHbj-TUI?si=bTN92Wcda6mWQLER" title="YouTube video player" width="560"></iframe>
<p>It’s cheating to say that a result arrived at through classical mechanics—in this case, that <!-- $\frac{1}{2} m v^2$ --><math xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mfrac><mn>1</mn><mn>2</mn></mfrac><mi>m</mi><msup><mi>v</mi><mn>2</mn></msup></mrow></math> is the kinetic energy of a particle—is wrong because it’s only an approximation to relativistic physics. Of course that’s the case, and I swore at my phone when the “reveal” came.</p>
<p>By the end of the video, though, I had calmed down because I knew I could put together a quick post of my own by rewriting the infinite series equation he derived in a better form. Also, I could provide a general expression for the individual terms.</p>
<p>Let’s start with this result: that the kinetic energy of a particle (including relativistic effects) is</p>
<p><!-- $$ m c^2 ( \gamma - 1 ) $$ -->
<math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mi>m</mi><msup><mi>c</mi><mn>2</mn></msup><mo form="prefix" stretchy="false">(</mo><mi>γ</mi><mo>−</mo><mn>1</mn><mo form="postfix" stretchy="false">)</mo></mrow></math></p>
<p>where <em>m</em> is the mass of the particle, <em>c</em> is the speed of light, and</p>
<p><!-- $$ \gamma = \frac{1}{\sqrt{ 1 - \frac{v^2}{c^2} } } $$ -->
<math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mi>γ</mi><mo>=</mo><mfrac><mn>1</mn><msqrt><mrow><mn>1</mn><mo>−</mo><mfrac><msup><mi>v</mi><mn>2</mn></msup><msup><mi>c</mi><mn>2</mn></msup></mfrac></mrow></msqrt></mfrac></mrow></math></p>
<p>is the <a href="https://en.wikipedia.org/wiki/Lorentz_factor">Lorentz factor</a>, with <em>v</em> as the velocity of the particle. The video gets to this result at about the 8-minute mark.</p>
<p>Matt then does a series expansion of the <!-- $\gamma$ --><math xmlns="http://www.w3.org/1998/Math/MathML"><mi>γ</mi></math> term to get</p>
<p><!-- $$ \gamma = 1 + \frac{1}{2}\,\frac{v^2}{c^2} + \frac{3}{8}\,\frac{v^4}{c^4} + \frac{5}{16}\,\frac{v^6}{c^6} + \frac{35}{128}\,\frac{v^8}{c^8} + \ldots $$ -->
<math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mi>γ</mi><mo>=</mo><mn>1</mn><mo>+</mo><mfrac><mn>1</mn><mn>2</mn></mfrac><mspace width="0.167em"></mspace><mfrac><msup><mi>v</mi><mn>2</mn></msup><msup><mi>c</mi><mn>2</mn></msup></mfrac><mo>+</mo><mfrac><mn>3</mn><mn>8</mn></mfrac><mspace width="0.167em"></mspace><mfrac><msup><mi>v</mi><mn>4</mn></msup><msup><mi>c</mi><mn>4</mn></msup></mfrac><mo>+</mo><mfrac><mn>5</mn><mn>16</mn></mfrac><mspace width="0.167em"></mspace><mfrac><msup><mi>v</mi><mn>6</mn></msup><msup><mi>c</mi><mn>6</mn></msup></mfrac><mo>+</mo><mfrac><mn>35</mn><mn>128</mn></mfrac><mspace width="0.167em"></mspace><mfrac><msup><mi>v</mi><mn>8</mn></msup><msup><mi>c</mi><mn>8</mn></msup></mfrac><mo>+</mo><mi>…</mi></mrow></math></p>
<p>The leading 1 of this series gets canceled by the 1 that’s subtracted from <em>γ</em>, giving</p>
<p><!-- $$ \frac{1}{2}\,m v^2 + \frac{3}{8}\,m \frac{v^4}{c^2} + \frac{5}{16}\,m \frac{v^6}{c^4} + \frac{35}{128}\,m \frac{v^8}{c^6} + \ldots $$ -->
<math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mfrac><mn>1</mn><mn>2</mn></mfrac><mspace width="0.167em"></mspace><mi>m</mi><msup><mi>v</mi><mn>2</mn></msup><mo>+</mo><mfrac><mn>3</mn><mn>8</mn></mfrac><mspace width="0.167em"></mspace><mi>m</mi><mfrac><msup><mi>v</mi><mn>4</mn></msup><msup><mi>c</mi><mn>2</mn></msup></mfrac><mo>+</mo><mfrac><mn>5</mn><mn>16</mn></mfrac><mspace width="0.167em"></mspace><mi>m</mi><mfrac><msup><mi>v</mi><mn>6</mn></msup><msup><mi>c</mi><mn>4</mn></msup></mfrac><mo>+</mo><mfrac><mn>35</mn><mn>128</mn></mfrac><mspace width="0.167em"></mspace><mi>m</mi><mfrac><msup><mi>v</mi><mn>8</mn></msup><msup><mi>c</mi><mn>6</mn></msup></mfrac><mo>+</mo><mi>…</mi></mrow></math></p>
<p>for the kinetic energy. The leading term is the one we get from classical mechanics and the others are essentially zero unless you’re in a particle accelerator (which is discussed later in the video).</p>
<p>I don’t like this form for the equation. It’s cleaner if you factor out all the terms that give the expression the units of energy and then have a nondimensional expression afterward. Like this:</p>
<p><!-- $$ \frac{1}{2}\,m v^2 \, \left( 1 + \frac{3}{4}\,\frac{v^2}{c^2} + \frac{5}{8}\,\frac{v^4}{c^4}+ \frac{35}{64}\,\frac{v^6}{c^6} + \ldots \right) $$ -->
<math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mfrac><mn>1</mn><mn>2</mn></mfrac><mspace width="0.167em"></mspace><mi>m</mi><msup><mi>v</mi><mn>2</mn></msup><mspace width="0.167em"></mspace><mrow><mo form="prefix" stretchy="true">(</mo><mn>1</mn><mo>+</mo><mfrac><mn>3</mn><mn>4</mn></mfrac><mspace width="0.167em"></mspace><mfrac><msup><mi>v</mi><mn>2</mn></msup><msup><mi>c</mi><mn>2</mn></msup></mfrac><mo>+</mo><mfrac><mn>5</mn><mn>8</mn></mfrac><mspace width="0.167em"></mspace><mfrac><msup><mi>v</mi><mn>4</mn></msup><msup><mi>c</mi><mn>4</mn></msup></mfrac><mo>+</mo><mfrac><mn>35</mn><mn>64</mn></mfrac><mspace width="0.167em"></mspace><mfrac><msup><mi>v</mi><mn>6</mn></msup><msup><mi>c</mi><mn>6</mn></msup></mfrac><mo>+</mo><mi>…</mi><mo form="postfix" stretchy="true">)</mo></mrow></mrow></math></p>
<p>Isn’t this nicer? The expression in the parentheses is a function of the ratio of the velocity of the particle to the speed of light. If we call that</p>
<p><!-- $$ \phi = \frac{v}{c} $$ -->
<math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mi>ϕ</mi><mo>=</mo><mfrac><mi>v</mi><mi>c</mi></mfrac></mrow></math></p>
<p>then the kinetic energy is</p>
<p><!-- $$ \frac{1}{2}\,m v^2 \, \left( 1 + \frac{3}{4}\,\phi^2 + \frac{5}{8}\,\phi^4 + \frac{35}{64}\,\phi^6 + \ldots \right) $$ -->
<math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mfrac><mn>1</mn><mn>2</mn></mfrac><mspace width="0.167em"></mspace><mi>m</mi><msup><mi>v</mi><mn>2</mn></msup><mspace width="0.167em"></mspace><mrow><mo form="prefix" stretchy="true">(</mo><mn>1</mn><mo>+</mo><mfrac><mn>3</mn><mn>4</mn></mfrac><mspace width="0.167em"></mspace><msup><mi>ϕ</mi><mn>2</mn></msup><mo>+</mo><mfrac><mn>5</mn><mn>8</mn></mfrac><mspace width="0.167em"></mspace><msup><mi>ϕ</mi><mn>4</mn></msup><mo>+</mo><mfrac><mn>35</mn><mn>64</mn></mfrac><mspace width="0.167em"></mspace><msup><mi>ϕ</mi><mn>6</mn></msup><mo>+</mo><mi>…</mi><mo form="postfix" stretchy="true">)</mo></mrow></mrow></math></p>
<p>and it’s much easier to see why the terms after the 1 are vanishingly small for most situations—all the situations for which classical mechanics applies.</p>
<p>One last thing. Matt sort of explained how to calculate the terms of the expansion of <em>γ</em> in <a href="https://www.youtube.com/watch?v=VyYKwJanACI">the companion video</a>, but there was a lot of handwaving and he bailed out after the second term. It doesn’t take too much effort to show that the series expansion of <em>γ</em> can be written like this:</p>
<p><!-- $$ \gamma = \sum_{n = 0, 2, 4, \ldots}^\infty \; \frac{n!}{2^n \; \left[\left(n/2\right)! \right]^2} \; \phi^n $$ -->
<math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mi>γ</mi><mo>=</mo><munderover><mo>∑</mo><mrow><mi>n</mi><mo>=</mo><mn>0</mn><mo>,</mo><mn>2</mn><mo>,</mo><mn>4</mn><mo>,</mo><mi>…</mi></mrow><mo accent="false">∞</mo></munderover><mspace width="0.278em"></mspace><mfrac><mrow><mi>n</mi><mi>!</mi></mrow><mrow><msup><mn>2</mn><mi>n</mi></msup><mspace width="0.278em"></mspace><msup><mrow><mo form="prefix" stretchy="true">[</mo><mrow><mo form="prefix" stretchy="true">(</mo><mi>n</mi><mi>/</mi><mn>2</mn><mo form="postfix" stretchy="true">)</mo></mrow><mi>!</mi><mo form="postfix" stretchy="true">]</mo></mrow><mn>2</mn></msup></mrow></mfrac><mspace width="0.278em"></mspace><msup><mi>ϕ</mi><mi>n</mi></msup></mrow></math></p>
<p>That means the kinetic energy, <!-- $m c^2 (\gamma - 1)$ --><math xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mi>m</mi><msup><mi>c</mi><mn>2</mn></msup><mo form="prefix" stretchy="false">(</mo><mi>γ</mi><mo>−</mo><mn>1</mn><mo form="postfix" stretchy="false">)</mo></mrow></math>, is</p>
<p><!-- $$ \frac{1}{2} \, m v^2 \sum_{n = 2, 4, 6, \ldots}^\infty \; \frac{n!}{2^{n-1} \; \left[\left(n/2\right)! \right]^2} \; \phi^{n-2} $$ -->
<math display="block" xmlns="http://www.w3.org/1998/Math/MathML"><mrow><mfrac><mn>1</mn><mn>2</mn></mfrac><mspace width="0.167em"></mspace><mi>m</mi><msup><mi>v</mi><mn>2</mn></msup><munderover><mo>∑</mo><mrow><mi>n</mi><mo>=</mo><mn>2</mn><mo>,</mo><mn>4</mn><mo>,</mo><mn>6</mn><mo>,</mo><mi>…</mi></mrow><mo accent="false">∞</mo></munderover><mspace width="0.278em"></mspace><mfrac><mrow><mi>n</mi><mi>!</mi></mrow><mrow><msup><mn>2</mn><mrow><mi>n</mi><mo>−</mo><mn>1</mn></mrow></msup><mspace width="0.278em"></mspace><msup><mrow><mo form="prefix" stretchy="true">[</mo><mrow><mo form="prefix" stretchy="true">(</mo><mi>n</mi><mi>/</mi><mn>2</mn><mo form="postfix" stretchy="true">)</mo></mrow><mi>!</mi><mo form="postfix" stretchy="true">]</mo></mrow><mn>2</mn></msup></mrow></mfrac><mspace width="0.333em"></mspace><msup><mi>ϕ</mi><mrow><mi>n</mi><mo>−</mo><mn>2</mn></mrow></msup></mrow></math></p>
<p>You can confirm that these terms match the equation we saw earlier by plugging values of <em>n</em> from 2 through 8 into this expression. And now we can extend the series as far as we like, even though the additional terms add essentially nothing.</p>
  ]]>
</content:encoded>
</item>

<item>
<title>Apple drawings</title>
<link>https://leancrew.com/all-this/2026/09/apple-drawings/</link>
<pubDate>Tue, 15 Sep 2026 01:09:55 +0000</pubDate>
<dc:creator>
  <![CDATA[Dr. Drang]]>
</dc:creator>
<guid>https://leancrew.com/all-this/2026/09/apple-drawings/</guid>
<description>
  <![CDATA[Everyone’s favorite Apple archivist, Stephen Hackett, wrote <a href="https://512pixels.net/2026/09/apple-dimensional-drawings/">a short post</a> last week in which he linked to Apple’s page with <a href="https://developer.apple.com/accessories/dimensional-drawings/">dimensional drawings</a> of its products. He included this drawing of the iPhone 17 Pro:]]>
</description>
<content:encoded>
  <![CDATA[<p>Everyone’s favorite Apple archivist, Stephen Hackett, wrote <a href="https://512pixels.net/2026/09/apple-dimensional-drawings/">a short post</a> last week in which he linked to Apple’s page with <a href="https://developer.apple.com/accessories/dimensional-drawings/">dimensional drawings</a> of its products. He included this drawing of the iPhone 17 Pro:</p>
<p><a href="https://leancrew.com/all-this/images2026/20260914-Apple%20iPhone%2017%20Pro%20300%20dpi.png"><img alt="Apple iPhone 17 Pro drawing" class="ss" src="https://leancrew.com/all-this/images2026/20260914-Apple%20iPhone%2017%20Pro%20drawing.png" title="Apple iPhone 17 Pro drawing" width="100%"/></a></p>
<p>You can click on it to see a 300 dpi version. The Apple page linked above will give you infinite-resolution PDFs.</p>
<p>When I zoomed in on Stephen’s page, I was initially confused, but then I realized what seemed odd to me. You see, I’ve spent an awful lot of the past 40 years looking at engineering drawings, and I can’t think of any that looked like this. That’s because the drawings I’m used to are for making the depicted product, but the drawings Apple’s offering up here aren’t for that.<sup id="fnref:secret"><a href="#fn:secret" rel="footnote">1</a></sup> These are for <em>others</em>—not Apple and not its suppliers—to use for making cases and other accessories. I figured it was worth a quick post on what makes a drawing like the one above so different from what I’m used to.</p>
<p>First off, there are so many dimensions. Drawings of full products are typically called <em>assembly drawings</em>, and they have almost no dimensions. What they do is show how the various component pieces (subassemblies) are put together. The subassemblies have their own drawings that show how they are put together from their components, which are themselves typically subassemblies. Eventually, you get down to the individual part drawings, which depict a single piece of metal or glass or plastic. At each level in this hierarchy, the drawings tend to include only the dimensions necessary to build the object depicted. You don’t include the length and diameter of a screw on an assembly drawing; you simply call out its part number (which is also its drawing number).</p>
<p>Speaking of drawing numbers, if you look in the title block you’ll see that there is no drawing number. Design drawings always have these. They also have the names or initials of the draftsmen and checkers and, usually, a list of revisions. These public drawings don’t reveal any of that internal information.</p>
<p>There are names for many of the items and dimensions: product length, display active area, volume button, rear sensor, etc. These are not common in design drawings because they tend to be of no value to those doing the manufacturing. You don’t need to know what this hole is for; just make it this big and put it here.</p>
<p>Which leads us to tolerances, which are absent. Dimensions and positions are given to the nearest hundredth of a millimeter and there is no give or take. To the outside world, Apple’s dimensions are absolute and invariable. Inside Apple and its suppliers, people know better.</p>
<p>Also absent is any specification of material, other than a few generic mentions of glass. While assembly drawings don’t usually include materials, parts drawings always refer to material specs, usually included in another company document.</p>
<p>The last thing I’ll mention is the Notes section in the upper left corner. It has instructions clearly meant for people outside of Apple and making accessories. If I’d zoomed in on this section first, I probably wouldn’t have been even momentarily confused.</p>
<div class="footnotes">
<hr/>
<ol>
<li id="fn:secret">
<p>Obviously. Apple isn’t going to post its design drawings; they’re among its most tightly controlled proprietary documents. Even for a company that considers everything a secret, the design drawings are <em>really</em> secret. <a href="#fnref:secret" rev="footnote">↩</a></p>
</li>
</ol>
</div>]]>
</content:encoded>
</item>

<item>
<title>New Apple Watches have ears</title>
<link>https://leancrew.com/all-this/2026/09/new-apple-watches-have-ears/</link>
<pubDate>Thu, 10 Sep 2026 03:42:27 +0000</pubDate>
<dc:creator>
  <![CDATA[Dr. Drang]]>
</dc:creator>
<guid>https://leancrew.com/all-this/2026/09/new-apple-watches-have-ears/</guid>
<description>
  <![CDATA[Starting about 45 minutes into <a href="https://www.apple.com/apple-events/">today’s Apple Event</a>, during the segment on the new Apple Watch, Ron Huang introduced a couple of features of the Series 12 and Ultra 4 that struck me as both disturbing and possibly illegal. They certainly seem at odds with Apple’s commitment to privacy.]]>
</description>
<content:encoded>
  <![CDATA[<p>Starting about 45 minutes into <a href="https://www.apple.com/apple-events/">today’s Apple Event</a>, during the segment on the new Apple Watch, Ron Huang introduced a couple of features of the Series 12 and Ultra 4 that struck me as both disturbing and possibly illegal. They certainly seem at odds with Apple’s commitment to privacy.</p>
<p>First came Live Rewind, a feature that lets you “go back in time” to pick up on something you missed that was said in the past 15 seconds. Here’s how Apple describes it <a href="https://www.apple.com/apple-watch-series-12/">on the website</a>:</p>
<blockquote>
<p>Live Rewind catches what you missed. Did someone say something you couldn’t hear in a loud restaurant or share cooking instructions you didn’t quite catch? Just double-click the Digital Crown, and Live Rewind transcribes what was said in the last 15 seconds. You can ask Siri about the content of the transcript or save it to the new Siri app to revisit later.</p>
</blockquote>
<p>In the Event, this was illustrated by a waitress going through the restaurant’s specials too quickly for the diners to remember all of them. One of the diners double-clicks the crown on his watch and reads what she said.</p>
<p><img alt="Screenshot of Live Rewind demo" class="ss" src="https://leancrew.com/all-this/images2026/20260909-Screenshot%20of%20Live%20Rewind%20demo.jpg" title="Screenshot of Live Rewind demo" width="100%"/></p>
<p>It seems like your watch will be listening continuously, keeping the last 15 seconds in a buffer, ready to be transcribed when you ask. That’s fine for you, because you know it’s happening, but what about those around you? Did they agree to this? I doubt wait staff will be upset with their spiel being transcribed, but the idea behind Live Rewind seems to be that <em>everyone and everything</em> near your watch is being recorded for 15 seconds. Surely, some people wouldn’t consent to that if they were asked. Significantly, though, they’re not being asked. I’m sure Apple will argue that there’s no privacy issue because the recordings aren’t being saved. But if there’s a transcription, isn’t that a type of saving?</p>
<p>And then there’s the question of legality. A <a href="https://en.wikipedia.org/wiki/Telephone_call_recording_laws">great variety of law</a>, both in the United States and across the world, concerns the recording of electronic and in-person conversations. I’m sure Apple has considered this, but I have to think some jurisdictions will frown on Live Rewind. If Apple has to defend it, that’s fine. What’s one more squadron of lawyers to Apple? But if an Apple Watch <em>owner</em> has to defend a transcription made innocently—made with Apple’s encouragement, in fact—that seems like an unfair burden. Maybe Apple should indemnify all future Watch buyers from privacy-related legal action.</p>
<p>Right after Live Rewind, we get the introduction of Siri Recap. From the Series 12 web page:</p>
<blockquote>
<p>Siri Recap can summarize your chats to refresh your memory. Siri Recap transforms your conversations into high-level notes, so you can stay focused and present. Each Siri Recap includes a title, a summary, and key points that you can review in the Siri app on your Apple Watch or iPhone. You can turn Siri Recap on or off at any time from Control Center or choose where and when it takes notes, such as only at work or never at night.</p>
</blockquote>
<p>Siri Recap does a summary, not a transcription, and it’s not automatic the way Live Rewind is, although it does sound as if you can set it up to always record when you’re at a certain place, so that’s kind of automatic. Apple touted Siri Recap’s privacy with three bullet points:</p>
<p><img alt="Screenshot of Siri Recap protections" class="ss" src="https://leancrew.com/all-this/images2026/20260909-Screenshot%20of%20Siri%20Recap%20protections.jpg" title="Screenshot of Siri Recap protections" width="100%"/></p>
<p>I think Apple is slicing the baloney pretty thin when it says audio isn’t recorded. Surely there’s some recording because summaries require context; they can’t be made on the fly. Maybe a transcription is done in near-real time and the summary is drawn from that. If so, the transcription is a type of recording, albeit one that isn’t stored after the summary is made. As for not identifying the speakers, I don’t see how that matters. Old-fashioned audio recordings don’t identify speakers, either, but they’re still intrusions on the speakers’ privacy if they didn’t give consent.</p>
<p>Apple has always focused on the privacy of its customers: <em>your</em> information is encrypted, <em>your</em> data stays on <em>your</em> device. It’s following that same pattern here, but the privacy concerns of Live Rewind and Siri Recap aren’t limited to the owners of Apple Watches. Apple now needs think about the privacy of non-customers and be able to explain how that’s being protected, too.</p>
<p>And while an argument can be made that textual transcriptions and recaps aren’t <em>as</em> invasive as saved audio recordings, that doesn’t mean they aren’t invasive at all. That little lock animation Apple’s been using to describe its commitment to privacy has been very effective, but its binary nature doesn’t fit when the products start putting privacy on a sliding scale.</p>
<div class="update">
<p><strong>Update 10 Sep 2026 8:14 PM</strong><br/>
On Mastodon, Bill Lloyd <a href="https://mastodon.social/@wklj/117248345208895614">sent me a link</a> to <a href="https://www.apple.com/privacy/docs/Audio_Intelligence_Privacy_Overview_Sep_2026.pdf">this longer document</a> from Apple with further explanation of Live Rewind and Siri Recap. The hoops Apple jumped through to avoid certain words is pretty funny. For example, in the discussion of Live Rewind, we learn that</p>
<blockquote>
<p>Audio from the microphone flows into the audio buffer inside the Secure Exclave on the S11 chip.</p>
</blockquote>
<p>You think your watch records the audio around you? No no no. The audio <em>flows</em> into the Secure Enclave, and flowing is definitely not recording because it’s a different word. Apple’s documentation poets liked <em>flow</em> so much, they also used it in the description of Siri Recap:</p>
<blockquote>
<p>If a conversation is detected, audio flows into a protected buffer inside the Secure Exclave on the S11 chip.</p>
</blockquote>
<p>Note also that the audio flows into a protected buffer <em>inside</em> the Secure Enclave, so that must make it doubly private.</p>
<p>Thanks for the entertaining link, Bill!</p>
</div>]]>
</content:encoded>
</item>

</channel>
</rss>

