<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="https://mitchellt.com/feed.xml" rel="self" type="application/atom+xml" /><link href="https://mitchellt.com/" rel="alternate" type="text/html" /><updated>2026-04-10T13:24:02-05:00</updated><id>https://mitchellt.com/feed.xml</id><title type="html">Mitchell Paulus</title><subtitle>HVAC ⋅ Building Commissioning ⋅ Software Engineering</subtitle><author><name>Mitchell T. Paulus</name></author><entry><title type="html">mysql CLI client</title><link href="https://mitchellt.com/mysql-cli" rel="alternate" type="text/html" title="mysql CLI client" /><published>2026-03-28T00:00:00-05:00</published><updated>2026-03-28T00:00:00-05:00</updated><id>https://mitchellt.com/ai-mysql-cli</id><content type="html" xml:base="https://mitchellt.com/mysql-cli"><![CDATA[<p>Wanted to share an anecdote on how AI tooling has upgraded my abilities.</p>

<p>I work with some internal <a href="https://www.mysql.com/">MySQL</a> databases.
Having useful CLI utilities is critical. Looking around, I was surprised to find that there wasn’t much out there.</p>

<p>Obviously, there is the <a href="https://dev.mysql.com/doc/refman/8.4/en/mysql.html">mysql</a> command line SQL shell that sometimes comes with the MySQL distribution.
I had difficulty following the best practices for authentication - which <code class="language-plaintext highlighter-rouge">.my.cnf</code> file, how to secure it because it was in plain text, learning even more tooling like <a href="https://dev.mysql.com/doc/refman/8.4/en/mysql-config-editor.html"><code class="language-plaintext highlighter-rouge">mysql_config_editor</code></a>.
I also require working in both Linux and Windows.</p>

<p>The shortcomings of the standard <code class="language-plaintext highlighter-rouge">mysql</code> utility are not necessarily relevant here.
What is important is that I found a need where all I wanted was a simple CLI utility that:</p>

<ol>
  <li>Explicitly worked in UTF-8 by default</li>
  <li>Handled JSON as the native format for data in and data out</li>
  <li>Simplified auth through environment variables like many modern CLIs</li>
  <li>Made inserting, upserting from JSON extremely simple</li>
  <li>Single file binary (used golang for this)</li>
</ol>

<p>So turned it over to the AI agents, and from 10:00 AM to 4:00 PM on one workday,
I had exactly the CLI I wanted (see commits <a href="https://github.com/mitchpaulus/mmysql/commits/main/?since=2026-03-13&amp;until=2026-03-13">here</a>).<sup id="fnref:1"><a href="#fn:1" class="footnote" rel="footnote" role="doc-noteref">1</a></sup></p>

<p>This is the kind of personal tooling that I just wouldn’t have been able to dedicate time to in the past.
But for CLIs like this where the problem statement is not difficult, implementation is straightforward, the original time would have been significantly filled with</p>

<ul>
  <li>Looking up docs on <code class="language-plaintext highlighter-rouge">encoding/json</code> and <code class="language-plaintext highlighter-rouge">database/sql</code> because I don’t have them memorized</li>
  <li>Literally typing out the ~600 lines</li>
</ul>

<p>All that time essentially disappears to <em>zero</em>.</p>

<p>I am reminded of this <a href="https://www.scattered-thoughts.net/writing/speed-matters/">great post by Jamie Brandon</a>, called “Speed matters”.
What’s important to note is that this post was written in <strong>2021</strong>, and includes the quote:</p>

<blockquote>
  <p>Being 10x faster also changes the kinds of projects that are worth doing.</p>
</blockquote>

<p>For me, it’s the Unix philosophy supercharged.</p>

<blockquote>
  <p>Write programs that do one thing and do it well.</p>
</blockquote>

<p>For the “doing it well”, the AIs can make me my perfect CLI tool that fits exactly my needs with a paragraph of prompt text.</p>

<p>Then it’s just up to me to dream up the possibilities with the combinatorics between those programs.</p>

<div class="footnotes" role="doc-endnotes">
  <ol>
    <li id="fn:1">
      <p>If this CLI is exactly what you wanted as well, go ahead and get it <a href="https://github.com/mitchpaulus/mmysql">here</a>, just remember this clause of the MIT license: <em>IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY…</em> <a href="#fnref:1" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
  </ol>
</div>]]></content><author><name>Mitchell T. Paulus</name></author><summary type="html"><![CDATA[Wanted to share an anecdote on how AI tooling has upgraded my abilities.]]></summary></entry><entry><title type="html">Pulsed Timers in Alerton Visual Logic Programming</title><link href="https://mitchellt.com/alerton-timer" rel="alternate" type="text/html" title="Pulsed Timers in Alerton Visual Logic Programming" /><published>2026-03-26T00:00:00-05:00</published><updated>2026-03-26T00:00:00-05:00</updated><id>https://mitchellt.com/Timer-Pulse-in-Alerton-Visual-Logic</id><content type="html" xml:base="https://mitchellt.com/alerton-timer"><![CDATA[<p>This is a reminder to myself on how to generate a pulsed timer in Alerton Visual Logic.</p>

