tag:blogger.com,1999:blog-23525956419802834632024-03-05T21:57:07.540+11:00Pete's SoapboxWhatever's on Pete's mind today. I suppose we can expect Christianity, IT, programming, math, rights and, well, we'll find out.Peter Ayletthttp://www.blogger.com/profile/02745717570598757619noreply@blogger.comBlogger49125tag:blogger.com,1999:blog-2352595641980283463.post-80556781467926271592021-10-15T23:14:00.000+11:002021-10-15T23:14:37.901+11:00DevExpress XML Serialization Format<p>I've been stuck picking through serialized DevExpress layouts by hand lately. One aspect of it that had me confused for a while was this notation that appears within serialized structs:</p>
<code><property name="XtraSerializerScreenConfiguration" iskey="true" value="1"></code><div><code> <property name="Item1">@1,X=0@1,Y=0@4,Width=1920@4,Height=1080</property></code></div><div><code></property></code>
<p>
What's with the @?</p><p>Similar notation is used for FloatSize, FloatLocation, OriginalSize, XtraBounds.</p><p>It turns out the format is simply this:</p><p></p><ul style="text-align: left;"><li>each @ starts a new field in the struct</li><li>the per-field format is: @{0},{1}={2}</li><li>where {1} and {2} are naturally the field name and value respectively.</li><li>and the cryptic {0} is the number of characters required for the value {2}.</li></ul><div>There you go.</div><div><br /></div><p></p></div>Peter Ayletthttp://www.blogger.com/profile/02745717570598757619noreply@blogger.com0tag:blogger.com,1999:blog-2352595641980283463.post-689671832053602892020-12-15T23:53:00.005+11:002020-12-15T23:58:20.755+11:00How to define a variable within a Microsoft SQL query<p>Sometimes a SQL query ends up needing an expression to be represented more than once. For example, some queries I've worked on have required a complex-to-calculate denominator that needs to be reused in multiple division calculations.<br /><br />Usually one just duplicates the expression, but this is undesirable when:</p><p></p><ul style="text-align: left;"><li>the SQL for the expression is particularly long</li><li>or, particularly computationally expensive to calculate</li></ul><div>I had long wished there was a way to embed a variable in the body of a select statement. Something like:</div><div><br /></div>
<code>
<div>select</div><div> t.numerator1 / denominator,</div><div> t.numerator2 / denominator,</div><div>from</div><div> mytable t</div><div>let</div><div> demoninator = ....some complex calculation ... -- 'let' is NOT valid SQL</div>
</code>
<div><br /></div><div>Sadly the above is not valid SQL. However, it can be achieved as follows:</div><p></p>
<code><div>select</div><div><div> t.numerator1 / v.denominator,</div><div> t.numerator2 / v.denominator,</div><div>from</div><div> mytable t</div><div>outer apply (</div><div> select</div><div> demoninator = ....some complex calculation ...</div></div><div>) v</div><div><br /></div></code>
<div>Or more generally, this can be used with multiple variables, and the variables can be used in subsequent joins, and other query clauses.</div><div><br /></div><div>
<code>
<div>select</div><div><div> v.variable1,</div><div> v.variable2,</div><div> v.variable3</div><div>from</div><div> mytable t</div><div>outer apply (</div><div> select</div><div> variable1 = ...,</div><div> variable2 = ...,</div><div> variable3 = ...</div></div><div>) v</div></div><div>join</div><div> mytable2 t2 on t2.id = v.variable1</div><div>where</div><div> v.variable2 = ...</div><div>order by</div><div> v.variable3</div></code>
<div><br /></div><div>There is an important caveat with this: the outer-apply manifests in the query execution plan as a nested loop join. However, this isn't necessarily a bad thing - rather it's representing the fact that the variables will always be calculated prior to other elements of the query being processed.</div><div><br /></div><div>Note: don't go overboard with this method. But it can be a useful solution when duplication of expressions becomes problematic.</div><div><br /></div><div>Try <a href="http://sqlfiddle.com/#!18/52632/1">this technique on SQL Fiddle</a></div><div><br /></div>Peter Ayletthttp://www.blogger.com/profile/02745717570598757619noreply@blogger.com0tag:blogger.com,1999:blog-2352595641980283463.post-11419682790623363332020-06-27T23:22:00.001+10:002020-06-27T23:26:22.636+10:00Moving Average in Excel Power Query<p>Here's a general-purpose Power Query 'rolling' function that can be used to make a rolling averages / moving average, or any other aggregate function such as a rolling standard deviation, etc.</p>
<p>A self-contained example of a four-item moving average over a list of the numbers 1 to 10:</p>
<pre><code>let Rolling = (list, n, fn) =>
let
buffered = List.Buffer(list)
in
List.Transform(
List.Positions(buffered),
each
if _<n-1
then null
else fn(List.Range(buffered, _-n+1, n))
)
let
result = Rolling({1..10}, 3, List.Sum)
in
result</code></pre>
<p>Alternatively, to make as a reusable function:</p>
<ol>
<li>Select the <b>Data </b>tab</li>
<li>Click <b>Get Data </b>><b> From Other Sources </b>> <b>Blank Query</b></li>
<li>In the Power Query Editor window, type the name <b>Rolling</b> into the top-right <b>Name</b> box</li>
<li>Open <b>Advanced Editor</b> (on the <b>Home </b>tab)</li>
<li>Enter the following query:</li>
</ol>
<div>
<pre><code>(list, n, fn) =>
let
buffered = List.Buffer(list)
in
List.Transform(
List.Positions(buffered),
each
if _ < n-1
then null
else fn(List.Range(buffered, _-n+1, n))
)</code></pre>
<div>
<br /></div>
<div>
The <b>Rolling</b> function should now be defined, and usable in other queries, such as:</div>
<div>
=Rolling( {1..10}, 5, List.StandardDeviation )</div>
<div>
<br /></div>
<div>
for a 5 day rolling standard deviation over the numbers 1 to 10.</div>
<br />
<br />
<br />
<br /></div>
Peter Ayletthttp://www.blogger.com/profile/02745717570598757619noreply@blogger.com0tag:blogger.com,1999:blog-2352595641980283463.post-19605961060946109352020-03-26T21:59:00.000+11:002020-03-26T22:00:21.720+11:00Determining the growth rate of a published chartA friend drew my attention to <a href="https://swell.life/article/rMYhMFSSqDXi/bayarea-is-flattening-the-curve?fbclid=IwAR25WMiIDjGbaG3bkVE2izP_Q42UKWUgYQoH69Fapi-X4VCRBLkOgYc1lsc">this page comparing the Bay Area COVID-19 cases to New York</a>. But it can be hard to judge visually how steep a log chart is.<br />
<br />
To calculate the growth rates, for example of New York on the following chart:<br />
<br />
<ol>
<li>Take a screen capture</li>
<li>Paste it into MSPaint, or similar</li>
<li>Drag the selection box from one log-axis marker to the next.</li>
<li>Use MSPaint's ruler indicator (bottom left corner) to see how high the selction is.</li>
<ol>
<li>E.g. in the following example, measure from the 1,000 grid line to the 10,000 grid line.</li>
<li>The distance is <b>198 pixels for a 10x multiplication</b> </li>
<li>Let's call this PixelsPerTenfold</li>
</ol>
<li>Pick two date lines around the slope being measured</li>
<ol>
<li>Start dragging the selection box from the point where the data line intersects the first date line.</li>
<li>Drag to a point where the data line intersections the last date line.</li>
<li>Use the ruler in the corner to measure the vertical distance.</li>
<li>Call this PixelsIncreased</li>
<li>In the example below it is <b>240 pixels</b>.</li>
</ol>
<li>Apply calculations as follows:</li>
</ol>
<div>
<table border="0" cellpadding="0" cellspacing="0" style="border-collapse: collapse; width: 573px;">
<colgroup><col style="width: 48pt;" width="64"></col>
<col style="mso-width-alt: 4278; mso-width-source: userset; width: 88pt;" width="117"></col>
<col style="mso-width-alt: 11227; mso-width-source: userset; width: 230pt;" width="307"></col>
<col style="mso-width-alt: 3108; mso-width-source: userset; width: 64pt;" width="85"></col>
</colgroup><tbody>
<tr height="20" style="height: 15.0pt;">
<td height="20" style="height: 15.0pt; width: 48pt;" width="64"></td>
<td class="xl65" style="width: 88pt;" width="117">PixelsIncreased </td>
<td style="width: 230pt;" width="307"></td>
<td style="width: 64pt;" width="85">= 240</td>
</tr>
<tr height="20" style="height: 15.0pt;">
<td height="20" style="height: 15.0pt;"></td>
<td class="xl65">PixelsPerTenfold </td>
<td></td>
<td>= 198</td>
</tr>
<tr height="20" style="height: 15.0pt;">
<td height="20" style="height: 15.0pt;"></td>
<td class="xl65">Days</td>
<td></td>
<td>= 3</td>
</tr>
<tr height="20" style="height: 15.0pt;">
<td height="20" style="height: 15.0pt;"></td>
<td class="xl65"></td>
<td></td>
<td></td>
</tr>
<tr height="23" style="height: 17.25pt;">
<td height="23" style="height: 17.25pt;"></td>
<td class="xl65">Daily Multiplier</td>
<td>= 10<span class="font5"><sup>(PixelsIncreased / PixelsPerTenfold / Days)</sup></span></td>
<td>= 2.54</td>
</tr>
<tr height="20" style="height: 15.0pt;">
<td height="20" style="height: 15.0pt;"></td>
<td class="xl65">Daily % Increase</td>
<td>= 100 * (DailyMultiplier-1)</td>
<td>= 154%</td>
</tr>
<tr height="24" style="height: 18.0pt;">
<td height="24" style="height: 18.0pt;"></td>
<td class="xl65">Days to Double</td>
<td>= log<span class="font6"><sub>e</sub></span><span class="font0">2 / log</span><span class="font6"><sub>e</sub></span><span class="font0">DailyMultiplier</span></td>
<td>= 0.75 days</td>
</tr>
<tr height="24" style="height: 18.0pt;">
<td height="24" style="height: 18.0pt;"></td>
<td class="xl65">Days to 10x</td>
<td>= log<span class="font6"><sub>e</sub></span><span class="font0">10 / log</span><span class="font6"><sub>e</sub></span><span class="font0">DailyMultiplier</span></td>
<td>= 2.47 days</td>
</tr>
</tbody></table>
</div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhOY0-E2d4GhMYHVpc429qtlOO7bbljlogP0FQGh14d7WCNzU7jd6A4qhSF4ZCpwtkZMFVkUjWAZHnVF2nyz4w-krhAbZILQOsH8vNM4uH3HgzazK5Fp-QaAvzduGLPx_aOS7xmnS6iPSH1/s1600/bay1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="535" data-original-width="900" height="379" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhOY0-E2d4GhMYHVpc429qtlOO7bbljlogP0FQGh14d7WCNzU7jd6A4qhSF4ZCpwtkZMFVkUjWAZHnVF2nyz4w-krhAbZILQOsH8vNM4uH3HgzazK5Fp-QaAvzduGLPx_aOS7xmnS6iPSH1/s640/bay1.png" width="640" /></a></div>
<br />
<br />Peter Ayletthttp://www.blogger.com/profile/02745717570598757619noreply@blogger.com0tag:blogger.com,1999:blog-2352595641980283463.post-64017777338852250012020-03-26T09:23:00.000+11:002020-03-26T09:28:19.240+11:00Exponential growth - Year 10 maths revision"When will I ever need to use logarithms, or raising something to the the power of 1/n in real life". During Covid-19, it turns out. Since no one likes logarithms, I thought I'd just post a few formulas. The following should work on any system of exponential growth.<br />
<br />
(Naturally, for Excel formulas, substitute in the value or cell reference for X, Y, T, etc)<br />
<br />
<table border="0" cellpadding="0" cellspacing="0" style="border-collapse: collapse; table-layout: fixed; width: 743px;"><colgroup><col style="width: 155pt;" width="206"></col><col style="width: 104pt;" width="139"></col><col style="width: 124pt;" width="165"></col><col style="width: 48pt;" width="64"></col><col style="width: 127pt;" width="169"></col></colgroup><tbody>
<tr height="20" style="height: 15pt;"><td class="xl104" height="20" style="border: 0.5pt solid white; font-family: Calibri, sans-serif; font-size: 11pt; height: 15pt; padding: 0px; vertical-align: bottom; white-space: nowrap; width: 155pt;" width="206"></td><td class="xl105" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: 0.5pt solid white; font-family: Calibri, sans-serif; font-size: 11pt; font-weight: 700; padding: 0px; vertical-align: bottom; white-space: nowrap; width: 104pt;" width="139">Formula</td><td class="xl105" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: 0.5pt solid white; font-family: Calibri, sans-serif; font-size: 11pt; font-weight: 700; padding: 0px; vertical-align: bottom; white-space: nowrap; width: 124pt;" width="165">Excel Formula</td><td class="xl105" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: 0.5pt solid white; font-family: Calibri, sans-serif; font-size: 11pt; font-weight: 700; padding: 0px; vertical-align: bottom; white-space: nowrap; width: 48pt;" width="64">Example</td><td class="xl104" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: 0.5pt solid white; font-family: Calibri, sans-serif; font-size: 11pt; padding: 0px; vertical-align: bottom; white-space: nowrap; width: 127pt;" width="169"></td></tr>
<tr height="20" style="height: 15pt;"><td class="xl106" height="20" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: 0.5pt solid white; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; height: 15pt; padding: 0px; vertical-align: bottom; white-space: nowrap;"></td><td class="xl106" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; padding: 0px; vertical-align: bottom; white-space: nowrap;"></td><td class="xl106" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; padding: 0px; vertical-align: bottom; white-space: nowrap;"></td><td class="xl104" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; padding: 0px; vertical-align: bottom; white-space: nowrap;"></td><td class="xl104" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; padding: 0px; vertical-align: bottom; white-space: nowrap;"></td></tr>
<tr height="20" style="height: 15pt;"><td class="xl124" height="20" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: 0.5pt solid white; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; font-weight: 700; height: 15pt; padding: 0px; vertical-align: bottom; white-space: nowrap;">Initial Cases</td><td class="xl106" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; padding: 0px; vertical-align: bottom; white-space: nowrap;">X</td><td class="xl106" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; padding: 0px; vertical-align: bottom; white-space: nowrap;"></td><td align="right" class="xl104" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; padding: 0px; vertical-align: bottom; white-space: nowrap;">112</td><td class="xl104" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; padding: 0px; vertical-align: bottom; white-space: nowrap;"> Aus # Mar10</td></tr>
<tr height="20" style="height: 15pt;"><td class="xl124" height="20" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: 0.5pt solid white; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; font-weight: 700; height: 15pt; padding: 0px; vertical-align: bottom; white-space: nowrap;">Final Cases</td><td class="xl106" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; padding: 0px; vertical-align: bottom; white-space: nowrap;">Y</td><td class="xl106" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; padding: 0px; vertical-align: bottom; white-space: nowrap;"></td><td align="right" class="xl129" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; padding: 0px; vertical-align: bottom; white-space: nowrap;">2,431</td><td class="xl104" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; padding: 0px; vertical-align: bottom; white-space: nowrap;"> Aus # Mar25</td></tr>
<tr height="20" style="height: 15pt;"><td class="xl124" height="20" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: 0.5pt solid white; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; font-weight: 700; height: 15pt; padding: 0px; vertical-align: bottom; white-space: nowrap;">Time</td><td class="xl106" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; padding: 0px; vertical-align: bottom; white-space: nowrap;">T</td><td class="xl106" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; padding: 0px; vertical-align: bottom; white-space: nowrap;"></td><td align="right" class="xl104" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; padding: 0px; vertical-align: bottom; white-space: nowrap;">15</td><td class="xl104" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; padding: 0px; vertical-align: bottom; white-space: nowrap;"> days</td></tr>
<tr height="20" style="height: 15pt;"><td class="xl124" height="20" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: 0.5pt solid white; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; font-weight: 700; height: 15pt; padding: 0px; vertical-align: bottom; white-space: nowrap;"></td><td class="xl106" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; padding: 0px; vertical-align: bottom; white-space: nowrap;"></td><td class="xl106" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; padding: 0px; vertical-align: bottom; white-space: nowrap;"></td><td class="xl104" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; padding: 0px; vertical-align: bottom; white-space: nowrap;"></td><td class="xl104" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; padding: 0px; vertical-align: bottom; white-space: nowrap;"></td></tr>
<tr height="20" style="height: 15pt;"><td class="xl124" height="20" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: 0.5pt solid white; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; font-weight: 700; height: 15pt; padding: 0px; vertical-align: bottom; white-space: nowrap;">Multiplier over duration</td><td class="xl106" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; padding: 0px; vertical-align: bottom; white-space: nowrap;">M = Y/X</td><td class="xl106" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; padding: 0px; vertical-align: bottom; white-space: nowrap;">=Y/X</td><td align="right" class="xl106" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; padding: 0px; vertical-align: bottom; white-space: nowrap;">21.71</td><td class="xl104" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; padding: 0px; vertical-align: bottom; white-space: nowrap;"></td></tr>
<tr height="25" style="height: 18.75pt;"><td class="xl124" height="25" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: 0.5pt solid white; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; font-weight: 700; height: 18.75pt; padding: 0px; vertical-align: bottom; white-space: nowrap;">Daily Multiplier</td><td class="xl106" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; padding: 0px; vertical-align: bottom; white-space: nowrap;">M<span class="font17" style="font-size: 11pt;"><sub>D</sub></span><span class="font0" style="font-size: 11pt;"> = M</span><span class="font18" style="font-size: 11pt;"><sup>1/T</sup></span></td><td class="xl106" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; padding: 0px; vertical-align: bottom; white-space: nowrap;">=(Y/X)^(1/T)</td><td align="right" class="xl106" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; padding: 0px; vertical-align: bottom; white-space: nowrap;">1.23</td><td class="xl104" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; padding: 0px; vertical-align: bottom; white-space: nowrap;"></td></tr>
<tr height="24" style="height: 18pt;"><td class="xl124" height="24" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: 0.5pt solid white; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; font-weight: 700; height: 18pt; padding: 0px; vertical-align: bottom; white-space: nowrap;">Daily % Increase</td><td class="xl106" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; padding: 0px; vertical-align: bottom; white-space: nowrap;"> =(M<span class="font17" style="font-size: 11pt;"><sub>D</sub></span><span class="font0" style="font-size: 11pt;"> -1) * 100</span></td><td class="xl106" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; padding: 0px; vertical-align: bottom; white-space: nowrap;">=((Y/X)^(1/T)-1)</td><td align="right" class="xl107" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; padding: 0px; vertical-align: bottom; white-space: nowrap;">22.8%</td><td class="xl104" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; padding: 0px; vertical-align: bottom; white-space: nowrap;"> Format as %</td></tr>
<tr height="20" style="height: 15pt;"><td class="xl124" height="20" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: 0.5pt solid white; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; font-weight: 700; height: 15pt; padding: 0px; vertical-align: bottom; white-space: nowrap;"></td><td class="xl106" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; padding: 0px; vertical-align: bottom; white-space: nowrap;"></td><td class="xl106" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; padding: 0px; vertical-align: bottom; white-space: nowrap;"></td><td class="xl104" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; padding: 0px; vertical-align: bottom; white-space: nowrap;"></td><td class="xl104" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; padding: 0px; vertical-align: bottom; white-space: nowrap;"></td></tr>
<tr height="24" style="height: 18pt;"><td class="xl124" height="24" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: 0.5pt solid white; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; font-weight: 700; height: 18pt; padding: 0px; vertical-align: bottom; white-space: nowrap;">Time to double</td><td class="xl106" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; padding: 0px; vertical-align: bottom; white-space: nowrap;">T<span class="font17" style="font-size: 11pt;"><sub>2X</sub></span><span class="font0" style="font-size: 11pt;"> = log</span><span class="font17" style="font-size: 11pt;"><sub>e</sub></span><span class="font0" style="font-size: 11pt;">2 / log</span><span class="font17" style="font-size: 11pt;"><sub>e</sub></span><span class="font0" style="font-size: 11pt;">M</span><span class="font17" style="font-size: 11pt;"><sub>D</sub></span></td><td class="xl106" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; padding: 0px; vertical-align: bottom; white-space: nowrap;">=LN(2)/LN((Y/X)^(1/T))</td><td align="right" class="xl106" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; padding: 0px; vertical-align: bottom; white-space: nowrap;">3.38</td><td class="xl104" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; padding: 0px; vertical-align: bottom; white-space: nowrap;"> days</td></tr>
<tr height="24" style="height: 18pt;"><td class="xl124" height="24" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: 0.5pt solid white; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; font-weight: 700; height: 18pt; padding: 0px; vertical-align: bottom; white-space: nowrap;">Time to 10x</td><td class="xl106" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; padding: 0px; vertical-align: bottom; white-space: nowrap;">T<span class="font17" style="font-size: 11pt;"><sub>10X</sub></span><span class="font0" style="font-size: 11pt;"> = log</span><span class="font17" style="font-size: 11pt;"><sub>e</sub></span><span class="font0" style="font-size: 11pt;">10 / log</span><span class="font17" style="font-size: 11pt;"><sub>e</sub></span><span class="font0" style="font-size: 11pt;">M</span><span class="font17" style="font-size: 11pt;"><sub>D</sub></span></td><td class="xl106" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; padding: 0px; vertical-align: bottom; white-space: nowrap;">=(Y/X)^(1/T)/LN(10)</td><td align="right" class="xl106" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; padding: 0px; vertical-align: bottom; white-space: nowrap;">11.22</td><td class="xl104" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; padding: 0px; vertical-align: bottom; white-space: nowrap;"> days</td></tr>
<tr height="20" style="height: 15pt;"><td class="xl104" height="20" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: 0.5pt solid white; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; height: 15pt; padding: 0px; vertical-align: bottom; white-space: nowrap;"></td><td class="xl104" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; padding: 0px; vertical-align: bottom; white-space: nowrap;"></td><td class="xl104" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; padding: 0px; vertical-align: bottom; white-space: nowrap;"></td><td class="xl106" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; padding: 0px; vertical-align: bottom; white-space: nowrap;"></td><td class="xl104" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; padding: 0px; vertical-align: bottom; white-space: nowrap;"></td></tr>
<tr height="20" style="height: 15pt;"><td class="xl104" height="20" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: 0.5pt solid white; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; height: 15pt; padding: 0px; vertical-align: bottom; white-space: nowrap;"></td><td class="xl104" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; padding: 0px; vertical-align: bottom; white-space: nowrap;"></td><td class="xl104" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; padding: 0px; vertical-align: bottom; white-space: nowrap;"></td><td class="xl106" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; padding: 0px; vertical-align: bottom; white-space: nowrap;"></td><td class="xl104" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; padding: 0px; vertical-align: bottom; white-space: nowrap;"></td></tr>
<tr height="20" style="height: 15pt;"><td class="xl104" height="20" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: 0.5pt solid white; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; height: 15pt; padding: 0px; vertical-align: bottom; white-space: nowrap;"></td><td class="xl104" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; padding: 0px; vertical-align: bottom; white-space: nowrap;"></td><td class="xl104" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; padding: 0px; vertical-align: bottom; white-space: nowrap;"></td><td class="xl106" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; padding: 0px; vertical-align: bottom; white-space: nowrap;"></td><td class="xl104" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; padding: 0px; vertical-align: bottom; white-space: nowrap;"></td></tr>
<tr height="20" style="height: 15pt;"><td class="xl125" colspan="2" height="20" style="border: 0.5pt solid white; font-family: Calibri, sans-serif; font-size: 11pt; font-weight: 700; height: 15pt; padding: 0px; vertical-align: bottom; white-space: nowrap;">Convert from 'time to double' to 'time to 10x'</td><td class="xl104" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; padding: 0px; vertical-align: bottom; white-space: nowrap;"></td><td class="xl106" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; padding: 0px; vertical-align: bottom; white-space: nowrap;"></td><td class="xl104" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; padding: 0px; vertical-align: bottom; white-space: nowrap;"></td></tr>
<tr height="24" style="height: 18pt;"><td class="xl127" colspan="2" height="24" style="border: 0.5pt solid white; font-family: Calibri, sans-serif; font-size: 11pt; height: 18pt; padding: 0px; vertical-align: bottom; white-space: nowrap;">T<span class="font17" style="font-size: 11pt;"><sub>10X </sub></span><span class="font0" style="font-size: 11pt;">= T</span><span class="font17" style="font-size: 11pt;"><sub>2X</sub></span><span class="font0" style="font-size: 11pt;"> * log</span><span class="font17" style="font-size: 11pt;"><sub>e</sub></span><span class="font0" style="font-size: 11pt;">10 / log</span><span class="font17" style="font-size: 11pt;"><sub>e</sub></span><span class="font0" style="font-size: 11pt;">2</span></td><td class="xl104" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; padding: 0px; vertical-align: bottom; white-space: nowrap;">=<span class="font19" style="font-size: 11pt; font-style: italic;">TDOUBLE</span><span class="font0" style="font-size: 11pt;"> * LN(10)/LN(2)</span></td><td class="xl104" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; padding: 0px; vertical-align: bottom; white-space: nowrap;"></td><td class="xl104" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; padding: 0px; vertical-align: bottom; white-space: nowrap;"></td></tr>
<tr height="20" style="height: 15pt;"><td class="xl104" height="20" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: 0.5pt solid white; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; height: 15pt; padding: 0px; vertical-align: bottom; white-space: nowrap;"></td><td class="xl104" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; padding: 0px; vertical-align: bottom; white-space: nowrap;"></td><td class="xl104" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; padding: 0px; vertical-align: bottom; white-space: nowrap;"></td><td class="xl104" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; padding: 0px; vertical-align: bottom; white-space: nowrap;"></td><td class="xl104" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; padding: 0px; vertical-align: bottom; white-space: nowrap;"></td></tr>
<tr height="20" style="height: 15pt;"><td class="xl125" colspan="2" height="20" style="border: 0.5pt solid white; font-family: Calibri, sans-serif; font-size: 11pt; font-weight: 700; height: 15pt; padding: 0px; vertical-align: bottom; white-space: nowrap;">Convert from 'time to 10x' to 'time to double'</td><td class="xl104" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; padding: 0px; vertical-align: bottom; white-space: nowrap;"></td><td class="xl104" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; padding: 0px; vertical-align: bottom; white-space: nowrap;"></td><td class="xl104" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; padding: 0px; vertical-align: bottom; white-space: nowrap;"></td></tr>
<tr height="24" style="height: 18pt;"><td class="xl127" colspan="2" height="24" style="border: 0.5pt solid white; font-family: Calibri, sans-serif; font-size: 11pt; height: 18pt; padding: 0px; vertical-align: bottom; white-space: nowrap;">T<span class="font17" style="font-size: 11pt;"><sub>2X</sub></span><span class="font0" style="font-size: 11pt;"> =T</span><span class="font17" style="font-size: 11pt;"><sub>10X</sub></span><span class="font0" style="font-size: 11pt;"> * log</span><span class="font17" style="font-size: 11pt;"><sub>e</sub></span><span class="font0" style="font-size: 11pt;">2 / log</span><span class="font17" style="font-size: 11pt;"><sub>e</sub></span><span class="font0" style="font-size: 11pt;">10</span></td><td class="xl104" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; padding: 0px; vertical-align: bottom; white-space: nowrap;">=<span class="font19" style="font-size: 11pt; font-style: italic;">TTEN</span><span class="font0" style="font-size: 11pt;"> * LN(2)/LN(10)</span></td><td class="xl104" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; padding: 0px; vertical-align: bottom; white-space: nowrap;"></td><td class="xl104" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; padding: 0px; vertical-align: bottom; white-space: nowrap;"></td></tr>
<tr height="20" style="height: 15pt;"><td class="xl104" height="20" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: 0.5pt solid white; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; height: 15pt; padding: 0px; vertical-align: bottom; white-space: nowrap;"></td><td class="xl104" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; padding: 0px; vertical-align: bottom; white-space: nowrap;"></td><td class="xl104" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; padding: 0px; vertical-align: bottom; white-space: nowrap;"></td><td class="xl104" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; padding: 0px; vertical-align: bottom; white-space: nowrap;"></td><td class="xl104" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; padding: 0px; vertical-align: bottom; white-space: nowrap;"></td></tr>
<tr height="20" style="height: 15pt;"><td class="xl125" colspan="2" height="20" style="border: 0.5pt solid white; font-family: Calibri, sans-serif; font-size: 11pt; font-weight: 700; height: 15pt; padding: 0px; vertical-align: bottom; white-space: nowrap;">Convert from 'time to double' to 'daily multiplier'</td><td class="xl104" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; padding: 0px; vertical-align: bottom; white-space: nowrap;"></td><td class="xl104" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; padding: 0px; vertical-align: bottom; white-space: nowrap;"></td><td class="xl104" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; padding: 0px; vertical-align: bottom; white-space: nowrap;"></td></tr>
<tr height="25" style="height: 18.75pt;"><td class="xl127" colspan="2" height="25" style="border: 0.5pt solid white; font-family: Calibri, sans-serif; font-size: 11pt; height: 18.75pt; padding: 0px; vertical-align: bottom; white-space: nowrap;">M<span class="font17" style="font-size: 11pt;"><sub>D</sub></span><span class="font0" style="font-size: 11pt;"> = e</span><span class="font18" style="font-size: 11pt;"><sup>log2 / T2X</sup></span></td><td class="xl104" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; padding: 0px; vertical-align: bottom; white-space: nowrap;">=EXP( LN(2) / <span class="font19" style="font-size: 11pt; font-style: italic;">TDOUBLE</span><span class="font0" style="font-size: 11pt;">)</span></td><td class="xl104" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; padding: 0px; vertical-align: bottom; white-space: nowrap;"></td><td class="xl104" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; padding: 0px; vertical-align: bottom; white-space: nowrap;"></td></tr>
<tr height="20" style="height: 15pt;"><td class="xl104" height="20" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: 0.5pt solid white; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; height: 15pt; padding: 0px; vertical-align: bottom; white-space: nowrap;"></td><td class="xl104" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; padding: 0px; vertical-align: bottom; white-space: nowrap;"></td><td class="xl104" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; padding: 0px; vertical-align: bottom; white-space: nowrap;"></td><td class="xl104" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; padding: 0px; vertical-align: bottom; white-space: nowrap;"></td><td class="xl104" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; padding: 0px; vertical-align: bottom; white-space: nowrap;"></td></tr>
<tr height="20" style="height: 15pt;"><td class="xl128" colspan="2" height="20" style="border: 0.5pt solid white; font-family: Calibri, sans-serif; font-size: 11pt; font-weight: 700; height: 15pt; padding: 0px; vertical-align: bottom; white-space: nowrap;">Apply a daily multiplier for N days</td><td class="xl104" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; padding: 0px; vertical-align: bottom; white-space: nowrap;"></td><td class="xl104" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; padding: 0px; vertical-align: bottom; white-space: nowrap;"></td><td class="xl104" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; padding: 0px; vertical-align: bottom; white-space: nowrap;"></td></tr>
<tr height="25" style="height: 18.75pt;"><td class="xl127" colspan="2" height="25" style="border: 0.5pt solid white; font-family: Calibri, sans-serif; font-size: 11pt; height: 18.75pt; padding: 0px; vertical-align: bottom; white-space: nowrap;">M = M<span class="font17" style="font-size: 11pt;"><sub>D</sub></span><span class="font18" style="font-size: 11pt;"><sup>N</sup></span></td><td class="xl104" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; padding: 0px; vertical-align: bottom; white-space: nowrap;">=POWER(<span class="font19" style="font-size: 11pt; font-style: italic;">MD</span><span class="font0" style="font-size: 11pt;">, </span><span class="font19" style="font-size: 11pt; font-style: italic;">NUMDAYS</span><span class="font0" style="font-size: 11pt;">)</span></td><td class="xl104" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; padding: 0px; vertical-align: bottom; white-space: nowrap;"></td><td class="xl104" style="border-bottom: 0.5pt solid white; border-image: initial; border-left: none; border-right: 0.5pt solid white; border-top: none; font-family: Calibri, sans-serif; font-size: 11pt; padding: 0px; vertical-align: bottom; white-space: nowrap;"></td></tr>
</tbody></table>
<br />
<br />
<br />
<br />
<br />Peter Ayletthttp://www.blogger.com/profile/02745717570598757619noreply@blogger.com0tag:blogger.com,1999:blog-2352595641980283463.post-9880143715254210972018-04-06T23:41:00.003+10:002018-04-06T23:41:28.331+10:00Using NULLIF to avoiding duplicating long T-SQL sub expressions for safe division, exclusive betweenI seem to find myself generating a lot of SQL from other higher-level query structures. And it's bugged me for a while that if I have some long SQL expression, and then need to perform certain operations such as division, or exclusive BETWEEN, then it gets repeated.<br />
<br />
So it seems like the ISNULL and NULLIF functions are awesome for solving this kind of problem.<br />
<br />
<h3>
The safe null-if-zero division problem</h3>
If we want to divide by <i>some-long-expression</i> and want to return NULL if it is zero, then we might find ourselves writing:<br />
<br />
<pre>CASE WHEN <i>some-long-expression </i>= 0 THEN NULL ELSE <i>numerator</i> / <i>some-long-expression </i>END</pre>
<br />
But we can avoid including some-long-expression twice by using:<br />
<br />
<pre><i>numerator</i> / NULLIF(<i>some-long-expression</i>, 0)</pre>
<br />
<h3>
The inclusive/exclusive BETWEEN problem</h3>
The BETWEEN clause gives us <i>lower</i> <= <i>test-value</i> <= <i>upper, </i>including both lower and upper in the test range. But sometimes we might need lower only, or upper only, or both, to be exclusive tests.<br />
<br />
This can lead to duplicating long expressions by having to write:<br />
<br />
<pre><i>lower</i> < (<i>some-long-expression)</i> AND (<i>some-long-expression</i>) < upper</pre>
<br />
But we can use NULLIF to similarly avoid repeating the long expression being tested:<br />
<br />
<pre>NULLIF( NULLIF( <i>some-long-expression, lower</i>)<i>, upper</i>) BETWEEN <i>lower </i>AND <i>upper</i></pre>
<i><br /></i>There's a few different combinations of scenarios we might need, as follows:<br />
<br />
<table>
<tbody>
<tr><th>Include<br>Lower</th><th>Include<br>Upper</th><th>Include<br>Null</th><th>SQL</th></tr>
<tr><td>Yes</td><td>Yes</td><td>Yes</td><td><pre>ISNULL(expr, lower) BETWEEN lower AND upper</pre></td></tr>
<tr><td>Yes</td><td>Yes</td><td>No</td><td><pre>expr BETWEEN lower AND upper</pre></td></tr>
<tr><td>Yes</td><td>No</td><td>Yes</td><td><pre>NULLIF(ISNULL(expr, lower), upper) BETWEEN lower AND upper</pre></td></tr>
<tr><td>Yes</td><td>No</td><td>No</td><td><pre>NULLIF(expr, upper) BETWEEN lower AND upper</pre></td></tr>
<tr><td>No</td><td>Yes</td><td>Yes</td><td><pre>NULLIF(ISNULL(expr, upper), lower) BETWEEN lower AND upper</pre></td></tr>
<tr><td>No</td><td>Yes</td><td>No</td><td><pre>NULLIF(expr, lower) BETWEEN lower AND upper</pre></td></tr>
<tr><td>No</td><td>No</td><td>Yes</td><td><pre>NULLIF(NULLIF(ISNULL(expr, some-midpoint) lower), upper) BETWEEN lower AND upper</pre></td></tr>
<tr><td>No</td><td>No</td><td>No</td><td><pre>NULLIF(NULLIF(expr, lower), upper) BETWEEN lower AND upper</pre></td></tr>
</tbody></table>
<br />
<i><br /></i>
<i><br /></i>
<br />
<br />Peter Ayletthttp://www.blogger.com/profile/02745717570598757619noreply@blogger.com0tag:blogger.com,1999:blog-2352595641980283463.post-41046610964620658742017-11-13T21:07:00.001+11:002017-11-13T21:24:57.515+11:00Jaycar Arduino 16 Key Touch keypad XC4602So my ten year old daughter wanted to build a keypad enabled electric lock for her bedroom "to keep her little brothers out". TLDR: <a href="http://itimewaste.blogspot.com.au/2014/12/arduino-code-for-ttp229-touch-16-button.html">go here and solder</a>.<br />
<br />
We picked up the Jaycar <a href="https://www.jaycar.com.au/arduino-compatible-16-key-touch-keypad-module/p/XC4602">Arduino Compatible 16 Key Touch keypad module</a> cat XC4602, which is based on the TTP229 capacitative touch sensor IC. The board's by duinotech, and the only discernible numbers are 1003010 on the board, and 8229BSF on the IC.<br />
<br />
There's a downloadable Arduino demo on the Jaycar page, but we didn't have any luck with it.<br />
<br />
To get all 16 keys working, we followed the <a href="http://itimewaste.blogspot.com.au/2014/12/arduino-code-for-ttp229-touch-16-button.html">helpful instructions posted by this guy</a>. Yes, it does actually seem like you have to solder at least jumper 3 (yellow link on his post). That's the only one we did.<br />
<br />
Then he's got a link to his code, but it's hidden down the bottom of the page. <a href="https://www.dropbox.com/s/15h3znv4hxid23r/TouchButton16.ino?dl=0">Direct link</a>. You'll need to create yourself a Dropbox account to be able to download it though. The only other gotcha is that his sample code writes to serial at 115200 baud. Make sure you set your monitor to the same or you'll just get rubbish.<br />
<br />
After that, it's happy days. Just follow his wiring, and sample code. I figured I'd put this post out there pointing to his blog because there's a number of other posts out there about this IC that were much less helpful.<br />
<br />
Aside, we're using the Jaycar <a href="https://www.jaycar.com.au/electric-door-strike-12vdc-fail-safe/p/LA5081">Electric Strike EL-973</a> (fail safe version), Jaycar cat LA5081, for the lock mechanism. It needs 12V to activate, so I figured we'd drive it like a motor with an IRF520 mosfet. It works a treat.Peter Ayletthttp://www.blogger.com/profile/02745717570598757619noreply@blogger.com1tag:blogger.com,1999:blog-2352595641980283463.post-90464034134748665702017-01-29T14:47:00.001+11:002017-01-29T14:47:33.566+11:00Arduino Grove LCD RGB Backlight not workingThe <a href="https://www.seeedstudio.com/Grove-Starter-Kit-for-Arduino-p-1855.html">Grove Starter Kit</a> is a fun way to start on Arduino for young kids, because components can be easily plugged in, rather than needing to poke components into a board.<br />
<br />
The first time I tried to use the Grove LCD RGB Backlight board, I was disappointed that it seemed to not work. I could change the backlight color, however no text would appear.<br />
<br />
The simple resolution: The <a href="http://wiki.seeed.cc/Grove-LCD_RGB_Backlight/">LCD specs</a> state that it requires 5V to work. The Grove Base Shield has a slide switch to select 3.3V or 5V. Sensibly, it came preset to 3.3V. Slide it over to 5V and the LCD text starts working. When all else fails, RTM.Peter Ayletthttp://www.blogger.com/profile/02745717570598757619noreply@blogger.com1tag:blogger.com,1999:blog-2352595641980283463.post-31155604095079976392017-01-29T14:18:00.001+11:002017-01-29T14:20:50.817+11:00Playing with the Jaycar 2.8" TFT LCD touch screen XC4630Last year I was playing around with the 2.8" TFT LCD touch screen that's available from <a href="https://www.jaycar.com.au/medias/sys_master/images/8918529769502/XC4630-dataSheetMain.pdf">Jaycar XC4630</a> on the Arduino Uno. This is must try for anyone experimenting with Arduino. Easy to use and lots of fun.<br />
<br />
If this appears to be not working or broken with a blank screen, then possibly the driver library is not quite right.<br />
<br />
Jaycar now have a <a href="https://www.jaycar.com.au/medias/sys_master/images/8918529703966/XC4630-softwareMain.zip">custom build of libraries</a> on their website, which works fine. Download the file, and follow the instructions in the "XC4630 Notes.txt" file. These drivers and examples work fine for me.<br />
<br />
Unfortunately this wasn't available last year when I was trying to first get it working. (I was just sitting down now to write up what you can do, but see that it's all much easier now).<br />
<br />
The Jaycar libraries are based on the Adafruit libraries, which are hosted in GitHub. For posterity (or if you want to use a more up to date version of the libraries), I had to do the following to get them to work.<br />
<br />
1. Download the libraries<br />
<ul>
<li><a href="https://github.com/adafruit/Adafruit-GFX-Library">Adafruit GFX Library</a> (<a href="https://github.com/adafruit/Adafruit-GFX-Library/archive/master.zip">zip download</a>)</li>
<li><a href="https://github.com/adafruit/TFTLCD-Library">Adafruit TFTLCD Library</a> (<a href="https://github.com/adafruit/TFTLCD-Library/archive/master.zip">zip download</a>)</li>
<li><a href="https://github.com/adafruit/Touch-Screen-Library">Adafruit Touch Screen Library</a> (<a href="https://github.com/adafruit/Touch-Screen-Library/archive/master.zip">zip download</a>)</li>
</ul>
<div>
2. Import the libraries into the Arduino software</div>
<div>
<ul>
<li>Sketch | Include Library | Add .ZIP Library... (once for each)</li>
</ul>
<div>
3. Open an example</div>
</div>
<div>
<ul>
<li>File | Examples | TFTLCD-Library-master | graphicstest</li>
</ul>
<div>
4. Fix the hardware identifier</div>
<div>
<br /></div>
<div>
This is the bit that took a while to figure out. For reference, the serial number on my TFT LCD is: QR4 5265S01 G3/2 TP28017.</div>
</div>
<div>
<ul>
<li>It seems that the readID() function in the Adafruit library does not work with this particular hardware.</li>
<li>In the example graphicstest program, Locate line 60: uint16_t identifier = tft.readID();</li>
<li>Change it to: uint16_t identifier = 0x9341;</li>
<li>Or, equivalently, change line 84 to: tft.begin(0x9341);</li>
</ul>
<div>
The tftpaint program also worked for me with a similar change.</div>
<div>
<br /></div>
<div>
Hope this helps someone.</div>
<div>
<br /></div>
<div>
<br /></div>
</div>
<br />
<br />Peter Ayletthttp://www.blogger.com/profile/02745717570598757619noreply@blogger.com8tag:blogger.com,1999:blog-2352595641980283463.post-55287432903694293922014-04-17T13:40:00.000+10:002014-04-17T13:40:27.375+10:00Using property getter/setter functions in Angular bindingOK, is most circumstances there's a better way to do this, but sometimes life would be easier if we could have a getter function and a setter function in an Angular binding.<br />
<br />
Here's a helper function to make it more convenient to wrap them up. It's a bit rough, but does the job.<br />
<br />
<pre><code>
/**
* For use when you really want to intercept two-way Angular bindings.
* (And usually there's another better way)
*
* Example
* <input
* ng-model="asProp(getCheckbox, setCheckbox, someArg1, someArg2).value"
* type="checkbox" />
* ...
* $scope.asProp = lib.asProp;
* $scope.getCheckbox = function(someArg1, someArg2) { return ... };
* $scope.setCheckbox = function(newValue, someArg1, someArg2) { ... };
*
* Takes a getter and a setter function.
* And optionally additional arguments.
* Returns an object with a single property called 'value'.
* 'value' uses the provided getter and setter functions.
* Additional arguments are passed to the getter and setter:
* getter(additionalArgs) -> currentValue
* setter(newValue, additionalArgs)
*/
lib.asProp = function (getter, setter /* .. args */) {
var res = {};
var args = _.toArray(arguments).slice(2);
Object.defineProperty(res, 'value', {
get: function () {
return getter.apply(null, args);
},
set: function (val) {
var args2 = [val].concat(args);
setter.apply(null, args2);
},
enumerable: true,
configurable: true
});
return res;
};
</code>
</pre>
Peter Ayletthttp://www.blogger.com/profile/02745717570598757619noreply@blogger.com1tag:blogger.com,1999:blog-2352595641980283463.post-76445282922460084242014-01-04T21:11:00.000+11:002014-01-04T21:11:10.060+11:00Aurora inverter USB connectionWe had solar electric installed (yay!). We are using the Aurora PVI 4.2kW inverter, which appears to be a very well recommended unit, but there were a couple of challenges with trying to plug into the USB connection to download live data. Just thought I'd note them down here to hopefully save someone else a bit of time.<br />
<br />
There are two pieces of software you need:<br />
1. USB driver - makes the Aurora appear under Windows as a COM port. (Texas Instruments 3410 USB driver). We used this one instead of the Aurora one. "TI WDF USBUART Single Driver" from the software section of <a href="http://www.ti.com/product/tusb3410">this page</a>.<br />2. Aurora communicator software - Communicates with the Inverter to download and chart data.<br />
(Unfortunately the inverter doesn't actually collect historical data, you need to essentially leave the program running and poll for it). Communicator can be downloaded from <a href="http://www.power-one.com/renewable-energy/products/solar/string-inverters/aurora-uno-single-phase/pvi-303642-europe-apac/series">here</a>. (select 'UK' as the country, then select Software - because not all countries have any 'software' listed against them).<br />
<br />
Issue 1: My laptop is running Windows 7 (x64). For better or worse, the 64 bit version of Windows doesn't run unsigned device drivers. The driver may look like it has installed - but it won't run. The work-around for now is to boot Windows in the special mode to allow unsigned drivers. (Press F8 while the computer is booting, and select "Disable Driver Signature Enforcement."). Or <a href="http://www.raymond.cc/blog/loading-unsigned-drivers-in-windows-7-and-vista-64-bit-x64/2/">see here</a> for other options.<br />
<br />
Issue 2: The Inverter itself needed to be assigned an "address" before it would talk to anything. Go to the inverter itself and use the menu options to go into the settings and set an address. Any number will do. We used "2". Seems to be necessary and in our case wasn't already preconfigured.<br />
<br />
Next task: ditch the 70W laptop and start using a Rasberry Pi instead.Peter Ayletthttp://www.blogger.com/profile/02745717570598757619noreply@blogger.com2tag:blogger.com,1999:blog-2352595641980283463.post-58159703273165098692013-10-28T22:39:00.000+11:002013-10-28T22:39:41.384+11:00Bank Security MadnessThis has probably been said by countless people before, but banking security is just mind bogglingly dumb.<br />
<br />
Yesterday I phoned the NAB bank. Along with the usual questions I was asked to name a recent transaction. I couldn't recall one so I asked my wife who was standing next to me. The phone operator proceeded to tell me that I wasn't allowed to ask her because I was the person who needed to know the answer! NAB, if you make me communicate with my wife using a pen and paper instead, then you're not going to gain any security, you're just going to annoy customers.<br />
<br />
The next thing that struck me was that the transaction used for authentication could be a debit. Now, generally speaking you don't need to do any authentication to put money into an account. Anyone can deposit into your account as long as they have the account number; thereby rendering this authentication method (as it stands) useless at best.<br />
<br />
Today I phoned the ANZ bank. Their system is straight forward enough. I just need to know my Customer Reference Number, my telecode, my security code, and my web password. And I'd better well be able to remember which is which before I run out of attempts.<br />
<br />
Authentication is a hard problem to solve, but surely we can do a bit better than this.Peter Ayletthttp://www.blogger.com/profile/02745717570598757619noreply@blogger.com0tag:blogger.com,1999:blog-2352595641980283463.post-83154304255053055092013-10-08T22:34:00.001+11:002013-10-08T22:34:56.023+11:00Javascript dictionary using objects as keysOne thing that bugs me about Javascript is the inability to have a dictionary with objects as keys. Objects are dictionaries, but essentially toString gets called on anything you use as a key, which isn't always very helpful.<br />
<br />
Typical solutions are to call stringify on each object, which is relatively slow and doesn't guarantee reference equality, or to have a custom hashing function, which feels like unnecessary effort. (The <a href="http://www.timdown.co.uk/jshashtable/">jshashtable</a> library generally looks useful, but unless you provide the hashing function the performance drops considerably.<br />
<br />
So my requirements are:<br />
<ul>
<li>A dictionary that takes objects as keys</li>
<li>And will only resolve values using the same instance of the object (not just some string match)</li>
<li>Is fast</li>
<li>Without any custom hashing functions</li>
</ul>
It took a little while to realize that since the key is an object, the value can be stored directly on it, so long as we know which property the value got stored in. Job done. But because my poor head wants to deal with something like a traditional dictionary API, it can be achieved something like this:<br />
<br />
<pre>function Dict() {
Dict.id = (Dict.id || 0) + 1;
this._prop = '_dict' + Dict.id;
}
Dict.prototype = {
add: function(key, value) {
key[this._prop] = value;
},
contains: function(key) {
return typeof key[this._prop] != 'undefined';
},
get: function(key) {
return key[this._prop];
},
remove: function(key) {
delete key[this._prop];
}
};
// Sample usage
var a = {};
var b = {};
var c = {};
var dict1 = new Dict();
dict1.add(a, 123);
dict1.add(b, 456);
var dict2 = new Dict();
dict2.add(c, 789);
alert(dict1.get(a)); // 123
alert(dict1.contains(c)); // false
alert(dict2.contains(c)); // true
dict2.remove(c);
alert(dict2.contains(c)); // false
</pre>
<br />
OK, it needs a whole lot more work, but you get the idea. We keep track of a global ID so that a key can be used in more than one dictionary simultaneously. If we want to have some way to enumerate over the values or get a count, then we'd also need to store keys/values in the Dictionary itself. I'd probably go with a doubly-linked-list, otherwise add/removes would get slow.<br />
<br />
The main disadvantage is that we are adding an extra property to the key objects, which may be undesirable in some circumstances. But overall it solves the requirements without too much mess.Peter Ayletthttp://www.blogger.com/profile/02745717570598757619noreply@blogger.com0tag:blogger.com,1999:blog-2352595641980283463.post-63797222211001055212013-09-23T14:23:00.000+10:002013-09-23T14:23:01.656+10:00Using $q promises to run synchronous code asynchronouslyThe Q Javascript library provides a great way to handle the results of asynchronous tasks in a simple flexible manner. But the APIs required to actually generate and return promises for your own synchronous code are often a bit verbose, particularly if you want to catch and pass on exceptions as well.<br />
<br />
Here's a convenient shortcut: Just call $q.when() with no arguments, then place all of your synchronous code (that you want to behave asynchronously) in a subsequent .then() call. This will automatically pick up any results, or exceptions, and pass them on as promises.<br />
<br />
E.g.<br />
<pre>
function myAsyncSqrt(value) {
return $q.when()
.then(function() {
return Math.sqrt(value);
});
}
...
var promise = myAsyncSqrt(16);
promise.then(
function(res) { alert('answer:' + res); },
function(err) { alert('uh oh:' + err); });
</pre>Peter Ayletthttp://www.blogger.com/profile/02745717570598757619noreply@blogger.com0tag:blogger.com,1999:blog-2352595641980283463.post-74359593178111755212013-08-30T12:07:00.001+10:002013-08-30T12:07:26.057+10:00Allowing .Net unit tests to access internal membersGood code encapsulation requires that various members be marked as private, or at least internal. However this can make it difficult for unit test frameworks such as NUnit to access them.<br />
<br />
You can grant an external (e.g. unit test) assembly access to internal members by doing the following:<br />
<br />
<ol>
<li>Give your test assembly a strong name (via Project Properties, Signing, Sign the assembly)</li>
<li>Compile the assembly (eg. My.Test.dll)</li>
<li>Open the Visual Studio command prompt</li>
<li>Navigate to the folder where My.Test.dll got built</li>
<li>Run: sn -Tp My.Test.dll</li>
<li>This will display the full public key for the signed assembly. Copy it. (it'll be about 320 chars)</li>
<li>Open the AssemblyInfo.cs file for the assembly containing the code with internals to be tested.</li>
<li>Enter a line such as: [assembly: InternalsVisibleTo("My.Test, PublicKey=1234")] where 1234 is the full key generated in step 6.</li>
</ol>
Note: this only works if the full key is used, not the shorter summary key.Peter Ayletthttp://www.blogger.com/profile/02745717570598757619noreply@blogger.com0tag:blogger.com,1999:blog-2352595641980283463.post-23096901608114114672013-08-19T22:05:00.000+10:002013-08-19T22:06:15.003+10:00How to mock an Angular service for testing<p>To inject a fake version of <code>myService</code>, and intercept calls to <code>myMethod</code>, do something like this:</p>
<p>Or check out the cool video <a href="http://www.youtube.com/watch?v=qK-Z0oEdE4Y">here</a>.</p>
<pre>
var myMethodFake = function() { ... };
beforeEach(function () {
module(function ($provide) {
mockMyService = {
myMethod: jasmine.createSpy('myMethod').andCallFake(myMethodFake)
};
$provide.value('myService', mockMyService);
});
});
it('does stuff', inject(function(myService) {
myService.myMethod();
});
</pre>Peter Ayletthttp://www.blogger.com/profile/02745717570598757619noreply@blogger.com0tag:blogger.com,1999:blog-2352595641980283463.post-8909820106019800302013-08-15T17:52:00.000+10:002013-08-15T17:52:07.347+10:00Default IE XSLT for viewing XMLBeing blogged just because it shouldn't have taken me nearly as long to figure this out as it did.<br />
<br />
How to download the default XSLT template that IE uses for viewing XML. (The pretty looking one with collapsible/expandable elements):<br />
<br />
<ol>
<li>Use Visual Studio</li>
<li>Click File | Open | File</li>
<li>Open C:\Windows\System32\msxml3.dll (because VS knows what to do with a DLL)</li>
<li>Expand to: XML \ DEFAULTSS.XML</li>
<li>Right-click and Export..</li>
<li>Save it as an .xsl</li>
</ol>
<div>
All done.</div>
Peter Ayletthttp://www.blogger.com/profile/02745717570598757619noreply@blogger.com0tag:blogger.com,1999:blog-2352595641980283463.post-41548906129801950092013-03-18T22:23:00.002+11:002014-01-04T21:15:40.774+11:00The Hard Problem of Consciousness<br />
Personally I find the phenomena of human consciousness to be a powerful evidence that there is more to reality than the physical material world that naturalism is selling to us. Following is an attempt to gather and articulate my reasoning.<br />
<h4>
What is the ‘hard problem of consciousness’</h4>
<a href="http://en.wikipedia.org/wiki/David_Chalmers">David Chalmers</a> introduced ‘<a href="http://en.wikipedia.org/wiki/Hard_problem_of_consciousness">the hard problem of consciousness</a>’ as the internal experience that we perceive. “It is undeniable that some organisms are subjects of experience… Why should physical processing give rise to a rich inner life at all? It seems objectively unreasonable that it should, and yet it does.” Questions include: why do we experience colour, sound, emotions – as distinct from the physical questions of how we collect, transmit and process this information.<br />
<br />
It is distinct from other problems of consciousness, which he calls the ‘easy problems’ (although non-trivial in themselves), such as creativity, learning, introspection, and so on. The hard problem focusses on experience – why we perceive anything at all. Whereas the other problems are all just about behaviours – the way the brain reacts to stimulus. They’re essentially just information processing problems: receive input, access memory, process, produce output.<br />
<h4>
The answer does not lie in physical matter</h4>
Clearly brains are made of atoms. A single atom has a (relatively) simple behaviour. Apply some stimulus, and it will exhibit a somewhat predictable result. Put a small number of atoms together and their limited behaviours combine to be collectively more complex. Exponentially. So it’s perfectly reasonable to expect that a brain-sized bag of atoms can exhibit behaviours at least as complex as the brain itself. But at the end of the day, actions within are still just like long causal chains of dominoes. Individual atoms are just reacting to the forces on them.<br />
<br />
So what physical thing might be doing any sort of experiencing or perceiving? Physically, we still only have atoms. If a single atom has zero ability to experience, then neither does two or any number of atoms together. Regardless of how complex the structures, and how complex the behaviour, there is still nothing to do the perceiving. If you have a whole stadium full of blind people, then corporately they still wouldn’t figure out whether the lights were on just by talking to each other. Chalmers suggests that maybe atoms do have their own simple experiential life - I'm far from convinced.<br />
<br />
It should also be noted that the physical atoms – in the form of proteins and so on – that comprise the brain are being constantly refreshed, without apparent interruption to experience.<br />
<h4>
The answer does not lie in informational structures</h4>
It is often argued that experience must be an emergent property of the complex network of interconnected brain bits. However, I find this unconvincing. Informational systems still just produce behaviour. They can all still be distilled down to a Turing machine equivalent. (A <a href="http://en.wikipedia.org/wiki/Turing_machine">Turing machine</a> is the mathematical description of a computation process. Again: receive input, access memory, process, produce output.) Experience is not found at the logical level either.<br />
<br />
A thought experiment: Physics tells us that only a finite amount of information can be packed into a space. What if we could capture a brain (or an entire person) into a set of bits. A complex algorithm could be devised to ‘simulate’ the brain on a Turing machine. It could then be converted to a universal Turing machine (bigger dataset, tiny algorithm). What are we left with: the entire logical structure of a functioning brain would just be a phenomenally long string of ones and zeros flipping on and off. It could still produce the same complex array of behaviours – but where is the ability to experience hiding in that string of bits? How does it perceive the colour blue?<br />
<br />
A second: consider a constructed brain where it was possible to capture and log every logical input and output (along with its precise time and location) at each functional logical unit – as fine-grained as desired. Now rewire each functional unit so that it ignores its input and instead plays back from the log; and rerun it with the same stimulus. Every unit will give the same result as before, and present itself to the rest of the network in the same manner as before. It appears to run equivalently to the first run, even logically at the most granular level. However, the entire execution is a fraud – just a play-back of a fixed stream of data, devoid of experience.<br />
<h4>
One question…</h4>
While we’re simulating brains, what might we get if we perfectly scanned and simulated a real brain? Would this demonstrate that experience derives from the physical? No. It may be observed to behave like the original brain, but we have no way of verifying if it is actually experiencing anything. After all, only the entity itself can be aware of its own experience. It may be what is often called a <a href="http://en.wikipedia.org/wiki/Philosophical_zombie">philosophical zombie</a> – behaving, but not perceiving.<br />
<h4>
Natural or beyond</h4>
Whatever the solution to the hard problem may be, it is generally presented that the answer will be found without needing to invoke anything beyond the physical world that science is comfortable with. I find this to be circular reasoning. We are told that consciousness can be fully explained by the material world, because that is all there is. We are told that the physical world is all there is because we are not aware of any phenomena that cannot be explained by physical laws. Hmm.<br />
<br />
To me, a much more satisfying answer is a dualist approach. The brain gathers information. It does a great amount of processing, and problem solving. But ultimately it has a non-physical element that is able to genuinely experience the data gathered by the brain. I call it a soul. But whatever it is, the problem is real, and I really don’t think it’s going to be solved with hand-waiving and a material reality alone. I’m not suggesting “we haven’t found an answer yet, so it is reasonable to appeal to the super natural”. Rather, I am arguing a case that there can be no answer in the natural alone.<br />
<br />
The logical next question is ‘what good is an observing soul if it can’t influence the behaviour of the deterministic brain?’ That can be for another post.<br />
<br />Peter Ayletthttp://www.blogger.com/profile/02745717570598757619noreply@blogger.com0tag:blogger.com,1999:blog-2352595641980283463.post-47703016391301789842012-09-15T22:30:00.000+10:002012-09-15T22:30:45.683+10:00Interpreting the Bible<br />
Today I got asked "<i>Is it possible to accurately channel the bible, given that there are so many different interpretations available? Genuine question, not flamebait.</i>" Thought I'd repost the reply here.<br />
<br />
Sure, fair question. Assuming it isn't about translations or source of text. (But if it is, these are built on evidence-based processes using thousands of historical manuscripts, etc. Be suspicious of anyone says that only 'their' translation is correct). Different translations often serve different purpose (e.g. with varying tradeoffs between readability vs more literal translation of original text, which have less readable grammatical structures)<br />
<br />
Facetiously, there are so many different interpretations because people try to interpret it, rather than just read it. Reading the Bible is a comprehension exercise, like reading the paper, and for the most part it's pretty clear what it says. Unclear parts often become clear once more context is read; or when historical customs/geography/sayings are uncovered (often in the footnotes). Some parts are just plain unclear, but these tend not to be about topics that catch the public eye. Given it's a book to be understood by all people in all times, I wonder if some parts just aren't meant for us now.<br />
<br />
Unsurprising, not everyone who presents an 'interpretation' is doing so with honest intentions. Many try to use the Bible in the same way politicians use statistics: for support, rather than illumination. Reasons include:<br />
<br />
<ul>
<li>to deceive others</li>
<li>to deceive themselves</li>
<li>to self promote by trying to value-add</li>
</ul>
<br />
<br />
Some ways that people arrive at the wrong meaning include:<br />
<br />
<ol>
<li>like most documents, it's pretty easy to make it say the exact opposite of what it clearly says by quoting out of context; and you see a fair bit of that.</li>
<li>interpreting descriptive text as prescriptive text. (e.g. Abraham did this or that, but that doesn't mean that he was right to do it, let alone that we should do it).</li>
<li>trying to apply Old Testament rules to modern times. The Bible is clear that most don't apply now, along with why they did then, but don't after Jesus.</li>
<li>claiming it says something on a topic that it is silent on. (e.g. should children be baptised? some say yes, some say no, the Bible doesn't really say at all).</li>
<li>try to interpret text that is clearly poetry, parable, dream or metaphore, as literal. With a bit of context it's usually pretty easy to tell which is which.</li>
</ol>
<br />
<br />
Watching someone put a clearly wrong interpretation with a clear agenda is about as frustrating as watching people get up and say that climate change isn't happening. :)<br />
<br />
<span style="font-size: x-small;">p.s. I can't remember where I heard some of these analogies, but felt should at least say they're not original.</span>Peter Ayletthttp://www.blogger.com/profile/02745717570598757619noreply@blogger.com0tag:blogger.com,1999:blog-2352595641980283463.post-11965292207890815092012-05-03T00:10:00.002+10:002012-05-03T00:10:47.974+10:00MSBuild Task to generate hash of files<p>Here's a handy inline MSBuild task to take a bunch of files and generate a hash. I used it to generate a hash of source files in order to determine if an exe has really been changed (given that exe's compile to distinct files each time even if the source hasn't changed).</p><code><pre><Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"><br> <br> <UsingTask TaskName="GenerateHash" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll"><br> <ParameterGroup><br> <InputFiles ParameterType="Microsoft.Build.Framework.ITaskItem[]" Required="true" /><br> <OutputFile ParameterType="System.String" Required="true" /><br> </ParameterGroup><br> <Task><br> <Using Namespace="System.IO" /><br> <Using Namespace="System.Linq" /><br> <Using Namespace="System.Security.Cryptography" /><br> <Code Type="Fragment" Language="cs"><![CDATA[<br> using (var ms = new MemoryStream())<br> using (var md5 = MD5.Create())<br> { <br> foreach (var item in InputFiles)<br> {<br> string path = item.ItemSpec;<br> using (FileStream stream = new FileStream(path, FileMode.Open))<br> {<br> var fileHash = md5.ComputeHash(stream);<br> ms.Write(fileHash, 0, fileHash.Length);<br> }<br> }<br> ms.Flush();<br> ms.Position = 0;<br> var dirHash = md5.ComputeHash(ms);<br> using (TextWriter w = new StreamWriter(OutputFile, false))<br> {<br> w.WriteLine(string.Join("", dirHash.Select(b => b.ToString("x2"))));<br> }<br> }<br> ]]></Code><br> </Task><br> </UsingTask><br><br> <Target Name="Demo"><br> <GenerateHash InputFiles="@(SomeFiles)" OutputFile="res.txt" /><br> </Target><br></Project></pre></code>Peter Ayletthttp://www.blogger.com/profile/02745717570598757619noreply@blogger.com0tag:blogger.com,1999:blog-2352595641980283463.post-19893698430758703412012-05-03T00:07:00.001+10:002020-03-26T09:24:04.547+11:00Inline MSBuild task to generate hash of files<p>Here's a handy inline MSBuild task to take a bunch of files and generate a hash. I used it to determine if two sets of source code are changed.</p><code><Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"><br> <br> <UsingTask TaskName="GenerateHash" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll"><br> <ParameterGroup><br> <InputFiles ParameterType="Microsoft.Build.Framework.ITaskItem[]" Required="true" /><br> <OutputFile ParameterType="System.String" Required="true" /><br> </ParameterGroup><br> <Task><br> <Using Namespace="System.IO" /><br> <Using Namespace="System.Linq" /><br> <Using Namespace="System.Security.Cryptography" /><br> <Code Type="Fragment" Language="cs"><![CDATA[<br> using (var ms = new MemoryStream())<br> using (var md5 = MD5.Create())<br> { <br> foreach (var item in InputFiles)<br> {<br> string path = item.ItemSpec;<br> using (FileStream stream = new FileStream(path, FileMode.Open))<br> {<br> var fileHash = md5.ComputeHash(stream);<br> ms.Write(fileHash, 0, fileHash.Length);<br> }<br> }<br> ms.Flush();<br> ms.Position = 0;<br> var dirHash = md5.ComputeHash(ms);<br> using (TextWriter w = new StreamWriter(OutputFile, false))<br> {<br> w.WriteLine(string.Join("", dirHash.Select(b => b.ToString("x2"))));<br> }<br> }<br> ]]></Code><br> </Task><br> </UsingTask><br><br> <Target Name="Demo"><br> <GenerateHash InputFiles="@(SomeFiles)" OutputFile="res.txt" /><br> </Target><br></Project></code>Peter Ayletthttp://www.blogger.com/profile/02745717570598757619noreply@blogger.com0tag:blogger.com,1999:blog-2352595641980283463.post-43192354224847843212012-03-11T23:08:00.002+11:002012-03-11T23:11:37.973+11:00GoDaddy Joomla on Windows: fail<p>Hi GoDaddy Support,</p><p>I recently installed the Joomla application. I deployed two instances to: <em>URIs omitted</em></p><p>They are both running extremely slowly. (Between 4 and 10 seconds to respond - way to slow for a web site). I haven't even set up any content on them yet. Can you please help? Why are they running so slowly?</p><p>Thanks in advance.</p><hr><b>Support Staff Response</b><p>Dear Peter,</p><p>Thank you for contacting Online Support. I understand you installed Joomla to a Windows hosting plan. This would be why the sites are resolving slowly. If you do not have ASP elements or any other windows only content, I would recommend switching to a Linux hosting plan as these run Joomla much better. You can change your hosting Operating System by following the instructions below.</p><p>If you find that you need to switch the operating system of your hosting account, you can do so at any time.</p><p><b>To Switch Your Hosting Account Operating System</b></p><ul><li>Log in to your Account Manager.Click Web Hosting.</li><li>Click Options next to the account you want to use.</li><li>Go to the Customize tab.</li><li>From the Plan menu, select a new hosting plan. NOTE: If you do not see the Plan menu, contact customer support.</li><li>Click Save Changes or Checkout, and then complete your purchase.</li></ul><p>This change may make take up to 72 hours depending on the size of the site, the number of databases and other factors that may increase the complexity of the migration. We recommend that you do not try to FTP to your hosting account during the migration. You will receive an email message when we complete your upgrade.</p><p>NOTE: If your website contains certain advanced features, such as ASP, ASP.NET, CGI, or PHP applications and you select a hosting plan that does not support those advanced features, your website may no longer function properly after the plan change. Please make sure your website does not contain advanced features BEFORE moving to a plan that may not support them or be prepared to modify your Web content accordingly.</p><p>NOTE: If you created databases that are incompatible with the new operating system, you must delete them before proceeding. Data existing in compatible databases will be preserved.</p><p>Please let us know if we can assist you in any other way.</p><p>Sincerely,</p><p>Mike P.</p><p>Online Support</p><hr><p>*sigh*</p>Peter Ayletthttp://www.blogger.com/profile/02745717570598757619noreply@blogger.com4tag:blogger.com,1999:blog-2352595641980283463.post-89280795117366450452012-02-09T09:43:00.000+11:002012-02-09T09:44:13.151+11:00Universal Turing SnakeRandom thought for the day: How hard would it be to make a mechanical Universal Turing Machine that used an arbitrarily long Rubik's snake as the tape? ...out of Lego... Hmm...Peter Ayletthttp://www.blogger.com/profile/02745717570598757619noreply@blogger.com2tag:blogger.com,1999:blog-2352595641980283463.post-90763884974834599602012-02-09T09:31:00.004+11:002012-02-09T09:40:22.337+11:00ShouldSerialize<p>Sometimes features are staring at you in the face, all you need to do is read the docs. Other times it really feels like things are hidden. Thanks Con for pointing me to <code>ShouldSerialize</code><em>PropertyName</em> - I did a careful look through the MSDN serialization docs in hope of finding this very feature, but didn't have any luck.</p><p>What does it do? For any given property, create a <code>bool ShouldSerialize</code><em>PropertyName</em><code>()</code> method to decide if it should be included in serialization. A bit magical, but does the trick.</p><p>Why do I want this? I want to serialize an object graph to XML. But I don't want to render a container element for any empty collections. I think I'm becoming a bit of a pedent when it comes to XML.</p><p>Docs (in as much as I could be find any) are <a href="http://msdn.microsoft.com/en-us/library/53b8022e.aspx">over here</a> under Windows Form Controls.</p>Peter Ayletthttp://www.blogger.com/profile/02745717570598757619noreply@blogger.com0tag:blogger.com,1999:blog-2352595641980283463.post-79939739186419906302012-01-31T22:15:00.001+11:002012-01-31T22:15:35.514+11:00SQL Optimisation articleThanks to Martin for pointing me to this Microsoft article on SQL optimization: <a href="http://download.microsoft.com/download/d/9/4/d948f981-926e-40fa-a026-5bfcf076d9b9/bpsemanticdbmodeling.docx">Best Practices for Semantic Data Modeling for Performance and Scalability</a>. A tightly packed and in depth look at various SQL Server optimisation techniques.Peter Ayletthttp://www.blogger.com/profile/02745717570598757619noreply@blogger.com0