tag:blogger.com,1999:blog-131873192024-03-07T08:35:05.151+00:00Copious Free Time<b>copious free time</b> (n.): [used ironically to indicate the speaker's lack of the quantity in question] A mythical schedule slot for accomplishing tasks held to be unlikely or impossible. Sometimes used to indicate that the speaker is interested in accomplishing the task, but believes that the opportunity will not arise. "I'll implement the automatic layout stuff in my copious free time."Unknownnoreply@blogger.comBlogger21125tag:blogger.com,1999:blog-13187319.post-2497747239988634222008-04-17T11:36:00.000+01:002008-04-19T11:36:34.632+01:00--work-properly<span style='font-size:10px;'>[<b>reading:</b>
<a href="http://www.amazon.co.uk/exec/obidos/ASIN/0572029187">Jean Hugard & Frederick Braue, "The Royal Road to Card Magic (revised edition)"</a>; recently
<a href="http://www.amazon.co.uk/exec/obidos/ASIN/0486410870">Henning Nelms, "Magic and Showmanship: A Handbook for Conjurers"</a>]</span>
<p>
Today's
<a href="http://paranormalorigin.blogspot.com/2005/04/finding-work-properly-option.html"><code>--work-properly</code></a>
option: adding <b><code>-rdynamic</code></b> (a.k.a. <code>--export-dynamic</code>) to a
<a href="http://gcc.gnu.org">GCC</a>
link line will mean that any
<a href="http://linux.die.net/man/3/dlopen"><code>dlopen</code></a>ed libraries are able to bind to the symbols in the
running executable.
</p>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-13187319.post-40621098734950679582008-02-25T20:44:00.001+00:002008-02-25T20:44:39.114+00:00Remote Reset<span style='font-size:10px;'>[<b>reading:</b>
<a href="http://www.amazon.co.uk/exec/obidos/ASIN/1905239572">Neil Gaiman, "Eternals"</a>]</span>
<p>
Someone at work was complaining the other week about the difficulties of testing with the
<a href="http://www.enea.com/templates/Extension____12765.aspx">OSE</a> board. The board
needs to have the reset button pressed after each test, and the problem was that the board
lives in the machine room at the other end of the building.
</p><p>
I remembered that I had an old Lego
<a href="http://en.wikipedia.org/wiki/Lego_Mindstorms">Mindstorms</a>
set rotting in the cellar, so I decided to help out:
</p>
<a href="http://www.flickr.com/photos/90388579@N00/2291357909/" title="Board reset device">
<img src="http://farm4.static.flickr.com/3187/2291357909_f6daae36be.jpg" width="500" height="375" alt="P1010535" /></a>
<p>
One of the motors had died in the meanwhile, but a contraption to press a button only needs a single motor.
The software had rotted quite badly too—the old software that came with the set wouldn't work
with XP, and there didn't seem to be any updates on the Lego website.
</p><p>
Open source to the rescue: the <a href="http://bricxcc.sourceforge.net/nqc/">NQC</a> compiler
together with the <a href="http://bricxcc.sourceforge.net/">Bricx</a> IDE sorted out the 6 line
program that I needed, and so remote reset was born.
</p>
<div class='tags'>hardware</div>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-13187319.post-91423355637756248332007-12-22T17:15:00.000+00:002007-12-23T07:56:58.467+00:00O for Oxygen, 0 for Zero<span style='font-size:10px;'>[<b>reading:</b>
<a href="http://www.amazon.co.uk/exec/obidos/ASIN/0462099121">Bjørn Lomborg, "Cool It: The Skeptical Environmentalist's Guide to Global Warming"</a>; recently
<a href="http://www.amazon.co.uk/exec/obidos/ASIN/1841495700">Charles Stross, "The Jennifer Morgue"</a>]</span>
<p>
Shocking. The reporting of science in the media has always been pretty rubbish, but the
<a href="http://news.bbc.co.uk">BBC News website</a> can't even
<a href="http://news.bbc.co.uk/1/hi/uk/7150834.stm">spell
CO<sub>2</sub> correctly</a>.
</p><p>
I'd let them off not doing the subscript correctly, even though it's not exactly
difficult to do <code><sub>2</sub></code> or <code>&#x2082;</code> for '₂'
(<a href="http://www.fileformat.info/info/unicode/char/2082/index.htm">U+2082</a>).
</p><p>
But not being able to spell "<b>O</b>" correctly is just impressively awful. And it's
<a href="http://search.bbc.co.uk/cgi-bin/search/results.pl?tab=ns&q=c02&edition=d&scope=all">endemic</a>.
</p>Unknownnoreply@blogger.com1tag:blogger.com,1999:blog-13187319.post-42926310867985799222007-09-25T19:50:00.000+01:002007-09-26T07:57:28.601+01:00Denied<span style='font-size:10px;'>[<b>reading:</b>
<a href="http://www.amazon.co.uk/exec/obidos/ASIN/0521867444">Michael Spivak, "Calculus"</a>]</span>
<p>
Bugger. It turns out that the Apple rep who told me on the phone that
the new iPod Classic would work with Mac OS X 10.3.9 was
<a href="http://personal.cis.strath.ac.uk/~rjg/tmp/ipod/ipod_classic_workaround.html">lying</a>.
</p>
<a href="http://www.flickr.com/photos/90388579@N00/1440913431/">
<img src="http://farm2.static.flickr.com/1223/1440913431_690ec09fc8_o.jpg" width="474" height="146" alt="ipodissue" /></a>
<p>
I don't really want to have to buy
<a href="http://store.apple.com/Apple/WebObjects/ukstore.woa/wa/RSLID?mco=9401D3C8&nplm=MA454">Mac OS X
10.4</a>.
I particularly don't want to have to buy 10.4 a mere
<a href="http://gwhiz.wordpress.com/2007/04/12/leopard-release-date-october-07/">month before 10.5 comes out</a>.
It's especially annoying as I spent a while cleaning up my music library and getting album art for
everything in anticipation of the Arrival of the New Toy.
</p><p>
So I guess I've got an expensive paperweight for the next month or two (until 10.5 comes out).
<p>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-13187319.post-4974517224004266672007-06-11T21:40:00.000+01:002007-06-12T09:41:17.306+01:00Bogo-Permute<p>
So here's today's random question, apropos of, er, nothing. What's the performance of the following
<a href="http://en.wikipedia.org/wiki/Bogosort#Bozo_sort">incredibly-poor</a>
algorithm for randomly permuting a list of numbers?
</p>
<pre>
def bogo_permute(in_list):
N = len(in_list)
out_list = []
# Keep track of whether we have dealt with each element of the input list
seen = [False] * N
for iteration in range(N):
while True:
which = randrange(N)
if not seen[which]:
out_list.append(in_list[which])
seen[which] = True
break
return out_list
</pre>
<p>
There are <i>N</i> selections needed for the output list. The first time through, the randomly selected
entry from the input list will definitely not have been processed already, so it can be transferred
across to the output list. The second time through, there's a chance that the random selection
process will select the same entry again; for later iterations, this chance of selecting something
that has already been selected will get higher and higher. So, on average, how many of these repeated
picks are needed?
<blockquote>
<p>
Given a coin that comes up heads with probability <i>p</i> (and so tails with probability <i>q=1-p</i>),
what's the average number of coin tosses needed before the first heads comes up?
</p><p>
As an example, imagine that the first head turns up on the fourth toss. This means that the sequence
of tosses is TTTH. The probability of this sequence of coin tosses is then
<i>q<sup>3</sup>p</i> = <i>(1-p)<sup>3</sup>p</i>.
This is easy to generalize:
</p>
<table>
<tr><th>Number of Tosses</th><th>Sequence</th><th>Probability</th></tr>
<tr><td>1</td><td>H</td><td><i>p</i></td></tr>
<tr><td>2</td><td>TH</td><td><i>qp</i></td></tr>
<tr><td>3</td><td>TTH</td><td><i>q<sup>2</sup>p</i></td></tr>
<tr><td>4</td><td>TTTH</td><td><i>q<sup>3</sup>p</i></td></tr>
<tr><td>⋮</td><td>⋮</td><td>⋮</td></tr>
<tr><td>m</td><td>T…TH</td><td><i>q<sup>m-1</sup>p</i></td></tr>
</table>
<p>
We want the average number of tosses needed to get a head, also known as the
<a href="http://en.wikipedia.org/wiki/Expected_value">expected value</a>.
This is a sum of the each possible value multiplied by the probability of that value occurring. In other
words, the average number of tosses needed is:
</p>
<blockquote>
(1*(probability of heads on first toss) + 2*(probability of first heads on second toss) + 3*(probability of
heads on third toss) + …)
</blockquote>
<p>
Put into maths, this means that the average number is an infinite sum:
<i>Σ<sub>m=1</sub><sup>∞</sup> m (q<sup>m-1</sup>p)</i>. From a trusty
<a href="http://en.wikipedia.org/wiki/Binomial_expansion">binomial
expansion</a>, the
<i>Σ<sub>m=1</sub><sup>∞</sup> m q<sup>m-1</sup></i> part pops out
as <i>(1-q)<sup>-2</sup></i>, and since <i>q=1-p</i> this means that the whole thing
simplifies down to just <i><b>1/p</b></i>.</p>
</p><p>
(This seems reasonable: for a fair coin, it takes an average of 2 throws to get a head; for a coin
that only comes up heads one time in a hundred, it takes an average of a hundred throws.)
</p>
</blockquote>
<p>
So back to the original problem. For the <i>i</i>-th selection (with <i>i</i> running from 1 to N),
the chance of picking an array
entry that is still there is <i>p=(N+1-i)/N</i>, and so the average number of picks needed is
<i>N/(N+1-i)</i>. The first selection needs <i>N/N = 1</i> attempt, the second selection
needs <i>N/(N-1)</i> attempts, the third selection needs <i>N/(N-2)</i> attempts, …, the last
selection needs <i>N/1 = N</i> attempts (on average).
</p><p>
Taken together, this means that the average number of random picks for the whole process is
<i>Σ<sub>i=1</sub><sup>N</sup> N/(N+1-i)</i>. Rearranging (with <i>j=N+1-i</i>) this is the
same as <i>N Σ<sub>j=1</sub><sup>N</sup>1/j</i>, which includes a partial sum of the
<a href="http://en.wikipedia.org/wiki/Harmonic_series_%28mathematics%29#Partial_sums">harmonic series</a>,
known as a
<a href="http://en.wikipedia.org/wiki/Harmonic_number">harmonic number</a> <i>H<sub>N</sub></i>.
In the large <i>N</i> limit, the harmonic numbers tend to <i>H<sub>N</sub> ≈ ln(N) + γ</i>
(where <i>γ</i> is a <a href="http://en.wikipedia.org/wiki/Euler-Mascheroni_constant">constant</a>),
and so the asymptotic behaviour of the algorithm is <b><i>O(N ln(N))</i></b>.
</p><p>
So it's bad, but not quite as bad as I'd expected (I'd guessed it would be <i>O(N<sup>2</sup>)</i>).
</p>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-13187319.post-79501482658179789952007-05-04T17:01:00.000+01:002008-02-06T17:58:16.918+00:00inline_related_objects<i>[Edit, Feb 2008: fixed typo—changed <code>extra_content</code> to
<code>extra_conte<b>x</b>t</code>]</i>
</p><p>
Today's neat
<a href="http://www.djangoproject.com">Django</a> trick: getting the
<a href="http://www.djangoproject.com/documentation/generic_views/#create-update-delete-generic-views"><code>create_update</code> </a> generic views for a model to display entries
from a subsidiary model in-line—like the
<a href="http://www.djangoproject.com/documentation/tutorial02/">admin interface</a>
does when you add <code>edit_inline=models.TABULAR</code>.
</p><p>
The (<code>oldforms</code>) Form object that gets generated by the <code>create_update</code>
view already has most of the required gubbins inside it; we just need a few extra steps to get at it:
<ol>
<li>In <code>urls.py</code>, set an
<code>extra_context</code> argument for the view to be a dictionary that contains <code>inline_related_objects</code>:
<pre> {'inline_related_objects': <i>model</i>._meta.get_followed_related_objects(None) } </pre>
</li>
<li>In the template, include a loop to pull in all of the related objects:
<pre> {% for related_object in inline_related_objects %}{% edit_inline related_object %}{% endfor %} </pre>
within the <code><form></code> tag.
</li>
<li>Since the <code>edit_inline</code> template tag is not a built-in Django tag, the template also needs
to load up the <code>admin_modify</code> extension:
<pre> {% load admin_modify %} </pre>
</li>
<li>Make local copies of the relevant admin templates (such as <code>admin/edit_inline_tabular.html</code>
and <code>widget/foreign.html</code>) and tweak appropriately.</li>
</ol>
<p>
Of course, I didn't figure this out until <i>after</i> I'd spent a couple of hours dismantling the
admin interface code with a view to stealing the relevant bits. Roll on the
<a href="http://djangobook.com">Django book</a>.
</p>Unknownnoreply@blogger.com2tag:blogger.com,1999:blog-13187319.post-26745977530755708932007-04-14T14:50:00.000+01:002007-04-14T14:57:22.853+01:00The Joy of UNIX<p>
UNIX credo: you can do anything from a single command line (as long as the line is allowed to be arbitrarily long).
</p><p>
Case in point:
<a href="http://www.lurklurk.org/whitenoise.html">generating a white noise audio file</a>
</p>
<pre>
sox -t sl -r 44100 -c 2 /dev/zero \
-r 44100 -c 2 -w whitenoise.wav synth 10:00 whitenoise vol 0.6 fade q 10 10:00 10
</pre>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-13187319.post-25909714251365457282007-03-16T15:35:00.000+00:002007-03-18T17:51:30.967+00:00Magic Number<p>
And the number is: 978-1-84753-300-5.
</p>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-13187319.post-20847397326921712652007-02-25T18:00:00.000+00:002007-03-13T08:53:31.668+00:00The Spine is Evil<span style='font-size:10px;'>[<b>reading:</b>
<a href="http://www.amazon.co.uk/exec/obidos/ASIN/0932980015">Skippy Blair, "Disco to Tango and Back"</a>;
recently:
<a href="http://www.amazon.co.uk/exec/obidos/ASIN/1560259736">Simon Lovell, "How To Cheat At Everything"</a>]</span>
<p>
Drat; forgot to add extra space on the inside margins of my current typesetting project, so I had to go back
through all of the chapters and re-set everything. Like the man said,
<a href="http://www.egscomics.com/Filler/d/20050921.html">the spine is evil</a>.
</p>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-13187319.post-1166203818900819002006-12-13T17:29:00.000+00:002006-12-15T17:38:41.916+00:00Django Su<p>
It's always a sign of good design when adding a new feature turns out to be easy.
<p>
In the
<a href="http://www.djangoproject.com">Django</a>
<a href="http://www.djangoproject.com/documentation/authentication/">authentication system</a>, I
wanted a way for an administrator to view the site as if they were
a particular user; effectively an equivalent to
<a href="http://en.wikipedia.org/wiki/Su_(Unix)"><code>su</code></a> in UNIX-land.
</p>
<p>
The first easy step was to invent a URL to correspond to this action, which gets
encoded in
<a href="http://www.djangoproject.com/documentation/url_dispatch/"><code>urls.py</code></a>:
</p>
<pre>
(r'^su/(?P<username>.*)/$', 'qlockweb.accounts.views.su', {'redirect_url': '/qlockdata/'}),
</pre>
<p>
That done, the second and final step is to write some view code.
<pre>
@user_passes_test(lambda u: u.is_staff)
def su(request, username, redirect_url='/'):
su_user = get_object_or_404(User, username=username)
if su_user.is_active:
request.session[SESSION_KEY] = su_user.id
return HttpResponseRedirect(redirect_url)
</pre>
<p>
Seven lines of code and we're done (modulo a bunch of <code>import</code> statements).
</p>
<p>
Expanding what's going on here:
</p>
<ul>
<pre>(r'^su/(?P<username>.*)/$', 'qlockweb.accounts.views.su', {'redirect_url': '/qlockdata/'}), </pre>
<li>When an HTTP request arrives at the framework, Django goes through its list of URLs until it finds a
match. In this case, going to <b>http://mysite/accounts/su/fred/</b> ends hitting the <code>urls.py</code>
line above; the <code>/(?P<username>.*)/</code> part of the regexp pulls out "<b>fred</b>" and this gets
passed as a parameter named <code>username</code> into the function <code>su</code>
in <code>qlockweb/accounts/views.py</code>. This function also gets passed a parameter
called <code>redirect_url</code> with value <code>'/qlockdata/'</code>.</li>
<pre>@user_passes_test(lambda u: u.is_staff)</pre>
<li>Actually, we need to rewind one step before we get into the <code>su</code> function. The
line <i>before</i> the function definition is a Python
<a href="http://www.ddj.com/184406073">decorator</a>: some extra code wrapping the function that gets
executed just before the function itself is executed. This decorator needs some expansion of its own:
<ul>
<pre><b><span style='color:red'>@</span></b>user_passes_test(lambda u: u.is_staff)</pre>
<li>The @ sign is the syntactic sugar that indicates that this line is a decorator for the function
that comes immediately afterwards.</li>
<pre>@<b><span style='color:red'>user_passes_test(</span></b>lambda u: u.is_staff)</pre>
<li>This is the decorator function (from <code>contrib/auth/decorators.py</code>); its first
argument <code>test_func</code> is a function that does the test. This test function is given
a single parameter: the current <code>User</code>. If the test function returns
true, the wrapped view code is called; if not, then the user gets redirected to a login page.
</li>
<pre>@user_passes_test<b><span style='color:red'>(lambda u:</span></b> u.is_staff)</pre>
<li>More syntactic sugar. We want a function <code>is_this_a_staff_user(u)</code> that
checks whether its argument <code>u</code> is an administrator. However, as this is the
only place that the function is used, we don't bother to give it a name—we just use
a <a href="http://diveintopython.org/power_of_introspection/lambda_functions.html">lambda expression</a>
to give the definition right here and now.</li>
<pre>@user_passes_test(lambda u: <b><span style='color:red'>u.is_staff</span></b>)</pre>
<li>Finally, the body of the lambda expression just uses the method of the <code>User</code> class
that indicates whether the user is an administrator or not.</li>
</ul></li>
<pre>def su(request, username, redirect_url='/'):</pre>
<li>So now we're in the <code>su</code> function itself, and if we've got this far we're guaranteed that the person viewing the
page is logged in as an <code><b>is_staff</b></code> user. The function has the <code>username</code>
and <code>redirect_url</code> parameters mentioned earlier; it also has a <code>request</code>
parameter that holds all of the information about the original web request (in a
<a href="http://www.djangoproject.com/documentation/request_response/"><code>HttpRequest</code></a>
object).</li>
<pre> su_user = get_object_or_404(User, username=username)</pre>
<li>The next line of code gets a <code>User</code> object for the username that was
specified—<code>fred</code> in other words. If there isn't a user called <code>fred</code>, then
a <code>Http404</code> exception gets raised, which will percolate up the stack and display a (surprise,
surprise) 404 page.</li>
<pre> if su_user.is_active:</pre>
<li>This particular version of our code only allows impersonation of active users, helpfully provided by
the <code>is_active</code> field in the standard <code>User</code> model.</li>
<pre> request.session[SESSION_KEY] = su_user.id</pre>
<li>The next line of code is the one that actually does the work. The requesting user's
<a href="http://www.djangoproject.com/documentation/sessions/">session</a>
is modified so that its user ID is the impersonated user's.</li>
<pre> return HttpResponseRedirect(redirect_url)</pre>
<li>The final line of code redirects the web browser off to the <code>redirect_url</code> page.</li>
</ul>
<p>
(Statutory disclaimer: I am not a security expert, nor do I play one on TV. Adding this to a production
system is probably not a good idea.)
</p>
<hr/>
<p>
Another Django snippet: I finally
<a href="http://www.rossp.org/blog/2006/aug/23/changemanipulators-only-part-model/">discovered</a>
that the <code>follow</code> argument to the standard
<a href="http://www.djangoproject.com/documentation/forms/">Manipulators</a>
allows you to list fields in the model that the form should leave untouched. Very helpful: the
end result is more compact
and less brittle than the code I'd put together to manually override all of the hidden fields.
</p>
<p><span style='font-size:10px;'>[A:37385 B:3278 C:346 D:9187 E:62544 Total:112740]</span>
</p>Unknownnoreply@blogger.com3tag:blogger.com,1999:blog-13187319.post-1165069996085344142006-12-02T14:32:00.000+00:002007-08-02T16:08:58.824+01:00Mind Hack #39<span style='font-size:10px;'>[<b>reading:</b> Jón Árnason, Alan Boucher (translator), "Icelandic Folk Tales"]</span>
<p>
<p>
One of the <a href="http://www.mindhacks.com">MindHacks</a>
that doesn't include an easy demonstration is Hack 39,
where you're less likely to notice a trigger event if it occurs
soon (say, <0.5s) after another trigger event.
</p>
<p>(Now that I've got into the content rather than being
<a href="http://copiousfreetime.blogspot.com/2006/11/editing-hacks.html">distracted by the typesetting</a>, the
<a href="http://www.amazon.co.uk/exec/obidos/ASIN/0596007795">book</a> is turning out to be rather good.)
</p>
<p>
My first attempt to test this out is below, but I have to say that the
effect didn't seem all that strong to me—so maybe there's a bug or
I've implemented it wrong. Or maybe I'm just too impatient to run it for
long enough to get statistically significant data.
</p>
<blockquote>
<p>After hitting "Go", this applet will display letters for a tenth of a second each. You should hit a key
whenever the letter displayed is either "<b>X</b>" or is displayed in white. To stop the applet, hit "Stop"
or press the Escape key.
<p>
<applet code="ablink.class" archive="http://www.lurklurk.org/ablink.jar" width=300 height=300></applet>
<p>
After running the applet, the bar graph shows the time between triggers (on the X axis) against how
many triggers there were with that delay; the white is the total number shown, the black is the subset
of them that were missed. Hitting "Go" again accumulates more data.
<p>
(<a href="http://www.lurklurk.org/src/ablink.tgz">Download source code</a>)
</blockquote>
<p><span style='font-size:10px;'>Technical Details: letters are picked uniformly (so there's a 1/26 chance of
a letter X trigger) and white is used for the colour 1/20 of the time. A trigger is considered hit if there's
a keypress within 1 second after the trigger, but each keypress only counts once (so "trigger, trigger,
keypress, letters…" would count as one hit then one missed trigger, with a delay of 1).</span>
</p>
<p><span style='font-size:10px;'>[A:37385 B:3278 C:346 D:9187 E:46445 Total:96641]</span>
</p>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-13187319.post-1164896414887660872006-11-30T14:19:00.000+00:002007-07-12T09:15:44.503+01:00*knolp*<span style='font-size:10px;'>[<b>reading:</b>
<a href="http://www.amazon.co.uk/exec/obidos/ASIN/0099479311">William Faulkner, "As I Lay Dying"</a>; recently
<a href="http://www.amazon.co.uk/exec/obidos/ASIN/0060884053">Neil Strauss & Bernard Chang, "How To Make Money Like a Porn Star"</a>]</span>
<p>
Now that I've got
<a href="http://www.djangoproject.com">Django</a>
<a href="http://paranormalorigin.blogspot.com/2006/11/django.html">installed</a>
and running, I've been setting up my first web application with it.
</p>
<p>
I spent a bunch of time yesterday trying to figure out how to get extra parameters passed through a
<a href="http://www.djangoproject.com/documentation/generic_views/">generic view</a>; in the end I had to
<a href="http://catb.org/jargon/html/U/UTSL.html">UTSL</a>
to get a method that worked.
</p>
<p>
So of course today I find a
<a href="http://www.b-list.org/weblog/2006/11/16/django-tips-get-most-out-generic-views">nice page</a>
that concisely and coherently explains it, rather more quickly than the couple of hours it took me to figure
out.
</p>
<p>
Perhaps I can suggest <code><b>*knolp*</b></code> (the reverse of
<code><a href="http://catb.org/jargon/html/P/plonk.html">*plonk*</a></code>) as the sound of an
<a href="http://www.b-list.org/">RSS feed</a>
hitting my aggregator. (It looks like I'm not the
<a href="http://www.somethinkodd.com/oddthinking/2005/09/15/anti-plonk/#comment-712">first</a>
<a href="http://www.thescripts.com/forum/threadnav215304-3-10.html">person</a>
to think of this.)
</p>
<p><span style='font-size:10px;'>[A:37385 B:3278 C:346 D:9187 E:46320 Total:96516]</span>
</p>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-13187319.post-1164531509395460102006-11-25T20:57:00.000+00:002006-11-26T08:59:04.716+00:00&numl;<span style='font-size:10px;'>[<b>reading:</b>
<a href="http://www.amazon.co.uk/exec/obidos/ASIN/0950847003">Derek Young, "Rock'n'Roll Dancing"</a>]</span>
<p>
Here's a question: is there a <a href="http://unicode.org">Unicode</a> character for an N with an
<a href="http://en.wikipedia.org/wiki/Heavy_metal_umlaut">umlaut</a>?
</p>
<p>
(Triggered by eating a splendid dessert of
<a href="http://www.gupuds.com/decadent/index_master.html">Gü</a> brownies and
<a href="http://www.haagen-dazs.com/index.jsp">Häagen-Dazs</a> ice cream, which made me think of
that most famous of fake umlauts, the one in the name of
"<a href="http://www.spinaltap.com/">Spinal Tap</a>").
</p><p>
Oh, and compounds like <code>U+006E U+0208</code> (i.e. <code>0x6e 0xcc 0x88</code> in UTF-8)
don't count.
</p>
<p><span style='font-size:10px;'>[A:37385 B:3278 C:346 D:9187 E:39180 Total:89376]</span>
</p>Unknownnoreply@blogger.com2tag:blogger.com,1999:blog-13187319.post-1164103165218153962006-11-21T09:59:00.000+00:002007-08-05T10:35:19.898+01:00Editing Hacks<span style='font-size:10px;'>[<b>reading:</b>
<a href="http://www.amazon.co.uk/exec/obidos/ASIN/0596007795">Tom Stafford & Matt Webb, "Mind Hacks"</a>]</span>
<p>
Started reading <a href="http://www.amazon.co.uk/exec/obidos/ASIN/0596007795">"Mind Hacks"</a>, which looked
interesting in the bookshop but <span style='color:green'>the formatting</span> is already starting to annoy
me. <span style='color:green'>In that respect</span>,
it's the worst book-<span style='color:green'>that's-just-a-printout</span>-of-a-cool-website ever,
and that's up against some pretty stiff competition.
</p>
<ul>
<li>A large fraction of the hacks refer the reader off to movie files or Flash animations on the web. Not
very helpful for a physical book that you might want to read on a train.</li>
<li>"<i>Color: The second color is used to indicate a cross-reference within the text</i>". Except that there is
no second color—the relevant parts just come out in a hard-to-read light gray.</li>
<li>The <a href="http://en.wikipedia.org/wiki/Halftone">halftoning</a> for photographs and some of the
diagrams is poor—it looks like the output of an 1980's laserprinter.</li>
<li>I don't know what system they used to produce the book, but it's generated some real oddities in
linebreaking (mostly around URLs). Favourite so far: a line break after the decimal point in "3.3"
(page 144).</li>
</ul>
<p>Still, the content might be OK once I get into it, and at least they include lots of references to the original
literature.</p>
<p>
<span style='color:green'>[25-Nov-06] Edited to clarify that I'm complaining about the formatting rather
than the content. Feeling slightly guilty given that one of the
<a href="http://interconnected.org/home/">authors</a> came over and
<a href="http://www.blogger.com/comment.g?blogID=13187319&postID=116410316521815396">commented</a>. You'd
think I'd have learnt my
<a href="http://www.lurklurk.org/vent/google.html">lesson</a> about who finds what on tha intarweb.</span>
</p>
<p><span style='font-size:10px;'>[A:37385 B:3278 C:346 D:9187 E:34361 Total:84557]</span>
</p>Unknownnoreply@blogger.com2tag:blogger.com,1999:blog-13187319.post-1163174063121198372006-11-09T15:53:00.000+00:002006-11-10T15:54:23.196+00:00One Year In<span style='font-size:10px;'>[<b>reading:</b>
<a href="http://www.amazon.co.uk/exec/obidos/ASIN/057110813X">Seamus Heaney, "North"</a>]</span>
<p>
Just noticed: it's
<a href="http://copiousfreetime.blogspot.com/2005/11/day-190.html">a year</a>
since the original idea for the <a href="http://www.workingprogram.com">company</a>.
</p>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-13187319.post-1155890894218024622006-08-17T18:34:00.000+01:002007-09-19T08:13:43.459+01:00The Truth Mines<span style='font-size:10px;'><i>
<p>
In the Truth Mines, though, the tags weren't just references; they included
complete statements of the particular definitions, axioms, or theorems the objects
represented.
</p><p>
Every tunnel in the Mines was built from the steps of a watertight proof; every theorem, however deeply
buried, could be traced back to every one of its assumptions. And to pin down exactly what was meant by
'proof', every field of mathematics used its own collection of formal systems: sets of axioms, definitions,
and rules of deduction, along with the specialised vocabulary needed to state theorems and conjectures
precisely.<sup>*</sup>
</p></i></span>
<p>
I came across a cool <a href="http://us.metamath.org/mpegif/mmset.html">maths site</a>
today (via <a href="http://scienceblogs.com/goodmath/">Good Math, Bad Math</a>).
I'd actually been thinking about doing it myself for the last few years, but it always
looked a bit too much like hard work (even when I had Copious Free Time), so I never
quite got around to it.
</p><p>
It's kind of eerie, though—the proof pages are almost exactly
like the ones I'd mocked up and had in my head when I was playing with the project
(although less XML/<a href="http://www.lurklurk.org/maxima.html">MathML</a>-y).
I guess there aren't really that many different ways you could present it, but it does
feel like some sort of
<a href="http://www.venganza.org/">noodly appendage</a>
has sucked the idea right out of my head and served it up as a completed web page
(conveniently skipping the tedious business of doing all the work).
</p><hr/><p>
<span style='font-size:11px'><b>*</b>
<a href="http://gregegan.customer.netspace.net.au/">Greg Egan</a>, "Diaspora", 1997</span>
</p>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-13187319.post-1149854478912808352006-06-09T16:00:00.000+01:002006-06-09T16:14:56.853+01:00How do I exit thee? Let me count the ways<span style='font-size:10px;'>[<b>reading:</b>
<a href="http://www.amazon.co.uk/exec/obidos/ASIN/0349113157">Tom Holt, "Alexander at the World's End"</a>]</span>
<p>
Today I've been trying to sort out the interactions between the various different mechanisms for
generating and catching errors in Windows. With the help of a
<a type="text/plain" href="http://www.lurklurk.org/exittest.cpp">noddy test program</a>, I ended up with:
</p>
<table rules='all' frame='box' width='650px' style='font-size:10px;'>
<tr>
<th>Type</th>
<th width='20%'>No handler</th>
<th><code>atexit</code></th>
<th><code>signal</code></th>
<th><code>catch (...)</code></th>
<th><code>set_<wbr/>terminate</code></th>
<th><code>__except (EXCEPTION_<wbr/>EXECUTE_<wbr/>HANDLER)</code></th>
<th><code>__except (EXCEPTION_<wbr/>CONTINUE_<wbr/>EXECUTION)</code></th>
<th><code>Set<wbr/>Unhandled<wbr/>Exception<wbr/>Filter</code></th>
</tr>
<tr>
<th><code>exit(0)</code></th>
<td>No message</td>
<td>Hit</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<th><code>abort()</code></th>
<td>Visual C++ Runtime Error dialog</td>
<td></td>
<td>Hit (<code>SIGABRT</code>)</td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<th><code>c=*(char*)0</code></th>
<td>'Encountered a problem and needs to close' dialog</td>
<td></td>
<td>Hit (<code>SIGSEGV</code>)</td>
<td>Hit</td>
<td></td>
<td>Hit</td>
<td>Hit, generates infinite loop</td>
<td>Hit</td>
</tr>
<tr>
<th><code>i=1/0</code></th>
<td>'Encountered a problem and needs to close' dialog</td>
<td></td>
<td></td>
<td>Hit</td>
<td></td>
<td>Hit</td>
<td>Hit, generates infinite loop</td>
<td>Hit</td>
</tr>
<tr>
<th><code>raise()</code></th>
<td>No message</td>
<td></td>
<td>Hit, execution continues from the <code>raise</code></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<th><code>throw</code></th>
<td>Visual C++ Runtime Error dialog</td>
<td></td>
<td></td>
<td>Hit</td>
<td>Hit</td>
<td></td>
<td></td>
<td>Hit</td>
</tr>
<tr>
<th><code>RaiseException(<wbr/>0xE0000001,<wbr/>EXCEPTION_<wbr/>NONCONTINUABLE, 0, NULL)</code></th>
<td>'Encountered a problem and needs to close' dialog</td>
<td></td>
<td></td>
<td>Hit</td>
<td></td>
<td>Hit</td>
<td>Hit</td>
<td>Hit</td>
</tr>
<tr>
<th><code>RaiseException(<wbr/>0xE0000001, 0, 0, NULL)</code></th>
<td>'Encountered a problem and needs to close' dialog</td>
<td></td>
<td></td>
<td>Hit</td>
<td></td>
<td>Hit</td>
<td>Hit, execution continues from the <code>RaiseException</code></td>
<td>Hit</td>
</tr>
</table>
<p>
Other key points to note:
</p>
<ul>
<li>All catchers only see errors from the same thread, with the exception of the SEH unhandled exception
filter set by <code>SetUnhandledExceptionFilter()</code>.</li>
<li>For (say) a null dereference, the order that various handlers get to see things is:</li>
<ul>
<li>Vectored Exception Handler
(<a href="http://msdn.microsoft.com/library/en-us/debug/base/vectored_exception_handling.asp">VEH</a>)</li>
<li>C++ exception handler or Structured Exception Handler (SEH), whichever has the narrower enclosing
scope</li>
<li><code>SIGSEGV</code> signal handler <code>/* FALLTHRU */</code></li>
<li>SEH unhandled exception filter installed by <code>SetUnhandledExceptionFilter</code></li>
<li>C++ unhandled exception handler installed by <code>set_terminate</code></li>
</ul>
<li>I've no idea why a null dereference does appear as a C++ exception in a <code>catch (...)</code> block, but
<i>doesn't</i> hit the unhandled-C++-exception-handler installed by <code>set_terminate</code>.</li>
</ul>Unknownnoreply@blogger.com1tag:blogger.com,1999:blog-13187319.post-1149324463015737902006-06-03T09:47:00.000+01:002006-06-09T16:11:20.730+01:00Plenty Of BloodFinally getting around to booking
<a href="http://copiousfreetime.blogspot.com/2005/12/day-236.html">Titus Andronicus</a>
at the <a href="http://www.shakespeares-globe.org">Globe</a>, so here's
your cut-out-and-keep<sup>*</sup> guide to Shakespeare's
<a href="http://news.bbc.co.uk/1/hi/entertainment/5042516.stm">bloodiest</a> play:<br/>
<a href="http://www.lurklurk.org/TitusTree.gif"><img src="http://www.lurklurk.org/TitusTree.gif" alt="Titus Andronicus"></a>
</p><hr/><p>
<span style='font-size:11px'><b>*</b>OK, not really.</span>
</p>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-13187319.post-1144692146482206992006-04-10T19:02:00.000+01:002007-11-07T18:32:48.602+00:00Day 342<span style='font-size:10px;'>[<b>reading:</b>
<a href="http://www.amazon.co.uk/exec/obidos/ASIN/0919359086">Dave Sim, "Cerebus"</a>]</span>
<p>
[Edit 7-Nov-2007: I've since found a couple of
<a href="http://www.kenrockwell.com/tech/syncspeed.htm">good</a>
<a href="http://photo.net/bboard/q-and-a-fetch-msg?msg_id=00LWfz">explanations</a>.]
</p>
<p>
In my photography course yesterday, I found myself explaining how flash sync speeds work. To my surprise,
there doesn't seem to be an easily-<a href="http://www.google.com">googleable</a> explanation online, so I
though it might be worth writing up:
</p><hr/><p>
The flash sync speed for a camera is the fastest shutter speed you can set and still use flash. It varies
from camera to camera: more recent and more expensive cameras are faster, older cameras are slower (and often
have the sync speed helpfully marked in red on the speed dial). If you try to use a shutter speed that's
faster than the sync speed you end up with pictures like this:
</p><p>
<a href="http://www.flickr.com/photos/90388579@N00/126478356/"><img src="http://static.flickr.com/49/126478356_c09af13f87.jpg" width="500" height="333" alt="sync" /></a>
</p><p>
So what goes wrong?
</p><p>
The first thing to understand is how the camera's shutter works. If you could slow down time, you'd see a
sequence like this:
</p><p>
<a href="http://www.flickr.com/photos/90388579@N00/126486204/"><img src="http://static.flickr.com/1/126486204_3a304cf617.jpg" width="500" height="177" alt="60" /></a>
</p><p>
There are two shutter curtains that pass down the frame from top to bottom. This first opens things up to
light, and the second closes it again. As the shutter speed gets faster, we reach a point where the
shutter never completely opens during the sequence:
</p><p>
<a href="http://www.flickr.com/photos/90388579@N00/126928132/"><img src="http://static.flickr.com/44/126928132_4fc9b2f500.jpg" width="500" height="185" alt="250" /></a>
</p><p>
Each area of the frame is exposed for the same amount of time (because both shutter curtains move at the same
speed), but the top and bottom parts of the frame aren't exposed at the <i>same</i> time.
</p><p>
The second thing to realize is that flash is very fast—much faster than the fastest shutter speed on the
camera, maybe 1/16,000 to 1/50,000 of a second. Revisiting our two sequence diagrams:
</p><p>
<a href="http://www.flickr.com/photos/90388579@N00/126486205/"><img src="http://static.flickr.com/51/126486205_062f2ad49d.jpg" width="500" height="180" alt="60flash" /></a>
</p><p>
At this speed, everything is fine. The flash triggers and illuminates the whole of the image. At the faster speed,
problems arise:
</p><p>
<a href="http://www.flickr.com/photos/90388579@N00/126486207/"><img src="http://static.flickr.com/45/126486207_266258e55e.jpg" width="500" height="185" alt="250flash" /></a>
</p><p>
If we think of the flash as being effectively instantaneous, then because there is no moment where the whole
of the frame is exposed at once, there's no moment when the flash could fire and illuminate the whole
of the scene. This also explains the sort of problems that occur in the final image:
<ul>
<li>Dark bar at the top of the frame (illustrated above): the camera has triggered the flash when the first
shutter curtain reaches the bottom of the frame, but the second curtain is already obscuring the top of the
image.</li>
<li>Dark bar at the bottom of the frame: the camera has triggered the flash when the second shutter curtain
is about to start at the top of the frame, but the first curtain has not yet exposed the whole of the
bottom of the image.</li>
</ul>
<span style='font-size:10px'>Model: Bernard T.
<a href="http://copiousfreetime.blogspot.com/2006/03/day-307.html">Bonsai</a>.
</span>
</p><hr/><p>
And in other news, we've now had our first directors meeting for the
<a href="http://www.workingprogram.com">new company</a>.
</p>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-13187319.post-1143470362885740822006-03-27T15:39:00.000+01:002006-03-27T15:42:23.410+01:00Day 328A <a href="http://www.badpuns.com/jokes.php?section=shaggy&name=trifle">trifle bizarre</a>. After a bunch of
investigation, I eventually narrowed down a synchronization problem to the following mini test program:
<blockquote><pre>
#include <time.h>
#include <stdio.h>
int main()
{
time_t tv = time(NULL);
struct tm *tms = localtime(&tv);
printf("%02d:%02d:%02d DST:%d\n",
tms->tm_hour, tms->tm_min,
tms->tm_sec, tms->tm_isdst);
}
</pre></blockquote>
When I ran on Mac OS X:
<blockquote><pre>
~:<b>date</b>
Mon Mar 27 14:12:29 BST 2006
~:<b>a.out</b>
14:12:30 DST:1
</pre></blockquote>
But when I ran on my main Windows XP box:
<blockquote><pre>
c:\><b>time /t</b>
14:13
c:\><b>localtime.exe</b>
13:13:03 DST:0
</pre></blockquote>
Now, I'm usually happy to believe the worst of Microsoft, but it stretches even my credibility to think that
their C runtime doesn't get the 1989 ANSI standard right (particularly as a quick web search didn't turn up
any complaints).
</p><p>
Investigating further, when I ran the same code on a different Windows XP machine, I get the right answer:
<blockquote><pre>
c:\><b>time /t</b>
14:15
c:\><b>localtime.exe</b>
14:15:24 DST:0
</pre></blockquote>
</p><p>
So I checked <a href="http://msdn.microsoft.com">MSDN</a> and found some
<a href="http://msdn.microsoft.com/library/en-us/vccore98/HTML/_crt_localtime.asp">mutterings</a> about
"localtime corrects for the local time zone if the user first sets the global environment variable TZ...TZ is
a Microsoft extension and not part of the ANSI standard definition of localtime. Note: The target environment
should try to determine whether daylight saving time is in effect."
</p><p>
Running <code><b>echo %TZ%</b></code> from the command line showed up as <code>GMT</code>. So I tried
changing the timezone to EST, but <code><b>echo %TZ%</b></code> was still reading <code>GMT</code>. Odd.
</p><p>
Eventually, I discovered that my login had <code>TZ=GMT</code> hard-coded into the environment (Control Panel,
System, Advanced, Environment Variables). Not sure how it got that way, but finding it and making it not so
has just taken a couple of hours.
</p>
<p><span style='font-size:10px;'>[A:35029 B:3218 C:346 D:9187 Total:47780]</span>
</p>Unknownnoreply@blogger.com0tag:blogger.com,1999:blog-13187319.post-1121502262969685972005-07-16T09:24:00.000+01:002005-07-16T09:24:22.973+01:00Day 74<font size="-1">[<b>reading:</b> Scott Meyers, "Effective C++ (3rd edn.)"]</font>
<p>
I'm reading "Effective C++" again, with the publication of a new edition, and I'm struck by an observation. It's
startling how much of the advice in early parts of the book boils down to: Understand how the compiler works. (Items 2,
4, 5, 7, 9, 10, 16 and 17 out of 18 so far)
</p><p>
This is an approach that I've got a <a href="http://www.lurklurk.org/linkers/linkers.html">lot of sympathy with</a>; I
really got to grips with Microsoft Word when I stopped
observing the phenomonology of its peculiar behaviour, and instead sat down for half an hour to think about how it
might be implemented internally. After that (even though I'm sure I didn't even get close to the true internals), I
could cope with and predict the vagaries of the program much more effectively.
</p><p>
However, it does seem to me that one of the points of higher-level computer languages is so that programmers <i>don't</i> have
to understand the details of the implementation. I guess if you just memorize the Effective C++ items and forget
their explanations, then you can achieve that blissful state of ignorance—but it's safer and better to know the why
and the how, which is why Scott's books sell so well.
</p><p>
But this does lead back to my underlying concern: that C++ is too complicated for mere mortal programmers. All of the
individual features are there for a good reason, but taken as a whole the language is too big. A
top-flight C++ programmer pretty much needs to know the whole of:
<ul>
<li><a href="http://www.amazon.co.uk/exec/obidos/ASIN/0201889544">Bjarne Stroustrup: C++ Programming Language (868 pages)</a></li>
<li><a href="http://www.amazon.co.uk/exec/obidos/ASIN/0321334876">Scott Meyers: Effective C++ (272 pages)</a></li>
<li><a href="http://www.amazon.co.uk/exec/obidos/ASIN/0201379260">Josuttis: The C++ Standard Library (744 pages)</a></li>
</ul>
That's 1884 pages in total. Even <a href="http://www.amazon.co.uk/exec/obidos/ASIN/0131524143">Common Lisp: The
Language</a> only weighs in at 971 pages.
</p><p>
I just about trust myself to write C++, but that's only because I know I'll avoid the parts of C++ that I don't
understand fully. I've only ever met half a dozen people that I'd completely trust to write C++ (one of them being
<a
href="http://www.awprofessional.com/content/downloads/meyerscddemo/DEMO/INTRO/IN_DIR.HTM#dingp78">Scott</a>),
which makes for a hard time supporting C++ code.
</p>Unknownnoreply@blogger.com0