<p>Essentially need 3 blocks plus the AV point for the timer length in seconds.</p>

<ul>
  <li>Delay on Make</li>
  <li>Delay on Break</li>
  <li>One Shot</li>
</ul>

<p>With the following setup:</p>

<ul>
  <li>AV-1: Timer interval in seconds</li>
  <li>BV-1: Dedicated intermediate timer value</li>
  <li>BV-2: Output</li>
</ul>

<p>and the nomenclature:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Output = DOM(Seconds, Input)
</code></pre></div></div>

<table>
  <thead>
    <tr>
      <th>Line Num</th>
      <th>Block</th>
      <th>Comment</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>1</td>
      <td><code class="language-plaintext highlighter-rouge">BR-0 = DOM(AV-1, NOT(BV-1))</code></td>
      <td>Input of timer is negation of output of following DOB</td>
    </tr>
    <tr>
      <td>2</td>
      <td><code class="language-plaintext highlighter-rouge">BV-1 = DOB(0.5, BR-0)</code></td>
      <td>Timer length here is short, doesn’t really matter too much</td>
    </tr>
    <tr>
      <td>3</td>
      <td><code class="language-plaintext highlighter-rouge">BV-2 = OneShot(BV-1)</code></td>
      <td>Make sure that the output is a pulse for one DDC cycle</td>
    </tr>
  </tbody>
</table>

<p>The astute here may notice that the second delay on break isn’t really necessary.
My understanding is that on some controllers the OneShot could be finicky on single pass DDC transitions.
So the short timer is just to ensure the following OneShot works as intended for robustness.</p>]]></content><author><name>Mitchell T. Paulus</name></author><summary type="html"><![CDATA[This is a reminder to myself on how to generate a pulsed timer in Alerton Visual Logic.]]></summary></entry><entry><title type="html">Fixing Outlook cursor glitch</title><link href="https://mitchellt.com/outlook" rel="alternate" type="text/html" title="Fixing Outlook cursor glitch" /><published>2026-02-19T00:00:00-06:00</published><updated>2026-02-19T00:00:00-06:00</updated><id>https://mitchellt.com/outlook-glitch</id><content type="html" xml:base="https://mitchellt.com/outlook"><![CDATA[<p>This is a quick fix reminder to myself.
Sometimes the cursor over Outlook disappears.
Workaround has been to manage to create a “new email” window,
then the previous window seems to work.</p>]]></content><author><name>Mitchell T. Paulus</name></author><summary type="html"><![CDATA[This is a quick fix reminder to myself. Sometimes the cursor over Outlook disappears. Workaround has been to manage to create a “new email” window, then the previous window seems to work.]]></summary></entry><entry><title type="html">Fixing “wsl: Failed to configure network”</title><link href="https://mitchellt.com/wsl-fail" rel="alternate" type="text/html" title="Fixing “wsl: Failed to configure network”" /><published>2026-01-21T00:00:00-06:00</published><updated>2026-01-21T00:00:00-06:00</updated><id>https://mitchellt.com/WSL-fail</id><content type="html" xml:base="https://mitchellt.com/wsl-fail"><![CDATA[<p>tldr; Check that the HNS is not disabled, <code class="language-plaintext highlighter-rouge">sc.exe qc hns</code> to check,
<code class="language-plaintext highlighter-rouge">sc.exe config hns start= auto</code> to enable,
<code class="language-plaintext highlighter-rouge">Start-Service hns</code> to start.</p>

<p>I work in a Windows environment by necessity, not by choice.
The Windows Subsystem for Linux is a key part of my ability to work productively.</p>

<p>However, I’ve now come across several instances of this irritating error:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>wsl: Failed to configure network
</code></pre></div></div>

<p>And the culprit twice has been HNS, the <em>Host Network Service</em>.
As a mechanical engineering pleb, I don’t know much networking,
but it’s related to setting up virtual networks and since WSL 2 is running in a VM,
it needs these types of virtual networks.</p>

<p>Essentially fixed by running the following series of commands (PowerShell as admin)</p>

<div class="language-powershell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">wsl</span><span class="w"> </span><span class="nt">--shutdown</span><span class="w">                </span><span class="c"># Shut down any live WSL instances</span><span class="w">
</span><span class="n">sc.exe</span><span class="w"> </span><span class="nx">qc</span><span class="w"> </span><span class="nx">hns</span><span class="w">                 </span><span class="c"># Check if hns is disabled</span><span class="w">
</span><span class="n">sc.exe</span><span class="w"> </span><span class="nx">config</span><span class="w"> </span><span class="nx">hns</span><span class="w"> </span><span class="nx">start</span><span class="o">=</span><span class="w"> </span><span class="n">auto</span><span class="w"> </span><span class="c"># Try to configure so it doesn't happen again</span><span class="w">
</span><span class="n">Start-Service</span><span class="w"> </span><span class="nx">hns</span><span class="w">             </span><span class="c"># Start it back up</span><span class="w">
</span></code></pre></div></div>

<p>I’m thinking our IT management company pushes some policies or updates that periodically break this.
But until then, at least this should bring me back up quickly.</p>

<p>Shout out to Codex 5.2 for the help.</p>]]></content><author><name>Mitchell T. Paulus</name></author><summary type="html"><![CDATA[tldr; Check that the HNS is not disabled, sc.exe qc hns to check, sc.exe config hns start= auto to enable, Start-Service hns to start.]]></summary></entry><entry><title type="html">Word Watermarks</title><link href="https://mitchellt.com/watermark" rel="alternate" type="text/html" title="Word Watermarks" /><published>2025-12-11T00:00:00-06:00</published><updated>2025-12-11T00:00:00-06:00</updated><id>https://mitchellt.com/word-watermarks</id><content type="html" xml:base="https://mitchellt.com/watermark"><![CDATA[<p>When making engineering reports in MS Word, I often need to add a <em>DRAFT</em> watermark.</p>

<p>If I have a document with multiple sections, going to <em>Design</em> -&gt; <em>Watermark</em> -&gt; <em>Draft 1</em> will often not work.
It will add to the current section, but will remove from the others.</p>

<p>What I have found to work is to make sure there are no current watermarks using <em>Design</em> -&gt; <em>Watermark</em> -&gt; <em>Remove Watermark</em>,
then using the <em>Design</em> -&gt; <em>Watermark</em> -&gt; <em>Custom Watermark</em> instead.
You can use a text watermark with “DRAFT” and it will look the same as the default one.</p>]]></content><author><name>Mitchell T. Paulus</name></author><summary type="html"><![CDATA[When making engineering reports in MS Word, I often need to add a DRAFT watermark.]]></summary></entry><entry><title type="html">View Ad-hoc Multi-Trend List in EcoStruxure Building Operation</title><link href="https://mitchellt.com/ebo-multi-trend" rel="alternate" type="text/html" title="View Ad-hoc Multi-Trend List in EcoStruxure Building Operation" /><published>2025-09-19T00:00:00-05:00</published><updated>2025-09-19T00:00:00-05:00</updated><id>https://mitchellt.com/adhoc-multi-trend-list</id><content type="html" xml:base="https://mitchellt.com/ebo-multi-trend"><![CDATA[<p>Click the folder in the navigation pane containing the trend objects, then they show up on right pane.
That allows you then to <kbd>Ctrl</kbd>+<kbd>A</kbd>, or shift select.</p>

<p>Right click, then View, then “In Multi Trend Log List”.</p>

<p>From there, you can change the number of samples, and then export to CSV.</p>]]></content><author><name>Mitchell T. Paulus</name></author><summary type="html"><![CDATA[Click the folder in the navigation pane containing the trend objects, then they show up on right pane. That allows you then to Ctrl+A, or shift select.]]></summary></entry><entry><title type="html">Line endings and encoding in Python `print`</title><link href="https://mitchellt.com/print" rel="alternate" type="text/html" title="Line endings and encoding in Python `print`" /><published>2025-06-30T00:00:00-05:00</published><updated>2025-06-30T00:00:00-05:00</updated><id>https://mitchellt.com/Python-print</id><content type="html" xml:base="https://mitchellt.com/print"><![CDATA[<p>This one is going to be seared into my memory.</p>

<p>I have my own shell (even though the shell here doesn’t matter).
I essentially had Python code that looked like this:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">import</span> <span class="n">requests</span>

<span class="n">response</span> <span class="o">=</span> <span class="n">requests</span><span class="p">.</span><span class="nf">get</span><span class="p">(</span><span class="sh">"</span><span class="s">https://myapi.com</span><span class="sh">"</span><span class="p">)</span>
<span class="nf">print</span><span class="p">(</span><span class="n">response</span><span class="p">.</span><span class="n">text</span><span class="p">)</span>
</code></pre></div></div>

<p>The raw response here was a CSV file with DOS line endings (<code class="language-plaintext highlighter-rouge">\r\n</code>).</p>

<p>However, when I would redirect the output of this code, I got a file that had duplicate carriage returns; the ends of the lines were <code class="language-plaintext highlighter-rouge">\r\r\n</code>.
I didn’t get the same issue when I was on WSL.</p>

<p>I now have been enlightened that by default, the <code class="language-plaintext highlighter-rouge">sys.stdout</code> object in Python that <code class="language-plaintext highlighter-rouge">print</code> uses by default is opened in text mode with the system’s default encoding and line endings.</p>

<p>On Windows, the <code class="language-plaintext highlighter-rouge">newline</code> attribute for the <code class="language-plaintext highlighter-rouge">sys.stdout</code> is None.</p>

<p>From the documentation on <a href="https://docs.python.org/3/library/io.html#io.TextIOWrapper">class io.TextIOWrapper</a>, this means that</p>

<blockquote>
  <p>When writing output to the stream, if newline is None, any ‘\n’ characters written are translated to the system default line separator, <code class="language-plaintext highlighter-rouge">os.linesep</code>.</p>
</blockquote>

<p>Apparently, this is not smart. Like it is straight up find/replace on the ‘\n’ characters.</p>

<p>On more recent <code class="language-plaintext highlighter-rouge">Python3</code>s, you can change the <code class="language-plaintext highlighter-rouge">encoding</code> and <code class="language-plaintext highlighter-rouge">newline</code> parameters using the <a href="https://docs.python.org/3/library/io.html#io.TextIOWrapper.reconfigure"><code class="language-plaintext highlighter-rouge">sys.stdout.reconfigure()</code></a> method.</p>

<p>To avoid all of this and dump out the literal bytes from your response, do</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">response</span> <span class="o">=</span> <span class="n">requests</span><span class="p">.</span><span class="nf">get</span><span class="p">(</span><span class="sh">"</span><span class="s">https://myapi.com</span><span class="sh">"</span><span class="p">)</span>
<span class="n">sys</span><span class="p">.</span><span class="n">stdout</span><span class="p">.</span><span class="nb">buffer</span><span class="p">.</span><span class="nf">write</span><span class="p">(</span><span class="n">response</span><span class="p">.</span><span class="n">content</span><span class="p">)</span>
</code></pre></div></div>

<p>This is almost always what I want.</p>

<p>I was shocked by how little was returned in searches/AI prompts for “Duplicate carriage returns in Python print”.
Hopefully now this gets sucked up into the training data and helps someone else.</p>]]></content><author><name>Mitchell T. Paulus</name></author><summary type="html"><![CDATA[This one is going to be seared into my memory.]]></summary></entry><entry><title type="html">Viewing SharePoint Storage</title><link href="https://mitchellt.com/sp" rel="alternate" type="text/html" title="Viewing SharePoint Storage" /><published>2024-03-13T00:00:00-05:00</published><updated>2024-03-13T00:00:00-05:00</updated><id>https://mitchellt.com/viewing-sharepoint-storage</id><content type="html" xml:base="https://mitchellt.com/sp"><![CDATA[<p>SharePoint storage is relatively expensive. As of 2024-03-05 at our company, it’s on the order of $20/100 Gb/month.
So it pays to keep an eye on the storage.</p>

<p>However, it’s not a guarantee that Microsoft makes investigating what document libraries and files are taking up the most space easy.</p>

<p>If you search for ways to investigate this storage, you’ll find UI screenshots of pages that no longer exist and random PowerShell scripts.</p>

<p>Here’s a trick that should continue to work.
There’s a URL for each SharePoint site that provides UI showing a file and folder size breakdown, including versioning.</p>

<p>Just append <code class="language-plaintext highlighter-rouge">_layouts/15/storman.aspx</code> to the base SharePoint site URL.</p>

<p>For example, if your site home page is,
<code class="language-plaintext highlighter-rouge">https://mybusiness.sharepoint.com/jobs</code>, go to the URL <code class="language-plaintext highlighter-rouge">https://mybusiness.sharepoint.com/jobs/_layouts/15/storman.aspx</code>.</p>

<p>You should see something like:</p>

<p><img src="/assets/img/SharePoint_Storage.png" alt="SharePoint storage breakdown" /></p>

<p>From there, you can drill down deeper into the directory tree.</p>]]></content><author><name>Mitchell T. Paulus</name></author><summary type="html"><![CDATA[SharePoint storage is relatively expensive. As of 2024-03-05 at our company, it’s on the order of $20/100 Gb/month. So it pays to keep an eye on the storage.]]></summary></entry><entry><title type="html">Derivation of the counterflow effectiveness-NTU relation</title><link href="https://mitchellt.com/hx" rel="alternate" type="text/html" title="Derivation of the counterflow effectiveness-NTU relation" /><published>2023-05-19T00:00:00-05:00</published><updated>2023-05-19T00:00:00-05:00</updated><id>https://mitchellt.com/counterflow</id><content type="html" xml:base="https://mitchellt.com/hx"><![CDATA[<p>
<strong>Target Audience:</strong> Engineers or engineering students who've got some understanding of Calculus and Thermo.
</p>

<p>
In order to really grasp some engineering concepts, I need to derive them myself, in a way that makes sense to me.
One of these concepts is the ε-NTU method for counterflow heat exchangers.
</p>
<p>
The final result that relates a counterflow heat exchanger's effectiveness with \(N_{tu}\) (or <em>NTU</em>) for those who haven't seen it before is:
</p>

<p>
\[ \epsilon = \frac{1 - e^{-NTU(1-\frac{C_{min}}{C_{max}})}}{1 -  \frac{C_{min}}{C_{max}}  e^{-NTU(1 - \frac{C_min{}}{C_{max}} )}} \]
</p>

<p>
So here's a diagram of the setup. We've got two fluids, one hot and one cold, flowing in opposite directions.
I've drawn the hot fluid on top going to the right and the cold fluid on the bottom going to the left.
This is one dimensional, and the dimension is \(x\), going to the right.
</p>

<img src="/assets/img/counterflow.png" alt="counterflow heat exchanger" style="width: 100%;"/>

<p>
The basic essence of this derivation is that we have two energy balances (equations that look like \(Q=mcΔT\))
and a form of the heat transfer rate (like \(Q=UAΔT\)).
</p>

<p>
For a simple fluid experiencing only heat transfer, we have:
</p>

<p> \[ \dot{Q} = \dot{m} c_p \left(T_{out} - T_{in} \right) \] </p>

<p>
However, I'm going to write it a little differently, using \(x\) as our variable representing 1-D distance along the heat exchanger.
Important to note here is that \(T\) is a function of \(x\) (I'm going to color this function syntax red like this for clarity: \(T{\color{red}(x)}\)).
</p>

<p>
\[
\dot{Q} = \dot{m} c_p \left(T{\color{red}(x + Δx)} - T{\color{red}(x)}\right)
\]
</p>

<p>
For reasons that will make more sense later, I'm going to divide both sides by that \(Δx\).
</p>

<p>
\[
\frac{\dot{Q}}{Δx} = \dot{m} c_p \left(\frac{T{\color{red} (x + Δx) } - T{\color{red}(x)}}{Δx}\right)
\]
</p>

<p>
Now, If you take the limit as \(Δx\) goes to zero, you get the definition of the derivative of \(T\) with respect to \(x\) in that parenthesis.
</p>

<p>
\[
   \lim_{Δx \to 0} \frac{\dot{Q}}{Δx} = \dot{m} c_p \frac{dT}{dx}
\]
</p>

<p>
That \(\lim_{Δx \to 0} \dot{Q}/Δx\) is a little strange, but in the other derivations I've seen, most just call it the "differential" of \(\dot{Q}\).
But we're going to want to give it a name, so I'm going to call it \(\delta{} \dot{Q}\).
</p>

<p>
\[
   \delta \dot{Q} = \dot{m} c_p \frac{dT}{dx}
\]
</p>

<p>
Let's also replace the \(\dot{m} c_p\) with \(C\), which is the heat capacity rate of the fluid.
We have this formula for both the hot and cold fluids, so we'll subscript them with \(h\) and \(c\).
</p>

<p>
\begin{equation}\label{eq:eb}
\delta \dot{Q} = C_h \frac{dT_h}{dx} = C_c \frac{dT_c}{dx}
\end{equation}
</p>

<p>
At this point, I've not given any focus to the <em>sign</em> of the heat transfer rate.
It may seem strange at first, but I'm going to add a negative to the RHS of each of these.
Once you look at a plot of the temperature profiles, it will make more sense.
</p>

<p>
As you go from left to right (increasing \(x\)) on the plot, <em>both temperatures are decreasing</em>.
This means that the \(dT/dx\) is <em>negative</em> for both fluids.
We'd prefer to deal with a positive heat transfer rate everywhere,
so this means that we need to add a negative sign to both equations.
</p>

<p> \[ \delta \dot{Q} = -C_h \frac{dT_h}{dx} = -C_c \frac{dT_c}{dx} \] </p>

<p>
Now we can look at another way to calculate the heat transfer rate.
This is simply using the definition of the overall heat transfer coefficient \(U\).
I'm using \(W\) to represent some constant "width" of the heat exchanger,
such that the cross-sectional area is \(A = W Δx\).
</p>
<p>
I'm also going to assume some length that this heat transfer is happening over, \(x_{0}\) to \(x_{0} + \Delta x\).
The \(UA\) value is going to be multiplied by the average temperature difference between the two fluids (using the calculus definition of average).
</p>

<p> \[ \dot{Q} = U W Δx \int_{x_{0}}^{x_{0} + \Delta x} \frac{\left(T_{h} {\color{red}(x)}- T_{c}{\color{red}(x)}\right)}{ \Delta x}  \] </p>

<p>
Again, we can divide both sides by \(Δx\).
</p>

<p>
\[
\frac{\dot{Q}}{Δx} = U W \int_{x_{0}}^{x_{0} + \Delta x} \frac{\left(T_{h} {\color{red}(x)}- T_{c}{\color{red}(x)}\right)}{ \Delta x}
\]
</p>

<p>
But before we take the limit as \(Δx\) goes to zero, let's evaluate that integral.
I'm going to use \(T^{*}\) to represent some antiderivative of \(T\).
</p>

<p>
\[
\frac{\dot{Q}}{Δx} = U W \left( \frac{T^{*}_{h} {\color{red}(x_{0} + \Delta x)} - T^{*}_{h} {\color{red}(x_{0})}}{Δx} -  \frac{T^{*}_{c} {\color{red}(x_{0} + \Delta x)} - T^{*}_{c} {\color{red}(x_{0})}}{Δx}\right)
\]
</p>

<p>
Now let's take that limit.
We can use our definition of \(\delta \dot{Q}\) to replace the left side.
The temperature differences are again in the form of the definition of the derivative.
</p>

<p>
\[
\delta \dot{Q} = U W \left( \frac{dT^{*}_{h}}{dx} - \frac{dT^{*}_{c}}{dx} \right)
\]
</p>

<p>
But \(T^{*}\) was assumed to be an antiderivative of \(T\), so we can replace the derivatives with the original functions.
</p>


<p>
\begin{equation}\label{eq:deltaq}
\delta \dot{Q} = U W \left(T_{h}{\color{red}(x)}- T_{c}{\color{red}(x)}\right)
\end{equation}
</p>

<p style="font-size: 0.7em">
<em>(Ok, some of you probably didn't need that level of detail to accept the above equation at face value.
    But I did.)</em>
</p>

<p>
Let's rearrange the energy balance equations, to get a differential of the temperature differences.
\(\def\dq{\delta \dot{Q}}\)
</p>

<p>
\[
    \frac{dT_h}{dx} - \frac{dT_c}{dx} = \left( \frac{1}{-C_h} - \frac{1}{-C_c} \right) \dq
\]
</p>

<p>
Differentiation is a linear operator, this means that the difference of derivatives is equal to the derivative of the difference.
Also moving some things around on the RHS to deal with the double negative.
\(\def\Cdiff{\left( \frac{1}{C_c} - \frac{1}{C_h} \right)}\)
</p>

<p>
\[
    \frac{d}{dx} \left(T_h - T_c \right) = \left( \frac{1}{C_c} - \frac{1}{C_h} \right) \dq
\]
</p>

<p>
We can now substitute \eqref{eq:deltaq} for \(\dq\) (dropping the function syntax).
</p>

<p>\[ \frac{d}{dx} \left(T_h - T_c \right) =  \Cdiff U W \left(T_{h} - T_{c}\right) \] </p>

<p> Let's move all the temperature differences to the LHS. </p>

<p>
\[ \frac{\frac{d}{dx} \left(T_h - T_c \right)}{T_h - T_c} =  \Cdiff  U W \]
</p>

<p>
I'm going to define a new variable for the temperature difference, \(D\) (standing for <em>difference</em>).
</p>

<p>
\[ D = T_h - T_c \]

\[
\frac{1}{D} \frac{dD}{dx}  =  \Cdiff U W
\]
</p>

<p>
Integrating both sides with respect to \(x\), we get:
</p>

<p>
\[
\int_1^2 \frac{1}{D} \frac{dD}{dx} dx = \int_1^2 \Cdiff U W dx
\]
\[
\left.\ln D \right|_1^2 = \Cdiff U W L
\]
\[
\ln D_2 - \ln D_1 = \ln \frac{D_2}{D_1} = \Cdiff U A
\]
</p>

Multiply and divide RHS by \(-C_h\).

<p>
\[
\ln \frac{D_2}{D_1} = \left(1 - \frac{C_h}{C_c} \right) \frac{UA}{-C_h}
\]
\[
\ln \frac{D_2}{D_1} = -N_{tu} \left( 1 - \frac{C_h}{C_c} \right)
\]
</p>

<p>
Let's bring back the temperatures by replacing the definition of \(D\).
</p>
<p>
\begin{equation}\label{eq:ln}
\ln \frac{T_{h2} - T_{c2}}{T_{h1} - T_{c1}} = -N_{tu} \left( 1 - \frac{C_h}{C_c} \right)
\end{equation}
</p>

<p>
Note that we replaced \(\frac{UA}{C_h}\) with \(N_{tu}\).
\(N_{tu}\) is defined as \(UA/C_{min}\), where \(C_{min}\) is the minimum heat capacity rate of the fluids.
</p>

<p>
At this point, the hard part is done.
What remains is algebraic manipulation with the definition of effectiveness.
</p>

<p>
The eventual goal is to get this in terms of effectiveness, ε, removing all the temperatures.
The original Kays and London text with this derivation relies on a geometric interpretation that is really nice.
However, I'm going to show a different line of algebraic thought that also works.
</p>

<p>
First we need to <em>define</em> effectiveness. We have implicitly assumed that \(C_{h} < C_{c}\),
meaning that the hot flow has a lower heat capacity rate.
Whichever fluid has the lower heat capacity rate will have the maximum temperature difference,
with the largest possible difference being the difference between the inlet hot temperature and the inlet cold temperature.
So effectiveness is defined as the ratio of the actual temperature difference to the maximum possible temperature difference.
</p>

<p>
\begin{equation}\label{eq:eff}
ε = \frac{T_{h1} - T_{h2}}{T_{h1} - T_{c2}}
\end{equation}
</p>

<p>
In \eqref{eq:ln}, we have differences in temperatures at the same end, 1's with 1's and 2's with 2's.
Our effectiveness definition has differences in temperatures at <em>opposite</em> ends, 1's with 2's.
The other key insight here is that we know the temperatures differences from end 1 to end 2 are <em>proportional</em>,
based on \eqref{eq:eb}.
Using \eqref{eq:eb}, we can write:
</p>

<p>
\[
\frac{dT_h}{dT_c} = \frac{C_c}{C_h} = \frac{T_{h1} - T_{h2}}{T_{c1} - T_{c2}}
\]
</p>

<p>
Looking at the numerator of \eqref{eq:ln}, we have temperatures at end 2 (\(T_{h2} - T_{c2}\)).
The simplest way to get the temperature differences between ends 1 and 2 is to add and subtract one of the temperatures at end 1,
either \(T_{h1}\) or \(T_{c1}\).
Arbitrarily, let's try adding and subtracting \(T_{h1}\).
</p>

<p>
\[
T_{h2} - T_{c2} = T_{h2} - T_{c2} + T_{h1} - T_{h1} = \left( T_{h1} - T_{c2} \right) -  \left(T_{h1} - T_{h2}\right)
\]
</p>

<p>
This is good because the terms \(\left( T_{h1} - T_{c2} \right)\) and \(\left(T_{h1} - T_{h2}\right)\) are both in the definition of effectiveness \eqref{eq:eff}.
</p>

Doing a similar thing for the bottom, but this time adding and subtracting \(T_{c1}\).

<p>
\[
T_{h1} - T_{c1} = T_{h1} - T_{c1} + T_{c2} - T_{c2} = \left( T_{h1} - T_{c2} \right) -  \left(T_{c1} - T_{c2}\right)
\]
</p>

As a reminder, we are trying to simply the fraction on the LHS of \eqref{eq:ln}.

<p>
\[
\frac{T_{h2} - T_{c2}}{T_{h1} - T_{c1}} = \frac{\left( T_{h1} - T_{c2} \right) -  \left(T_{h1} - T_{h2}\right)}{\left( T_{h1} - T_{c2} \right) -  \left(T_{c1} - T_{c2}\right)}
\]
</p>

Hopefully you can see that by dividing the top and bottom by \(\left( T_{h1} - T_{c2} \right)\),
we are going to cancel the first terms in the numerator and denominator and get 1's, and then we'll get an effectiveness term right away on the top.

<p>
\[
\frac{\left( T_{h1} - T_{c2} \right) -  \left(T_{h1} - T_{h2}\right)}{\left( T_{h1} - T_{c2} \right) -  \left(T_{c1} - T_{c2}\right)} = \frac{ \frac{\left( T_{h1} - T_{c2} \right) -  \left(T_{h1} - T_{h2}\right)}{ \left( T_{h1} - T_{c2} \right)  }   }{ \frac{\left( T_{h1} - T_{c2} \right) -  \left(T_{c1} - T_{c2}\right)}{  \left( T_{h1} - T_{c2} \right)  } } = \frac{1 - ε}{1 - \frac{ T_{c1} - T_{c2}}{ T_{h1} - T_{c2} } }
\]
</p>

<p>
We're close now. If that \(T_{c1} - T_{c2}\) term just had \(h\)'s instead, we'd have another effectiveness term.
Fortunately, we have a conversion factor for that, \(\frac{C_c}{C_h}\).
</p>
<p>
Replace \(T_{c1} - T_{c2}\) with \(\frac{C_h}{C_c} \left( T_{h1} - T_{h2} \right)\), and we now have an expression with no temperatures.
</p>

<p>
\[
\frac{T_{h2} - T_{c2}}{T_{h1} - T_{c1}} = \frac{1 - ε}{1 - \frac{C_h}{C_c} ε}
\]
</p>

<p>
Now it's just algebra time - let's substitute this back into \eqref{eq:ln} and solve for \(ε\).
</p>

<p>

\[
\ln \left(  \frac{1 - ε}{1 - \frac{C_h}{C_c} ε} \right) = -N_{tu} \left( 1 - \frac{C_h}{C_c}  \right)
\]
\[
\left(  \frac{1 - ε}{1 - \frac{C_h}{C_c} ε} \right) = e^{-N_{tu} \left( 1 - \frac{C_h}{C_c}  \right) }
\]
\[
1 - ε = \left( 1 - \frac{C_h}{C_c} ε \right) e^{-N_{tu} \left( 1 - \frac{C_h}{C_c}  \right) }
\]
\[
1 - ε = e^{-N_{tu} \left( 1 - \frac{C_h}{C_c}  \right) } -  \frac{C_h}{C_c} ε  e^{-N_{tu} \left( 1 - \frac{C_h}{C_c}  \right) }
\]
\[
1 - e^{-N_{tu} \left( 1 - \frac{C_h}{C_c}  \right) } = ε \left( 1 -  \frac{C_h}{C_c}  e^{-N_{tu} \left( 1 - \frac{C_h}{C_c}  \right) }   \right)
\]
\[
ε = \frac{1 - e^{-N_{tu} \left( 1 - \frac{C_h}{C_c}  \right) }}{1 -  \frac{C_h}{C_c}  e^{-N_{tu} \left( 1 - \frac{C_h}{C_c}  \right) } }
\]
</p>

<p>
Now, since our assumption throughout was that \(C_h \lt C_c\),
we can account for that here,
and we get the final result that you'll see in your heat transfer textbooks.
</p>

<p>
\[ \epsilon = \frac{1 - e^{-NTU(1-\frac{C_{min}}{C_{max}})}}{1 -  \frac{C_{min}}{C_{max}}  e^{-NTU(1 - \frac{C_min{}}{C_{max}} )}} \]
</p>]]></content><author><name>Mitchell T. Paulus</name></author><summary type="html"><![CDATA[Target Audience: Engineers or engineering students who've got some understanding of Calculus and Thermo.]]></summary></entry><entry><title type="html">What is the value of `-2^2`?</title><link href="https://mitchellt.com/ooo" rel="alternate" type="text/html" title="What is the value of `-2^2`?" /><published>2023-01-28T00:00:00-06:00</published><updated>2023-01-28T00:00:00-06:00</updated><id>https://mitchellt.com/unary_minus_and_exponentiation</id><content type="html" xml:base="https://mitchellt.com/ooo"><![CDATA[<p>tldr: Depends on who you ask. And watch out for Excel – it takes the minority position that this is 4.</p>

<p>This is not meant to be a trick question – it is simply a matter of arbitrary choice in the order of operations.</p>

<p>So while <a href="https://en.wikipedia.org/wiki/Order_of_operations#Mnemonics">PEMDAS</a> is pretty well agreed upon,
the relationship between <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Unary_negation">unary minus</a> and exponentiation is not.
Different programming languages or spreadsheets handle it differently.</p>

<p>Here’s an example of how I ran into this bug.
I was using <a href="https://maxima.sourceforge.io/">Maxima</a>,
a free computer algebra system to solve a very complicated set of simultaneous equations.
I then was copying this symbolic solution to a programming language of my own that I’ve been developing for engineering.
I evaluated the expressions in both, and one of the evaluated expressions was completely different between the two.</p>

<p>I knew that the evaluated Maxima solution was correct based on the value.
I then tried to copy the expression in Excel.</p>

<p>What then shocked me was that Excel matched <em>my</em> solution!</p>

<p>After evaluating what seemed like a thousand sub expressions, I found the culprit: <code class="language-plaintext highlighter-rouge">-a^b</code>.</p>

<p>It turns out I had decided (without any thought) that unary minus should bind more tightly than exponentiation.
Maxima, and from what I can tell, most other languages, has exponentiation at a higher precedence.</p>

<p>I proceeded to check how every language that I use handles this.
The only two that evaluated to 4 were Excel and the <code class="language-plaintext highlighter-rouge">math</code> function in the fish shell.</p>

<p>Programs that evaluate <code class="language-plaintext highlighter-rouge">-2^2</code> to 4:</p>

<ul>
  <li>Excel</li>
  <li><a href="https://fishshell.com/docs/current/cmds/math.html"><code class="language-plaintext highlighter-rouge">math</code></a> <a href="https://fishshell.com/">(fish shell)</a></li>
</ul>

<p>Programs that evaluate <code class="language-plaintext highlighter-rouge">-2^2</code> to -4:</p>

<ul>
  <li><a href="https://maxima.sourceforge.io/">Maxima</a></li>
  <li><a href="https://en.wikipedia.org/wiki/AWK">awk</a></li>
  <li><a href="https://www.python.org/">Python</a></li>
  <li><a href="https://www.lua.org">lua</a></li>
  <li><a href="https://en.wikipedia.org/wiki/Almquist_shell#dash">POSIX shell (dash)</a></li>
  <li><a href="https://www.typescriptlang.org/">JavaScript/TypeScript</a></li>
  <li><a href="https://www.mathworks.com/products/matlab.html">MATLAB</a></li>
  <li><a href="https://www.haskell.org/">Haskell</a></li>
  <li><a href="https://julialang.org/">Julia</a></li>
</ul>

<p>Languages that this doesn’t apply to:</p>

<ul>
  <li><a href="https://dotnet.microsoft.com/en-us/languages/csharphttps://dotnet.microsoft.com/en-us/languages/csharp">C#</a>: Uses <code class="language-plaintext highlighter-rouge">Math.Pow</code> method</li>
</ul>

<p>As it appears <code class="language-plaintext highlighter-rouge">-2^2</code> is generally evaluated to <code class="language-plaintext highlighter-rouge">-4</code>, I updated my programming language grammar to match.
What this does mean though, is that you have to be careful in formula generation or copying and pasting expression like this into Excel.</p>]]></content><author><name>Mitchell T. Paulus</name></author><summary type="html"><![CDATA[tldr: Depends on who you ask. And watch out for Excel – it takes the minority position that this is 4.]]></summary></entry></feed>