Uszla http://uszla.me.uk Toby White's thoughts - Fortran, XML, Python, and scientific data representation CC Attribution-NonCommercial-NoDerivs 3.0 30 Thu, 11 Mar 2010 00:50:10 GMT Thu, 11 Mar 2010 00:50:10 GMT http://blogs.law.harvard.edu/tech/rss yaki CloudCamb http://feedproxy.google.com/~r/Uszla/blog/~3/3vTscFtrtBw/24 <div class="para"><p>I've put up a (heavily-edited) <a href="http://uszla.me.uk/space/essays/CloudCamb" title="external link to http://uszla.me.uk/space/essays/CloudCamb" class="http">transcript</a> of my <a href="http://cloudcamb.org" title="external link to http://cloudcamb.org" class="http">CloudCamb</a> talk for anyone interested.</p></div> <br/><small><a href="http://uszla.me.uk/space/blog/2008/12/24" title="link to http://uszla.me.uk/space/blog/2008/12/24">@</a></small> Wed, 24 Dec 2008 15:16:32 GMT Toby White Uszla blog http://uszla.me.uk/space/blog/2008/12/24 http://uszla.me.uk/space/blog/2008/12/24 Revisiting Erlang http://feedproxy.google.com/~r/Uszla/blog/~3/Il1vAkD4R70/22 <div class="para"><p>I've put up a (heavily-edited) <a href="http://uszla.me.uk/space/essays/CloudCamb" title="external link to http://uszla.me.uk/space/essays/CloudCamb" class="http">transcript</a> of my <a href="http://cloudcamb.org" title="external link to http://cloudcamb.org" class="http">CloudCamb</a> talk for anyone interested.</p></div> <div class="para"><p>The first substantive exercise is:</p></div> <div class="quoteblock"> <div class="quoteblock-content"> <div class="para"><p>Write a ring benchmark. Create N processes in a ring. Send a message round the ring M times so that a total of N * M messages get sent. Time how long this takes for different values of N and M.</p></div> <div class="para"><p>Write a similar program in some other programming language you are familiar with. Compare the results. Write a blog, and publish the results on the internet!</p></div> </div> <div class="quoteblock-attribution"> <em>Programming Erlang</em><br /> — Joe Armstrong </div></div> <div class="para"><p>No benchmarking or comparison, I'm afraid, but here's my solution.</p></div> <div class="listingblock"> <div class="content"> <pre> <span class="htmlfontify-function-name">ringfun</span>(<span class="htmlfontify-variable-name">_</span>, 0) <span class="htmlfontify-function-name">-&gt;</span> ok; <span class="htmlfontify-function-name">ringfun</span>(<span class="htmlfontify-variable-name">Pid</span>, <span class="htmlfontify-variable-name">Times</span>) <span class="htmlfontify-function-name">-&gt;</span> <span class="htmlfontify-keyword">receive</span> next <span class="htmlfontify-function-name">-&gt;</span> io:format(<span class="htmlfontify-string">&quot;Pid ~p sending message ~p~n&quot;</span>, [<span class="htmlfontify-keyword">self</span>(), <span class="htmlfontify-variable-name">Times</span>]), <span class="htmlfontify-variable-name">Pid</span> ! next, ringfun(<span class="htmlfontify-variable-name">Pid</span>, <span class="htmlfontify-variable-name">Times</span>-1); <span class="htmlfontify-variable-name">Pid2</span> <span class="htmlfontify-function-name">-&gt;</span> ringfun(<span class="htmlfontify-variable-name">Pid2</span>, <span class="htmlfontify-variable-name">Times</span>) <span class="htmlfontify-keyword">end</span>. <span class="htmlfontify-function-name">ring</span>(<span class="htmlfontify-variable-name">N</span>, <span class="htmlfontify-variable-name">M</span>) <span class="htmlfontify-keyword">when</span> <span class="htmlfontify-variable-name">N</span>&gt;1, <span class="htmlfontify-variable-name">M</span>&gt;=1 <span class="htmlfontify-function-name">-&gt;</span> <span class="htmlfontify-variable-name">FirstPid</span> = <span class="htmlfontify-keyword">spawn</span>(<span class="htmlfontify-keyword">fun</span>() <span class="htmlfontify-function-name">-&gt;</span> ringfun(ok, <span class="htmlfontify-variable-name">M</span>) <span class="htmlfontify-keyword">end</span>), <span class="htmlfontify-variable-name">FirstPid</span> ! lists:foldl(<span class="htmlfontify-keyword">fun</span>(<span class="htmlfontify-variable-name">_</span>, <span class="htmlfontify-variable-name">Pid</span>) <span class="htmlfontify-function-name">-&gt;</span> <span class="htmlfontify-keyword">spawn</span>(<span class="htmlfontify-keyword">fun</span>() <span class="htmlfontify-function-name">-&gt;</span> ringfun(<span class="htmlfontify-variable-name">Pid</span>, <span class="htmlfontify-variable-name">M</span>) <span class="htmlfontify-keyword">end</span>) <span class="htmlfontify-keyword">end</span>, <span class="htmlfontify-variable-name">FirstPid</span>, lists:seq(1, <span class="htmlfontify-variable-name">N</span>-1)), <span class="htmlfontify-variable-name">FirstPid</span> ! next, ok.</pre></div></div> <div class="para"><p>The version above had no timing information. It also didn't communicate back to the parent process that the messages had finished circulating. These two issues were related (since the parent process needs to know when to stop timing. And the final time needs to be calculated on the final process in case the child processes have a different notion of time.) So the updated version below fixes both these issues:</p></div> <div class="listingblock"> <div class="content"> <pre> <span class="htmlfontify-function-name">ringfun</span>(<span class="htmlfontify-variable-name">_</span>, 0, ok) <span class="htmlfontify-function-name">-&gt;</span> ok; <span class="htmlfontify-function-name">ringfun</span>(<span class="htmlfontify-variable-name">_</span>, 0, <span class="htmlfontify-variable-name">ParentPid</span>) <span class="htmlfontify-function-name">-&gt;</span> <span class="htmlfontify-variable-name">ParentPid</span> ! done; <span class="htmlfontify-function-name">ringfun</span>(<span class="htmlfontify-variable-name">NextPid</span>, <span class="htmlfontify-variable-name">Times</span>, <span class="htmlfontify-variable-name">ParentPid</span>) <span class="htmlfontify-function-name">-&gt;</span> <span class="htmlfontify-keyword">receive</span> next <span class="htmlfontify-function-name">-&gt;</span> <span class="htmlfontify-variable-name">NextPid</span> ! next, ringfun(<span class="htmlfontify-variable-name">NextPid</span>, <span class="htmlfontify-variable-name">Times</span>-1, <span class="htmlfontify-variable-name">ParentPid</span>); <span class="htmlfontify-variable-name">NewPid</span> <span class="htmlfontify-function-name">-&gt;</span> ringfun(<span class="htmlfontify-variable-name">NewPid</span>, <span class="htmlfontify-variable-name">Times</span>, <span class="htmlfontify-variable-name">ParentPid</span>) <span class="htmlfontify-keyword">end</span>. <span class="htmlfontify-function-name">ring</span>(<span class="htmlfontify-variable-name">N</span>, <span class="htmlfontify-variable-name">M</span>) <span class="htmlfontify-keyword">when</span> <span class="htmlfontify-variable-name">N</span>&gt;1, <span class="htmlfontify-variable-name">M</span>&gt;0 <span class="htmlfontify-function-name">-&gt;</span> <span class="htmlfontify-variable-name">S</span> = <span class="htmlfontify-keyword">self</span>(), <span class="htmlfontify-variable-name">FirstPid</span> = <span class="htmlfontify-keyword">spawn</span>(<span class="htmlfontify-keyword">fun</span>() <span class="htmlfontify-function-name">-&gt;</span> ringfun(ok, <span class="htmlfontify-variable-name">M</span>, <span class="htmlfontify-variable-name">S</span>) <span class="htmlfontify-keyword">end</span>), <span class="htmlfontify-variable-name">FirstPid</span> ! lists:foldl(<span class="htmlfontify-keyword">fun</span>(<span class="htmlfontify-variable-name">_</span>, <span class="htmlfontify-variable-name">Pid</span>) <span class="htmlfontify-function-name">-&gt;</span> <span class="htmlfontify-keyword">spawn</span>(<span class="htmlfontify-keyword">fun</span>() <span class="htmlfontify-function-name">-&gt;</span> ringfun(<span class="htmlfontify-variable-name">Pid</span>, <span class="htmlfontify-variable-name">M</span>, ok) <span class="htmlfontify-keyword">end</span>) <span class="htmlfontify-keyword">end</span>, <span class="htmlfontify-variable-name">FirstPid</span>, lists:seq(1, <span class="htmlfontify-variable-name">N</span>-1)), <span class="htmlfontify-variable-name">T1</span> = erlang:now(), <span class="htmlfontify-variable-name">FirstPid</span> ! next, <span class="htmlfontify-keyword">receive</span> done <span class="htmlfontify-function-name">-&gt;</span> <span class="htmlfontify-variable-name">T2</span> = erlang:now() <span class="htmlfontify-keyword">end</span>, <span class="htmlfontify-variable-name">Tdiff</span> = timer:now_diff(<span class="htmlfontify-variable-name">T2</span>, <span class="htmlfontify-variable-name">T1</span>)/1000000, io:format(<span class="htmlfontify-string">&quot;Sent ~p messages around a ring of length ~p in ~p seconds~n&quot;</span>, [<span class="htmlfontify-variable-name">M</span>, <span class="htmlfontify-variable-name">N</span>, <span class="htmlfontify-variable-name">Tdiff</span>]).</pre></div></div> <div class="para"><p>and a quick proof from the pudding:</p></div> <div class="listingblock"> <div class="content"> <pre> 13&gt; chapter8:ring(3000,3000). Sent 3000 messages around a ring of length 3000<span class="htmlfontify-keyword"> in</span> 10.3243 seconds ok</pre></div></div> <br/><small><a href="http://uszla.me.uk/space/blog/2008/12/22" title="link to http://uszla.me.uk/space/blog/2008/12/22">@</a></small> Wed, 24 Dec 2008 12:45:32 GMT Toby White Uszla blog http://uszla.me.uk/space/blog/2008/12/22 http://uszla.me.uk/space/blog/2008/12/22 Two quick git tricks http://feedproxy.google.com/~r/Uszla/blog/~3/R-ly9Zc3LoE/18 <h2 id="_a_handy_oneliner_2">A handy oneliner</h2> <div class="sectionbody"> <div class="para"><p>To retrieve the contents of a file from a different branch without affecting your current git state:</p></div> <div class="listingblock"> <div class="content"> <pre> git show <span class="htmlfontify-string">`git rev-parse $BRANCH_NAME:$FILE_PATH`</span></pre></div></div> </div> <h2 id="_creating_full_git_history_from_release_tarballs_2">Creating full git history from release tarballs</h2> <div class="sectionbody"> <div class="para"><p>Given a set of tar-balls from a project whose version control is not exposed to the public:</p></div> <div class="listingblock"> <div class="content"> <pre> toby-whites-macbook:python-memcached tow$ ls /Volumes/ftp.tummy.com/old-releases/*.tar.gz /Volumes/ftp.tummy.com/old-releases/python-memcached-1.2.tar.gz /Volumes/ftp.tummy.com/old-releases/python-memcached-1.2_tummy1.tar.gz /Volumes/ftp.tummy.com/old-releases/python-memcached-1.2_tummy2.tar.gz /Volumes/ftp.tummy.com/old-releases/python-memcached-1.2_tummy3.tar.gz /Volumes/ftp.tummy.com/old-releases/python-memcached-1.2_tummy4.tar.gz /Volumes/ftp.tummy.com/old-releases/python-memcached-1.2_tummy5.tar.gz /Volumes/ftp.tummy.com/old-releases/python-memcached-1.2_tummy6.tar.gz /Volumes/ftp.tummy.com/old-releases/python-memcached-1.31.tar.gz /Volumes/ftp.tummy.com/old-releases/python-memcached-1.32.tar.gz /Volumes/ftp.tummy.com/old-releases/python-memcached-1.33.tar.gz /Volumes/ftp.tummy.com/old-releases/python-memcached-1.34.tar.gz /Volumes/ftp.tummy.com/old-releases/python-memcached-1.36.tar.gz /Volumes/ftp.tummy.com/old-releases/python-memcached-1.37.tar.gz /Volumes/ftp.tummy.com/old-releases/python-memcached-1.38.tar.gz /Volumes/ftp.tummy.com/old-releases/python-memcached-1.39.tar.gz /Volumes/ftp.tummy.com/old-releases/python-memcached-1.40.tar.gz /Volumes/ftp.tummy.com/old-releases/python-memcached-1.41.tar.gz /Volumes/ftp.tummy.com/old-releases/python-memcached-1.42.tar.gz /Volumes/ftp.tummy.com/old-releases/python-memcached-1.43.tar.gz</pre></div></div> <div class="para"><p>We can turn this into a git repository with full version history fairly easily:</p></div> <div class="listingblock"> <div class="content"> <pre> <span class="htmlfontify-variable-name">PROJECT</span>=python-memcached mkdir $<span class="htmlfontify-variable-name">PROJECT</span> ( <span class="htmlfontify-builtin">cd</span> $<span class="htmlfontify-variable-name">PROJECT</span> git init git commit --allow-empty -m <span class="htmlfontify-string">&quot;Empty repo&quot;</span> ) <span class="htmlfontify-keyword">for</span> i<span class="htmlfontify-keyword"> in</span> $<span class="htmlfontify-variable-name">PROJECT</span>*.tar.gz; <span class="htmlfontify-keyword">do</span> <span class="htmlfontify-variable-name">vntgz</span>=${<span class="htmlfontify-variable-name">i</span>#$<span class="htmlfontify-variable-name">PROJECT</span>-} <span class="htmlfontify-variable-name">vn</span>=${<span class="htmlfontify-variable-name">vntgz</span>%%.tar.gz} <span class="htmlfontify-builtin">echo</span> $<span class="htmlfontify-variable-name">vn</span> tar xzf $<span class="htmlfontify-variable-name">i</span> mv $<span class="htmlfontify-variable-name">PROJECT</span>/.git $<span class="htmlfontify-variable-name">PROJECT</span>-$<span class="htmlfontify-variable-name">vn</span> ( <span class="htmlfontify-builtin">cd</span> $<span class="htmlfontify-variable-name">PROJECT</span>-$<span class="htmlfontify-variable-name">vn</span> find . -name <span class="htmlfontify-string">'.git'</span> -prune -o -exec git update-index --add --remove {} <span class="htmlfontify-string">\;</span> git commit -m $<span class="htmlfontify-variable-name">vn</span> ) mv $<span class="htmlfontify-variable-name">PROJECT</span>-$<span class="htmlfontify-variable-name">vn</span>/.git $<span class="htmlfontify-variable-name">PROJECT</span> <span class="htmlfontify-keyword">done</span></pre></div></div> <div class="para"><p>For re-use, you might need to play around with some of the substring matching to get the right naming conventions for another project.</p></div> <div class="para"><p>You don't get a useful Changelog, but now you can do <tt>git bisect</tt> tricks and the like.</p></div> </div> <br/><small><a href="http://uszla.me.uk/space/blog/2008/11/18" title="link to http://uszla.me.uk/space/blog/2008/11/18">@</a></small> Tue, 18 Nov 2008 11:13:57 GMT Toby White Uszla blog http://uszla.me.uk/space/blog/2008/11/18 http://uszla.me.uk/space/blog/2008/11/18 Python anonymous classes http://feedproxy.google.com/~r/Uszla/blog/~3/w7AlN0RrPCo/06 <div class="para"><p>This post is as much to remind me of how to do this as anything else.</p></div> <div class="para"><p>I sometimes find myself wanting anonymous classes; essentially, I want to be able to have objects which are just bags of properties. Clearly you can get most of this behaviour from a dictionary:</p></div> <div class="listingblock"> <div class="content"> <pre> anon_object_0 = {}</pre></div></div> <div class="para"><p>and then assign properties as dictionary entries:</p></div> <div class="listingblock"> <div class="content"> <pre> anon_object_0[<span class="htmlfontify-string">'property'</span>] = 1</pre></div></div> <div class="para"><p>But, in my head at least, there is a difference in intent when manipulating a dictionary, and when manipulating an object with properties, and sometimes I want to explicitly be using an object, with property-accessor syntax.</p></div> <div class="para"><p>It's also useful to be able to generate things that behave like objects, for driving interfaces which expect objects of a certain type; that is, "mock objects", thought that term means different things to different people. (and there are <a href="http://pypi.python.org/pypi/MiniMock/1.0" title="external link to http://pypi.python.org/pypi/MiniMock/1.0" class="http">Python libraries</a> for those already). That use case is most often seen in testing, but I've needed it in production code occasionally.</p></div> <div class="para"><p>So usually, when I want anonymous objects, I want to be able to set them up trivially; I don't want to pull in a library, nor do I want a lengthy definition - one line is verging on too much already.</p></div> <div class="para"><p>There's basically two ways to create useful anonymous classes in Python.</p></div> <div class="para"><p>The obvious way is just:</p></div> <div class="listingblock"> <div class="content"> <pre> <span class="htmlfontify-keyword">class</span> <span class="htmlfontify-type">Anonymous</span>(object): <span class="htmlfontify-keyword">pass</span></pre></div></div> <div class="para"><p>Thereafter you can do:</p></div> <div class="listingblock"> <div class="content"> <pre> anon_object_1 = Anonymous() anon_object_1.property = 1</pre></div></div> <div class="para"><p>My preferred way takes advantage of the python <a href="http://docs.python.org/library/functions.html#type" title="external link to http://docs.python.org/library/functions.html#type" class="http">type constructor</a>; this creates an anonymous class:</p></div> <div class="listingblock"> <div class="content"> <pre> <span class="htmlfontify-py-builtins-face">type</span>(<span class="htmlfontify-string">&quot;&quot;</span>, (), {})</pre></div></div> <div class="para"><p>and this, of course, creates an instance:</p></div> <div class="listingblock"> <div class="content"> <pre> anon_object_2 = <span class="htmlfontify-py-builtins-face">type</span>(<span class="htmlfontify-string">&quot;&quot;</span>, (), {})()</pre></div></div> <div class="para"><p>which I prefer to the first. Firstly, it genuinely is a one-liner to define an anonymous object, I don't have to worry about the anonymous class per se; and secondly, for the relatively unimportant reason that</p></div> <div class="listingblock"> <div class="content"> <pre> &gt;&gt;&gt; anon_object_1 &lt;__main__.Anonymous <span class="htmlfontify-py-builtins-face">object</span> at 0x6f8b0&gt; &gt;&gt;&gt; <span class="htmlfontify-py-builtins-face">type</span>(anon_object_1) &lt;<span class="htmlfontify-keyword">class</span> <span class="htmlfontify-string">'__main__.Anonymous'</span>&gt; &gt;&gt;&gt; anon_object_2 &lt;__main__. object at 0x6f8f0&gt; &gt;&gt;&gt; <span class="htmlfontify-py-builtins-face">type</span>(anon_object_2) &lt;<span class="htmlfontify-keyword">class</span> <span class="htmlfontify-string">'__main__.'</span>&gt;</pre></div></div> <div class="para"><p>The first contains a reference to the name of its defining class, so is not exactly anonymous; and it's invaded your namespace a little. Largely in an unimportant way, since you can re-use that part of your namespace easily enough, but this is true:</p></div> <div class="listingblock"> <div class="content"> <pre> &gt;&gt;&gt; <span class="htmlfontify-string">'Anonymous'</span> <span class="htmlfontify-keyword">in</span> <span class="htmlfontify-py-builtins-face">globals</span>() <span class="htmlfontify-py-pseudo-keyword-face">True</span></pre></div></div> <div class="para"><p>where it wasn't before.</p></div> <div class="para"><p>An interesting variation of the first way can be seen in Peter Norvig's <a href="http://norvig.com/python-iaq.html" title="external link to http://norvig.com/python-iaq.html" class="http">Python Infrequently Asked Questions</a> - he has a "Struct" class, which has a series of useful methods which help with initialization and update of arbitrary properties.</p></div> <br/><small><a href="http://uszla.me.uk/space/blog/2008/11/06" title="link to http://uszla.me.uk/space/blog/2008/11/06">@</a></small> Thu, 06 Nov 2008 11:50:49 GMT Toby White Uszla blog http://uszla.me.uk/space/blog/2008/11/06 http://uszla.me.uk/space/blog/2008/11/06 Testing with nose, or why setuptools is annoying. http://feedproxy.google.com/~r/Uszla/blog/~3/TKjLOCYcTPs/19 <div class="para"><p>I use <a href="http://somethingaboutorange.com/mrl/projects/nose/" title="external link to http://somethingaboutorange.com/mrl/projects/nose/" class="http">nose</a> for my Python tests. It's not the only Python testing framework out there, but it seems to fit my needs.</p></div> <div class="sidebarblock"> <div class="sidebar-content"> <div class="sidebar-title">Doctest discovery</div> <div class="para"><p>I started using it mainly because test discovery for doctests seems to be far harder to arrange than it ought to be. There's no point in me evangelizing doctests more than has been adequately done before, but it's far too hard to arrange to run all doctests within a project, which rather defeats their purpose. nose seems to manage it perfectly well without trying.)</p></div> </div></div> <div class="para"><p>Anyway; so nose has this concept of plugins, which let you extend test discovery , or add extra fixtures, or whatever. Indeed, nose's core functionality is implemented by bundled plugins. It picks up all available plugins automatically by scanning the entrypoints from packages installed by setuptools. This has the irritating effect that</p></div> <div class="ilist"><ul> <li> <p> nose itself can't work without being installed, since it needs to find its own bundled plugins. </p> </li> <li> <p> any additional plugins you write or use have to be installed as well. </p> </li> </ul></div> <div class="para"><p>Now I don't like this at the best of times; I get annoyed by software that insists it knows better than me where it should live, and I especially don't like blindly installing new software which might go &amp; stomp all over existing installed software. Once you introduce versioning into the equation, I get even more annoyed; you end up with a python version of <a href="http://en.wikipedia.org/wiki/DLL_hell" title="external link to http://en.wikipedia.org/wiki/DLL_hell" class="http">DLL Hell</a>, with one application needing version 0.8 of a package, and another needing version 0.9.</p></div> <div class="sidebarblock"> <div class="sidebar-content"> <div class="sidebar-title">Ruby gems</div> <div class="para"><p>Incidentally - see also Tim Bray's <a href="http://www.tbray.org/ongoing/When/200x/2008/08/31/Gem-Paranoia" title="external link to http://www.tbray.org/ongoing/When/200x/2008/08/31/Gem-Paranoia" class="http">take on a related issue from the Ruby point of view</a>. I'm familiar enough with Python to work my way around these problems when they arise, but not so for Ruby - how do you install a gem-distributed package locally without interfering with your system Ruby libraries?)</p></div> </div></div> <div class="para"><p>But - since most of the rest of the world apparently shares none of my concerns with these issues, I struggle manfully onwards.</p></div> <div class="para"><p>This week, there's been a thread on the <a href="http://lists.idyll.org/listinfo/testing-in-python" title="external link to http://lists.idyll.org/listinfo/testing-in-python" class="http">testing-in-python</a> mailing list "<a href="http://lists.idyll.org/pipermail/testing-in-python/2008-September/000966.html" title="external link to http://lists.idyll.org/pipermail/testing-in-python/2008-September/000966.html" class="http">why you should distribute tests with your application / module</a>". I agree 100% - tests should always be distributed with applications; I think almost all of the software I've ever written has had a bundled test-suite. (This was particularly useful for Fortran software, where there is such a wide range of compilers, but it still helps in tracking down system-specific issues even in Python).</p></div> <div class="para"><p>Unfortunately, nose's <tt>setup.py</tt> requirements fly in the face of this; most users won't have nose installed. I could just about forgive nose for this, if I could rely on distributing custom plugins with my package, and being able to pick them up from the local path; but I can't even do that.</p></div> <div class="para"><p>It's also worth noting that this is an issue even for software with a very limited distribution. If you're working collaboratively on a project, then all your colleagues need to be able to run tests too; and if you're working in a heterogeneous environment, then adding <a href="http://www.yosefk.com/blog/redundancy-vs-dependencies-which-is-worse.html" title="external link to http://www.yosefk.com/blog/redundancy-vs-dependencies-which-is-worse.html" class="http">additional dependencies and installation requirements</a> becomes rapidly onerous, and liable to piss off your co-developers.</p></div> <div class="para"><p>Anyway. To round this story off with at least a moderately cheerful ending, I was happy enough with nose's usability not to abandon it, but pissed off with its requirements enough to try and fix them. There's a <a href="http://code.google.com/p/python-nose/issues/detail?id=26&amp;colspec=ID%20Type%20Status%20Priority%20Stars%20Milestone%20Owner%20Summary" title="external link to http://code.google.com/p/python-nose/issues/detail?id=26&amp;colspec=ID%20Type%20Status%20Priority%20Stars%20Milestone%20Owner%20Summary" class="http">patch in the nose bug-tracker</a> which at least partly fixes the issue, so that nose will pick up plugins from sys.path.</p></div> <div class="para"><p>I suspect in the long term, though, the answer to most of these issues lies in the use of <a href="http://pypi.python.org/pypi/virtualenv" title="external link to http://pypi.python.org/pypi/virtualenv" class="http">virtualenv</a>. Enough people insist on requiring setuptools-based install, that it will probably be easier simply to isolate every app with its own dependencies in a virtualenv, and just distribute that instead.</p></div> <div class="para"><p>In the meantime, for anyone actually reading this; <strong>REQUIRING SETUPTOOLS IS FUCKING ANNOYING, MMM'KAY? DON'T DO IT</strong></p></div> <br/><small><a href="http://uszla.me.uk/space/blog/2008/09/19" title="link to http://uszla.me.uk/space/blog/2008/09/19">@</a></small> Fri, 19 Sep 2008 18:35:51 GMT Toby White Uszla blog http://uszla.me.uk/space/blog/2008/09/19 http://uszla.me.uk/space/blog/2008/09/19 New job + Python descriptors http://feedproxy.google.com/~r/Uszla/blog/~3/p3wFdVmAICQ/11 <div class="para"><p>So, there's been a bit of a hiatus in my blogging activity, which has coincided with a change in my job.</p></div> <div class="para"><p>I'm no longer employed by the university - as of the start of August I've been working as a founder of a startup. We're still in stealth mode, so output here will be work-related, but not too revealing, initially at least. I think it's probably safe to say that there will be much more Python than Fortran from now on!</p></div> <div class="para"><p>Anyway, I thought it good practice to start writing English again, after several weeks of nothing but Python. Naturally of course these English words will concern Python …</p></div> <div class="para"><p>So today I first used Python descriptors in anger. The particular pattern used I hadn't seen before, so I thought I'd write about it.</p></div> <div class="para"><p>The problem I faced was how to nicely deal with an object which is expensive to initialize, which there should only be one of, and which is used by a number of other objects. If I were writing in Java, this would be a classic use-case for a Singleton, with some form of delayed initialization. How to do it in a more Pythonic way, though?</p></div> <div class="para"><p>The easiest way to get Singleton-ish behaviour is probably to have the <tt>ExpensiveObject</tt> defined in its own module, with one instance instantiated as a module-level variable, and thus initialized on module import. This means that any other objects which need access to it can simply have a class attribute pointing at it.</p></div> <div class="listingblock"> <div class="content"> <pre> elsewhere.py: <span class="htmlfontify-keyword">class</span> <span class="htmlfontify-type">ExpensiveObject</span>(object): ... expensive_instance = ExpensiveObject()</pre></div></div> <div class="listingblock"> <div class="content"> <pre> user.py: <span class="htmlfontify-keyword">class</span> <span class="htmlfontify-type">ObjectUser</span>(object): <span class="htmlfontify-keyword">from</span> elsewhere <span class="htmlfontify-keyword">import</span> expensive_instance reference = expensive_instance ...</pre></div></div> <div class="para"><p>This doesn't delay instantiation, though - the instantiation is performed whenever the <tt>ObjectUser</tt> definition is processed. Since <tt>expensive_instance</tt> isn't always needed, it's annoying to have to always create it.</p></div> <div class="para"><p>In order to do avoid that, clearly we need to remove the expensive_instance from <tt>elsewhere</tt> and replace the ObjectUser attribute reference with a function call.</p></div> <div class="para"><p>We could do this in <tt>ObjectUser</tt> by overriding its <tt><em>getattr</em></tt> appropriately, to do the normal trick where we check whether <tt>expensive_instance</tt> is defined on this object, and if not, putting it there:</p></div> <div class="listingblock"> <div class="content"> <pre> <span class="htmlfontify-keyword">def</span> <span class="htmlfontify-function-name">__getattr__</span>(<span class="htmlfontify-py-pseudo-keyword-face">self</span>, name): <span class="htmlfontify-keyword">if</span> name == <span class="htmlfontify-string">'reference'</span> <span class="htmlfontify-keyword">and</span> name <span class="htmlfontify-keyword">not</span> <span class="htmlfontify-keyword">in</span> <span class="htmlfontify-py-pseudo-keyword-face">self</span>.__dict__: <span class="htmlfontify-keyword">from</span> elsewhere <span class="htmlfontify-keyword">import</span> expensive_instance object.__class__.name = expensive_instance <span class="htmlfontify-keyword">return</span> object__getattr__(<span class="htmlfontify-py-pseudo-keyword-face">self</span>, name)</pre></div></div> <div class="para"><p>which has a few problems.</p></div> <div class="ilist"><ul> <li> <p> Firstly, this involves doing this check for <strong>every</strong> attribute access on this object, which is an unnecessary price. </p> </li> <li> <p> Secondly, if we are doing lots of getattr tricks for other attributes as well, it's messy to have them all in the same method. </p> </li> <li> <p> Thirdly, we've set expensive_instance to be a class attribute, which means that every class for which we do this will get its own expensive_instance. </p> </li> </ul></div> <div class="para"><p>We could solve the second two issues with inheritance - have a small class (<tt>ExpensiveFactory</tt>?) which does nothing but override <tt><em>getattr</em></tt> for the attribute of interest. This isolates the <tt><em>getattr</em></tt> logic for this attribute, and makes sure that only one copy of <tt>expensive_instance</tt> is instantiated (as a class variable of <tt>ExpensiveFactory</tt>)</p></div> <div class="listingblock"> <div class="content"> <pre> <span class="htmlfontify-keyword">class</span> <span class="htmlfontify-type">ObjectUser</span>(object, ExpensiveFactory): ...</pre></div></div> <div class="para"><p>But: we still haven't solved the first problem (speed of <tt><em>getattr</em></tt>) and we've introduced another - if any of these child classes want to override getattr, they have to remember to call <tt>super()</tt> all the way up the inheritance hierarchy (see <a href="http://fuhm.net/super-harmful/" title="external link to http://fuhm.net/super-harmful/" class="http">Python's Super considered harmful</a>)</p></div> <div class="para"><p>Anyway - so this (I think) was exactly the reason that descriptors were invented. Instead of <tt>ExpensiveFactory</tt>, we have <tt>ExpensiveDescriptor</tt>:</p></div> <div class="listingblock"> <div class="content"> <pre> elsewhere.py: <span class="htmlfontify-keyword">class</span> <span class="htmlfontify-type">ExpensiveDescriptor</span>(object): _expensive_instance = <span class="htmlfontify-py-pseudo-keyword-face">None</span> <span class="htmlfontify-keyword">def</span> <span class="htmlfontify-function-name">__get__</span>(<span class="htmlfontify-py-pseudo-keyword-face">self</span>, instance, owner): <span class="htmlfontify-keyword">if</span> <span class="htmlfontify-py-pseudo-keyword-face">self</span>.__class__._expensive_instance <span class="htmlfontify-keyword">is</span> <span class="htmlfontify-py-pseudo-keyword-face">None</span>: <span class="htmlfontify-keyword">from</span> elsewhere <span class="htmlfontify-keyword">import</span> ExpensiveObject <span class="htmlfontify-py-pseudo-keyword-face">self</span>.__class__._expensive_instance = ExpensiveObject() <span class="htmlfontify-keyword">return</span> <span class="htmlfontify-py-pseudo-keyword-face">self</span>.__class__._expensive_instance</pre></div></div> <div class="listingblock"> <div class="content"> <pre> user.py: <span class="htmlfontify-keyword">class</span> <span class="htmlfontify-type">ObjectUser</span>(object): expensive_instance = elsewhere.ExpensiveDescriptor() ...</pre></div></div> <div class="para"><p>Whenever <tt>ObjectUser().expensive_instance</tt> is accessed, the descriptor's <tt><em>get</em></tt> method is invoked, and an <tt>ExpensiveObject</tt> created - but not before then.</p></div> <div class="para"><p>This happens for <tt>ObjectUser</tt>, and any classes which inherit from it, without any further interference in them.</p></div> <div class="para"><p>And, <tt><em>get</em></tt> is implemented to have no cost when accessing any other attributes.</p></div> <div class="para"><p>And, of course, since <tt>_expensive_instance</tt> is a class attribute of the Descriptor, there should only ever be one created.</p></div> <div class="para"><p>Actually, you could have <tt>ExpensiveDescriptor</tt> manipulating the module attribute <tt>elsewhere.expensive_instance</tt> - this would let you get at the <tt>expensive_instance</tt> from anywhere in the code without having to go through an object - but only after it had been instantiated by one of the accessing objects. Might or might not be useful, depending on your use cases.</p></div> <div class="para"><p>Anyway, so that's why descriptors are brilliant! For more reading, try:</p></div> <div class="ilist"><ul> <li> <p> <a href="http://users.rcn.com/python/download/Descriptor.htm" title="external link to http://users.rcn.com/python/download/Descriptor.htm" class="http">How-To Guide for Descriptors</a> </p> </li> <li> <p> <a href="http://gulopine.gamemusic.org/2007/nov/23/python-descriptors-part-1-of-2/" title="external link to http://gulopine.gamemusic.org/2007/nov/23/python-descriptors-part-1-of-2/" class="http">Python Descriptors part 1 of 2</a> </p> </li> <li> <p> <a href="http://gulopine.gamemusic.org/2007/nov/24/python-descriptors-part-2-of-2/" title="external link to http://gulopine.gamemusic.org/2007/nov/24/python-descriptors-part-2-of-2/" class="http">Python Descriptors part 2 of 2</a> </p> </li> </ul></div> <br/><small><a href="http://uszla.me.uk/space/blog/2008/09/11" title="link to http://uszla.me.uk/space/blog/2008/09/11">@</a></small> Mon, 15 Sep 2008 22:17:43 GMT Toby White Uszla blog http://uszla.me.uk/space/blog/2008/09/11 http://uszla.me.uk/space/blog/2008/09/11 XPath and QNames in content http://feedproxy.google.com/~r/Uszla/blog/~3/xZqPuHOsCH4/23 <div class="para"><p>As any fule no, QNames are how XML does namespaces. Where a namespace has been declared:</p></div> <div class="listingblock"> <div class="content"> <pre> &lt;c:cml xmlns:c=<span class="htmlfontify-string">&quot;</span><span class="htmlfontify-string">http://www.xml-cml.org/schema/&gt;</span><span class="htmlfontify-string"> </span></pre></div></div> <div class="para"><p>and the "c" prefix on the element name is associated, via the xmlns attribute, with the namespace URI. This is trivially manipulable with any namespace-aware tool.</p></div> <div class="para"><p>So far so good. However, when QNames are used in content (typically, as an attribute value) then the situation is more complex. The two nodes below are equivalent under QName-in-content processing.</p></div> <div class="listingblock"> <div class="content"> <pre> &lt;c:cml xmlns:c=<span class="htmlfontify-string">&quot;http://www.xml-cml.org/schema&quot;</span> att=<span class="htmlfontify-string">&quot;c:comp&quot;</span>/&gt; &lt;d:cml xmlns:d=<span class="htmlfontify-string">&quot;http://www.xml-cml.org/schema&quot;</span> att=<span class="htmlfontify-string">&quot;d:comp&quot;</span>/&gt;</pre></div></div> <div class="para"><p>This usage is blessed by the W3C, <a href="http://www.w3.org/2001/tag/doc/qnameids.html" title="external link to http://www.w3.org/2001/tag/doc/qnameids.html" class="http">http://www.w3.org/2001/tag/doc/qnameids.html</a>, and <a href="http://www.w3.org/TR/xslt" title="external link to http://www.w3.org/TR/xslt" class="http">XSLT</a> depends on it working.</p></div> <div class="para"><p>But it's significantly harder to work with using most XML toolkits.</p></div> <div class="listingblock"> <div class="content"> <pre> <span class="htmlfontify-function-name">node</span>()[@<span class="htmlfontify-variable-name">att</span>=<span class="htmlfontify-string">'string'</span>]</pre></div></div> <div class="para"><p>The above XPath returns all nodes which have <tt>att="string"</tt>. However, it turns out that matching on a namespace-resolved QName needs the following:</p></div> <div class="listingblock"> <div class="content"> <pre> <span class="htmlfontify-function-name">node</span>()[substring-after(@att, <span class="htmlfontify-string">':'</span>)=<span class="htmlfontify-string">'comp'</span> and @att[../namespace::* [name()=substring-before(../@att,<span class="htmlfontify-string">':'</span>)] =<span class="htmlfontify-string">'http://www.xml-cml.org/schema'</span>] ]</pre></div></div> <div class="para"><p>if you only allow for prefixed QNames (<strong>eg</strong> <tt>c:comp</tt> above). If you want to be able to match unprefixed QNames as well, that is, QNames in the default namespace:</p></div> <div class="listingblock"> <div class="content"> <pre> &lt;cml xmlns=<span class="htmlfontify-string">&quot;http://www.xml-cml.org/schema&quot;</span> att=<span class="htmlfontify-string">&quot;comp&quot;</span>/&gt;</pre></div></div> <div class="para"><p>then you need to extend the expression to the following:</p></div> <div class="listingblock"> <div class="content"> <pre> <span class="htmlfontify-function-name">node</span>()[(substring-after(@att, <span class="htmlfontify-string">':'</span>)=<span class="htmlfontify-string">'comp'</span> and @att[../namespace::* [name()=substring-before(../@att,<span class="htmlfontify-string">':'</span>)] =<span class="htmlfontify-string">'http://www.xml-cml.org/schema'</span>]) or (@<span class="htmlfontify-variable-name">att</span>=<span class="htmlfontify-string">'comp'</span> and and namespace::*[name()=<span class="htmlfontify-string">''</span>] =<span class="htmlfontify-string">'http://www.xml-cml.org/schema'</span>) ]</pre></div></div> <div class="para"><p>which is hardly transparent!</p></div> <div class="para"><p>Much as I think XPath 2 is a bad idea in general, this is one area where it is a significant step forward; it offers node functions:</p></div> <div class="ilist"><ul> <li> <p> <a href="http://www.w3.org/TR/xquery-operators/#func-local-name-from-QName" title="external link to http://www.w3.org/TR/xquery-operators/#func-local-name-from-QName" class="http">fn:local-name-from-QName</a> </p> </li> <li> <p> <a href="http://www.w3.org/TR/xquery-operators/#func-namespace-uri-from-QName" title="external link to http://www.w3.org/TR/xquery-operators/#func-namespace-uri-from-QName" class="http">fn:namespace-uri-from-QName</a> </p> </li> </ul></div> <div class="para"><p>which will do what they suggest. Of course XPath 2 then buggers things up again by saying:</p></div> <div class="quoteblock"> <div class="quoteblock-content"> <div class="para"><p>In XPath Version 2.0, the namespace axis is deprecated and need not be supported by a host language</p></div> </div> <div class="quoteblock-attribution"> <em>W3C Recommendation 23 January 2007</em><br /> — XML Path Language (XPath) 2.0 </div></div> <div class="para"><p>Who needs backwards compatibility anyway?</p></div> <div class="para"><p>But since <a href="http://xmlsoft.org/" title="external link to http://xmlsoft.org/" class="http">libxml2</a> doesn't support XPath2, I don't propose to worry very much about it.</p></div> <div class="para"><p>In any case, unwieldy though the above solutions are, they work correctly.</p></div> <br/><small><a href="http://uszla.me.uk/space/blog/2008/04/23" title="link to http://uszla.me.uk/space/blog/2008/04/23">@</a></small> Wed, 23 Apr 2008 21:27:31 GMT Toby White Uszla blog http://uszla.me.uk/space/blog/2008/04/23 http://uszla.me.uk/space/blog/2008/04/23 m4Y - the Y combinator in m4 http://feedproxy.google.com/~r/Uszla/blog/~3/KCt8ioOCrOI/22 <div class="para"><p>Just to get the goods up front:</p></div> <div class="listingblock"> <div class="content"> <pre> <span class="htmlfontify-keyword">define</span>(`m4Y', `<span class="htmlfontify-comment">dnl</span> <span class="htmlfontify-keyword">pushdef</span>(`m4Y_recur',<span class="htmlfontify-comment">dnl</span> `<span class="htmlfontify-keyword">pushdef</span>(`m4Y_LL',<span class="htmlfontify-comment">dnl</span> `<span class="htmlfontify-variable-name">$1</span>''<span class="htmlfontify-keyword">changequote</span>([,])(['<span class="htmlfontify-keyword">changequote</span>([,])`<span class="htmlfontify-keyword">changequote</span>`]`$[]1'(``$[]1'')<span class="htmlfontify-comment">dnl</span> ['<span class="htmlfontify-keyword">changequote</span>([,])'<span class="htmlfontify-keyword">changequote</span>`])<span class="htmlfontify-keyword">changequote</span>`<span class="htmlfontify-comment">dnl</span> (<span class="htmlfontify-keyword">changequote</span>([,])`$[]1'<span class="htmlfontify-keyword">changequote</span>)<span class="htmlfontify-comment">dnl</span> `<span class="htmlfontify-keyword">popdef</span>(`m4Y_LL')')'<span class="htmlfontify-comment">dnl</span> `m4Y_LL')<span class="htmlfontify-comment">dnl</span> <span class="htmlfontify-keyword">pushdef</span>(`m4Y_LL',`<span class="htmlfontify-comment">dnl</span> m4Y_recur(`m4Y_recur')'<span class="htmlfontify-keyword">changequote</span>([,])(`$[]1')<span class="htmlfontify-keyword">changequote</span>`<span class="htmlfontify-comment">dnl</span> <span class="htmlfontify-keyword">popdef</span>(`m4Y_recur')`'<span class="htmlfontify-keyword">popdef</span>(`m4Y_LL')')`'<span class="htmlfontify-comment">dnl</span> '`m4Y_LL')`'<span class="htmlfontify-comment">dnl</span></pre></div></div> <div class="para"><p>So as seems to be popular, I've been working my way through <a href="http://mitpress.mit.edu/catalog/item/default.asp?ttype=2&amp;tid=4825" title="external link to http://mitpress.mit.edu/catalog/item/default.asp?ttype=2&amp;tid=4825" class="http">The Little Schemer</a> over the last few weeks.</p></div> <div class="para"><p>And, as is equally common, I ground to a halt at the derivation at the end of Chapter IX, where they spring the <a href="http://en.wikipedia.org/wiki/Fixed_point_combinator" title="external link to http://en.wikipedia.org/wiki/Fixed_point_combinator" class="http">Y Combinator</a> on the unsuspecting audience. <a href="http://weblog.raganwald.com/2007/02/but-y-would-i-want-to-do-thing-like.html" title="external link to http://weblog.raganwald.com/2007/02/but-y-would-i-want-to-do-thing-like.html" class="http">The best way to understand it is to work through it by yourself</a>, so I thought I would see if you could do one in <a href="http://en.wikipedia.org/wiki/M4_%28computer_language%29" title="external link to http://en.wikipedia.org/wiki/M4_%28computer_language%29" class="http">m4</a>. And it turns out you can, though it's not very pretty!</p></div> <div class="para"><p>Clearly what the world needs is to know about it, so I wrote it up, and you can follow the derivation in two essays:</p></div> <div class="olist"><ol> <li> <p> <a href="http://uszla.me.uk/space/essays/m4HOP" class="wiki" title="essays/m4HOP was updated 1 year, 1 week ago">Higher-Order Programming in m4</a>, which shows you how to do proper quoting to get macro <a href="http://en.wikipedia.org/wiki/Currying" title="external link to http://en.wikipedia.org/wiki/Currying" class="http">Currying</a> to work. </p> </li> <li> <p> <a href="http://uszla.me.uk/space/essays/m4Y" class="wiki" title="essays/m4Y was updated 1 year, 1 week ago">The Y Combinator in m4</a>, which uses those quoting techniques to do the full derivation of <tt>m4Y</tt> above. </p> </li> </ol></div> <div class="quoteblock"> <div class="quoteblock-content"> <div class="para"><p>Beware that m4 may be dangerous for the health of compulsive programmers.</p></div> </div> <div class="quoteblock-attribution"> — The GNU m4 manual </div></div> <div class="technorati_tags" align="right"><small>Technorati Tags: <a href="http://technorati.com/tag/essays" rel="tag">essays</a>, <a href="http://technorati.com/tag/m4" rel="tag">m4</a>, <a href="http://technorati.com/tag/m4hop" rel="tag">m4hop</a>, <a href="http://technorati.com/tag/m4y" rel="tag">m4y</a>, <a href="http://technorati.com/tag/programming" rel="tag">programming</a>, <a href="http://technorati.com/tag/space" rel="tag">space</a></small></div><br/><small><a href="http://uszla.me.uk/space/blog/2008/04/22" title="link to http://uszla.me.uk/space/blog/2008/04/22">@</a></small> Tue, 22 Apr 2008 13:25:11 GMT Toby White Uszla blog http://uszla.me.uk/space/blog/2008/04/22 http://uszla.me.uk/space/blog/2008/04/22 asciidoc source code highlighting http://feedproxy.google.com/~r/Uszla/blog/~3/WWc9bROJe6Q/21 <div class="para"><p>As I've mentioned before, all the entries in this blog are written in <a href="http://www.methods.co.nz/asciidoc/" title="external link to http://www.methods.co.nz/asciidoc/" class="http">asciidoc</a>, which is very nice for a lightweight markup language, particularly in terms of embedding code fragments and having them marked up nicely.</p></div> <div class="para"><p><a href="http://www.methods.co.nz/asciidoc/" title="external link to http://www.methods.co.nz/asciidoc/" class="http">Asciidoc</a> uses <a href="http://www.gnu.org/software/src-highlite/" title="external link to http://www.gnu.org/software/src-highlite/" class="http">GNU Source-highlight</a> as its backend for generating pretty code fragments, which does a reasonable job, and <a href="http://www.lorenzobettini.it/" title="external link to http://www.lorenzobettini.it/" class="http">its author</a> is very responsive to feedback - he's fixed a couple of bugs in the Fortran and XML modules for me.</p></div> <div class="para"><p>However, I've been growing dissatisfied with its use, for two reasons.</p></div> <div class="olist"><ol> <li> <p> it has a <strong>very</strong> heavyweight dependency on <a href="http://www.boost.org/doc/libs/1_35_0/libs/regex/doc/html/index.html" title="external link to http://www.boost.org/doc/libs/1_35_0/libs/regex/doc/html/index.html" class="http">boost</a>, for its regex library. Compiling boost takes several hours, and this seems to me like massive overkill for a bit of code highlighting. </p> </li> <li> <p> It is purely regex-driven. Furthermore, all language front-ends are defined in terms of a mini-regex language. This means that its markup capabilities are fundamentally limited to a very simple regex subset. </p> </li> </ol></div> <div class="para"><p>In any case, it can't approach the expressiveness of <a href="http://www.gnu.org/software/emacs/" title="external link to http://www.gnu.org/software/emacs/" class="http">Emacs</a> font-lock highlighting, which is what I'm used to.</p></div> <div class="para"><p>So, I thought it ought to be possible to abuse one of <a href="http://www.emacswiki.org/cgi-bin/wiki/SaveAsHtml" title="external link to http://www.emacswiki.org/cgi-bin/wiki/SaveAsHtml" class="http">several available emacs-lisp packages</a> to do the job, and indeed it was. The <a href="http://source.uszla.me.uk/misc/htmlfontify" title="external link to http://source.uszla.me.uk/misc/htmlfontify" class="http">script available here</a> is a wrapper around a modified version of <a href="http://rtfm.etla.org/emacs/htmlfontify/" title="external link to http://rtfm.etla.org/emacs/htmlfontify/" class="http">htmlfontify</a>, and works like so:</p></div> <div class="listingblock"> <div class="content"> <pre> htmlfontify -mode $<span class="htmlfontify-variable-name">MODENAME</span> $<span class="htmlfontify-variable-name">FILENAME</span></pre></div></div> <div class="para"><p>or if <tt>$FILENAME</tt> is <tt>-</tt>, it takes input on <tt>stdin</tt>. It will print out a properly marked-up fragment of HTML on <tt>stdout</tt>, marked up according to emacs, in <tt>$MODENAME-mode</tt> fontification.</p></div> <div class="admonitionblock"> <table><tr> <td class="icon"> <div class="title">Note</div> </td> <td class="content">Importantly, it is entirely standalone, with no dependencies beyond Emacs 21 or better, which is installed everywhere these days.</td> </tr></table> </div> <div class="para"><p>This was easy to write an asciidoc filter for, so code in this blog will henceforth be marked up by emacs.</p></div> <br/><small><a href="http://uszla.me.uk/space/blog/2008/04/21" title="link to http://uszla.me.uk/space/blog/2008/04/21">@</a></small> Mon, 21 Apr 2008 21:49:05 GMT Toby White Uszla blog http://uszla.me.uk/space/blog/2008/04/21 http://uszla.me.uk/space/blog/2008/04/21 Finder WebDAV bugs, part II http://feedproxy.google.com/~r/Uszla/blog/~3/Nx81nWrd-bk/16 <div class="para"><p>As a follow-up to my last post on this, some good news and some bad.</p></div> <div class="para"><p>Good news: Apple Engineering got back rapidly, with a good understanding of the authentication issue, and a good suggestion for how they might fix it. Of course the fix won't emerge until at least 10.5.3.</p></div> <div class="para"><p>Bad news: there is another bug lurking in Finder's webdav implementation that I keep coming across. I haven't characterized it well enough to report, but I'm noting it down here so Google has some record of it at least.</p></div> <div class="para"><p>The symptom is that after the state of the webdav server changes in some way (Certainly not every time it changes; I <strong>think</strong> this occurs when a directory that was previously readable has become unreadable because permissions have changed) then when you try and eject the mounted disk, Finder refuses with one of two error messages.</p></div> <div class="olist"><ol> <li> <p> It complains that the disk is in use, even when it's not - and this can be confirmed by </p> <div class="para"><p>source<sub>~</sub>~<sub>~</sub>~<sub>~</sub>~<sub>~</sub>~<sub> sh-3.2# lsof /Volumes/webdav_mount lsof: WARNING: can't stat() webdav file system /Volumes/webdav_mount Output information may be incomplete. assuming "dev=2d000009" from mount table source</sub>~<sub>~</sub>~<sub>~</sub>~<sub>~</sub>~<sub>~</sub></p></div> <div class="para"><p>The fix for this is a simple</p></div> <div class="para"><p>source<sub>~</sub>~<sub>~</sub>~<sub>~</sub>~<sub>~</sub>~<sub> umount -f /Volumes/webdav_mount source</sub>~<sub>~</sub>~<sub>~</sub>~<sub>~</sub>~<sub>~</sub></p></div> </li> <li> <p> It gives the unhelpful message: "error code -8072" </p> <div class="para"><p>In this case, the fix is first to unmount the disk with <tt>umount</tt> as above, and then to restart Finder.</p></div> <div class="admonitionblock"> <table><tr> <td class="icon"> <div class="title">Note</div> </td> <td class="content"><strong>Make sure to unmount the disk first!!!</strong> If you try and restart Finder (or logout, or reboot) without doing so, then the OS is liable to hang in an unretrieveable state, so that only pulling the power cable fixes it - which has happened to me more than once.</td> </tr></table> </div> </li> </ol></div> <br/><small><a href="http://uszla.me.uk/space/blog/2008/04/16" title="link to http://uszla.me.uk/space/blog/2008/04/16">@</a></small> Wed, 16 Apr 2008 14:23:32 GMT Toby White Uszla blog http://uszla.me.uk/space/blog/2008/04/16 http://uszla.me.uk/space/blog/2008/04/16 shell history http://feedproxy.google.com/~r/Uszla/blog/~3/-XQtkbUfJxU/26 <div class="para"><p>Borrowed from <a href="http://plasmasturm.org/log/497/" title="external link to http://plasmasturm.org/log/497/" class="http">plasmasturm</a>.</p></div> <div class="para"><p>source<sub>~</sub>~<sub>~</sub>~<sub>~</sub>~<sub>~</sub>~<sub>~</sub>~<sub>~</sub>~<sub>~</sub>~ sloth:<sub> tow$ history|awk <em>{a[$2]++} END {for(i in a){printf "%5d\t%s\n",a[i],i}}</em>|sort -rn|head 99 ls 85 cd 66 git 53 xsltproc 44 vi 38 ssh 22 python 15 grep 8 wget 8 rm source</sub>~<sub>~</sub>~<sub>~</sub>~<sub>~</sub>~<sub>~</sub>~<sub>~</sub>~<sub>~</sub>~~~</p></div> <br/><small><a href="http://uszla.me.uk/space/blog/2008/04/10/16/26" title="link to http://uszla.me.uk/space/blog/2008/04/10/16/26">@</a></small> Thu, 10 Apr 2008 16:26:55 GMT Toby White Uszla blog http://uszla.me.uk/space/blog/2008/04/10/16/26 http://uszla.me.uk/space/blog/2008/04/10/16/26 The problem with visual programming languages http://feedproxy.google.com/~r/Uszla/blog/~3/val76GhCIf0/10 <div class="para"><p>People seem to like <a href="http://en.wikipedia.org/wiki/Visual_programming_language" title="external link to http://en.wikipedia.org/wiki/Visual_programming_language" class="http">visual (or graphical) programming languages</a>, (VPLs), but I don't think they should.</p></div> <h4 id="_reports_of_success_2">Reports of success</h4> <div class="para"><p>This was prompted by a talk on Monday, at the <a href="http://royalsociety.org/event.asp?id=6066" title="external link to http://royalsociety.org/event.asp?id=6066" class="http">Royal Society meeting on environmental e-Science</a>. One of the speakers (I forget who) was demonstrating a workflow system, run through a VPL environment. He talked about having given a workshop, showing scientists how to use the system, and quoted one of them as saying (paraphrased from memory):</p></div> <div class="quoteblock"> <div class="quoteblock-content"> <div class="para"><p>I've accomplished in one afternoon what it took me the whole of Summer 2005 to do.</p></div> </div> <div class="quoteblock-attribution"> </div></div> <div class="para"><p>and used this as evidence for how wonderful such "friendly" VPL environments are.</p></div> <div class="para"><p>I've been to a number of talks where such things are shown off, and it's undoubtedly true that placing these tools into the hands of some scientists does result in such reactions (although I suspect less often that their proponents like to think; and I'm not sure how long-lived such reactions are).</p></div> <div class="para"><p>However, contrary to the conclusions usually drawn, I don't think that the praise should be given to the VPL environment - indeed I think such things are actively harmful, and actually, you could get the same reactions via different means.</p></div> <h4 id="_cleaner_interfaces_2">Cleaner interfaces</h4> <div class="para"><p>I suspect that actually, such positive reactions aren't actually caused by the visual nature of the environment, so much as the fact that (compared with the typical workflow system of bodged-together Perl scripts)</p></div> <div class="olist"><ol> <li> <p> interfaces between components are much simpler, </p> </li> <li> <p> they've been pre-written by someone else </p> </li> <li> <p> they've been designed to plug together. </p> </li> </ol></div> <div class="para"><p>But because humans are very visual creatures, it is the obvious differences in the visual aspect of the interface that is noticed, and it's to that that positive effects are ascribed. It may well be that there is a small advantage there, but I think it is fairly small, and very easily overstated; see for example "<a href="http://portal.acm.org/citation.cfm?id=203251" title="external link to http://portal.acm.org/citation.cfm?id=203251" class="http">Why looking isn't always seeing: readership skills and graphical programming</a>", which I don't think enough relevant people have read.</p></div> <div class="para"><p>When pulling things together using bodged Perl scripts, then you are reliant on whatever interfaces to the script, and to whatever other programs are being called, that someone else has written.</p></div> <div class="para"><p>These interfaces are probably not quite what you want for your purposes, so you'll need to munge them a bit.</p></div> <div class="para"><p>They're almost certainly not well-designed - indeed probably little thought has gone into interface design at all, so much as ensuring that the necessary scientific job gets done.</p></div> <div class="para"><p>They may not be very functionally oriented; i.e. not well-suited to being called as part of a larger workflow. For example, there may be lots of out-of-band set-up required in the way of global environment variables and so forth.</p></div> <div class="para"><p>All of these problems will be ameliorated in building components for any workflow system, certainly those of the type likely to underlie typical VPLs. Interface design will be an integral part of making components that fit together to make workflows of the type envisaged; components will have been co-designed, so that interfaces between them match well their intended use; and they will have to be built such that they don't rely on global state.</p></div> <div class="para"><p>The end result is that the components of such a system can be pulled together and made to interact far far easier than a set of programs designed in isolation with little thought for reuse. (Though if badly done, it may result in components which can't be easily re-used outside the original workflow domain.) And of course this is true regardless of what programming interface is used to edit the resulting workflows.</p></div> <div class="para"><p>However, I also believe that beyond this, VPLs are actively harmful.</p></div> <h4 id="_text_munging_tools_2">Text-munging tools</h4> <div class="para"><p>My objection boils down to the fact that we have an enormous range of text-munging tools, but we have far fewer tools for munging whatever graphical representations are fed to us on the screen.</p></div> <div class="para"><p>The issue that most obviously shows itself to me is version control, or revision tracking.</p></div> <div class="para"><p>As any halfway-sensible programmer does, I keep all my projects under version control. The reasons are well-rehearsed, but I firmly believe that just as any program longer than 10 lines probably has a bug, any program longer than 10 lines should be kept under version control. The same applies to programs in VPLs. If you've got more than 10 or so components strung together, each of which probably has 5 or 6 tunable parameters, then you want to be able to preserve the state of the system, and record changes between them.</p></div> <div class="para"><p>And this is not just in order to be able to roll back to previous versions; but to be able to usefully compare source trees:</p></div> <div class="ilist"><ul> <li> <p> so that you can see the difference between last week's and this week's version </p> </li> <li> <p> so that you can see the difference between your version and your colleagues version. </p> </li> <li> <p> so that you can usefully merge in adaptations from variant source trees. </p> </li> </ul></div> <div class="para"><p>The tools for doing this are well-established for text source, as are standard practices for improving source code. For example, reformatting - whitespace-only - updates to source code are often deliberately isolated from semantic changes. Similarly, groups of related changes are often made together in changesets.</p></div> <div class="para"><p>Such practices facilitate the use of text-based tools, and as a result, management of multiple similar source trees is well understood and documented.</p></div> <div class="para"><p>By comparison; if code were stored, for example, in a Word document (or to make the same point more extravagantly, as a bitmap image showing the text), this would be impossible. It would be just as easy for the programmer to read - but you'd lose all the power of automatic comparisons; source trees diverge wildly with every minor change. This wouldn't stop you using version control, and backtracking to previous versions, but your diffs would carry no useful information.</p></div> <div class="para"><p>And so with visual programming. Clearly there is some serialization underlying whatever interface you're given, and more than likely that serialization is textual. So in principle, you could keep your programs under version control (though your IDE might not make it very easy).</p></div> <div class="para"><p>However, the visual interface is at liberty to rewrite the serialization without consulting you; and what might be a minor, or indeed insignificant change to you (moving a box without changing its connectors; adding one additional connector) might well result in the serialization being completely restructured.</p></div> <div class="para"><p>As a result, you end up in the same situation as with your Word-encoded source. You can't compare your workflows with a colleagues. You can't trivially diff your current version with that of 6 months ago, and identify key differences. You can't check it against yesterday's version, and work out what you changed which caused the testsuite breakage that you noticed this morning.</p></div> <div class="para"><p>Although version control is the most obvious to me as a useful application of text-munging, there's any number of others that are useful; automatic bug-finding tools; refactoring tools, etc, which rely on the well-understood machinery of text analysis.</p></div> <div class="para"><p>Even if some of these may exist in a given visual IDE (and I wouldn't be surprised if a few did), they certainly don't all, nor would it be easy to transfer them between IDEs, since there is no agreed upon standard way to do visual programming.</p></div> <h4 id="_source_control_2">Source control</h4> <div class="para"><p>The open source movement relies on source to programs being available. What that means in precise terms begins to break down when we move away from the realm of traditional compiled languages; but in any case, what it means to me is the ability to usefully manipulate and inspect the algorithms behind a program.</p></div> <div class="para"><p>You can't do this if you're given only the compiled program - all the usefully-human-readable information is in the source code, and is thrown away when compiling; minor changes in source code can result in very different machine code, and decompilers are very imperfect instruments.</p></div> <div class="para"><p>In fact, that's not quite true; there's three layers of information. There's the human-readable description of what the code should do. That's probably in someone's head. There's the partly human-, partly machine-readable form in the source code, which can be programmatically manipulated (or "compiled" as we like to say) into alternative forms, one of which is machine code for execution.</p></div> <div class="para"><p>When writing in VPLs, you radically lower the utility of the intermediate stage. The human-accessible code is in people's heads, and is transferred to a graphical form that isn't actually very human-readable - at least, not in the sense that I can write tools to do anything with it.</p></div> <div class="para"><p>So until people devote as much time to research into software engineering and code management tasks for non-textual code representations, I don't think VPLs are ever going to be properly successful.</p></div> <div class="para"><p>In fact, any code that is written in such environments is information that is being essentially thrown away - expertise that is being just as much wasted as if you threw away the source code to your compiled programs.</p></div> <br/><small><a href="http://uszla.me.uk/space/blog/2008/04/10" title="link to http://uszla.me.uk/space/blog/2008/04/10">@</a></small> Thu, 10 Apr 2008 16:13:00 GMT Toby White Uszla blog http://uszla.me.uk/space/blog/2008/04/10 http://uszla.me.uk/space/blog/2008/04/10 NO2ID update http://feedproxy.google.com/~r/Uszla/blog/~3/U_s2Um6nFHQ/06 <div class="para"><p>Finishing this political digression:</p></div> <div class="para"><p>The motion <a href="http://uszla.me.uk/space/blog/2008/03/31" title="external link to http://uszla.me.uk/space/blog/2008/03/31" class="http">mentioned above</a> passed under the rules of the local branch. A motion is now going forward to the UCU national Congress requesting that UCU formally affiliate itself to the NO2ID campaign.</p></div> <div class="para"><p>Thanks to everyone who took the time to email a vote. The next stage is Congress itself, which is at the end of May.</p></div> <br/><small><a href="http://uszla.me.uk/space/blog/2008/04/04/12/06" title="link to http://uszla.me.uk/space/blog/2008/04/04/12/06">@</a></small> Fri, 04 Apr 2008 12:06:37 GMT Toby White Uszla blog http://uszla.me.uk/space/blog/2008/04/04/12/06 http://uszla.me.uk/space/blog/2008/04/04/12/06 Mac OS X Finder WebDAV client authentication bug http://feedproxy.google.com/~r/Uszla/blog/~3/TBh-8I76qZM/04 <div class="para"><p>Recording this for the benefit of anyone else who comes across this problem:</p></div> <div class="para"><p>The Mac OS X Finder can act as a webdav client, allowing data exposed through a webdav interface to be mounted as an apparently native filesystem. This is how, for example, <a href="http://www.apple.com/dotmac/idisk.html" title="external link to http://www.apple.com/dotmac/idisk.html" class="http">iDisk</a> works.</p></div> <div class="para"><p>WebDAV authentication is taken care of the same way as HTTP; for any given operation, the server can demand authentication, by returning a 401 error and requiring an authentication token from the client. This token can be of various forms, but the simplest is Basic authentication - a username/password combination.</p></div> <div class="para"><p>And indeed, when you ask to mount a webdav filesystem protected by Basic authentication, Finder will pop up an appropriate dialogue box, and authenticate you.</p></div> <div class="para"><p>However - HTTP authentication works per-operation, not per-server. That is, different resources on the same server can have different authentication requirements; indeed different operations on the same resource may have different requirements (for example, user A may be allowed to read and write, user B may only be allowed to read).</p></div> <div class="para"><p>Finder doesn't completely understand this; or rather, the UI it presents to deal with this is broken. If you try and mount a directory, only some of whose sub-directories you have access to, then Finder will try and read all of the subdirectories. Given that you don't have access to everything it is trying to read, it will then conclude you don't have access to anything at all, and will only let you read any resources which are completely unauthenticated.</p></div> <div class="para"><p>A temporary work-around is on the server to move any such subdirectories elsewhere, and put temporary HTTP redirects in place. This seems to quieten Finder down, and give the desired result. Unfortunately, it doesn't usefully scale where there are many such cases; nor where these permissions are liable to relatively frequent change.</p></div> <div class="para"><p>As a result, it's essentially impossible to use Finder as a webdav client for a server with any complex ACL policy.</p></div> <div class="para"><p>I've reported this to Apple as <a href="http://uszla.me.ukrdar://problem/5837223" title="link to rdar://problem/5837223 on another Wiki" class="interwiki">bug 5837223</a>.</p></div> <br/><small><a href="http://uszla.me.uk/space/blog/2008/04/04" title="link to http://uszla.me.uk/space/blog/2008/04/04">@</a></small> Fri, 04 Apr 2008 12:06:32 GMT Toby White Uszla blog http://uszla.me.uk/space/blog/2008/04/04 http://uszla.me.uk/space/blog/2008/04/04 NO2ID http://feedproxy.google.com/~r/Uszla/blog/~3/r8I3bCbFZCA/31 <div class="para"><p>Please excuse a brief digression into politics. I don't know whether the readership of this blog includes any fellow members of the Cambridge branch of <a href="http://www.ucu.org.uk" title="external link to http://www.ucu.org.uk" class="http">UCU</a>, but if it does, and you're one of them, then read on:</p></div> <div class="para"><p>You will have got an email this morning alerting you to a motion I put before the local branch, regarding union support for <a href="http://www.no2id.net" title="external link to http://www.no2id.net" class="http">NO2ID</a>, the UK campaign against ID cards and the database state.</p></div> <div class="para"><p>In short, I'd like UCU to declare its support for NO2ID, as both UNISON and the NUJ have already done. NATFHE did so prior to their merger with the AUT to form UCU, so it's really only a re-confirmation of the union's position.</p></div> <div class="para"><p>The full text of the motion is available <a href="http://www.ucu.cam.ac.uk/resources/motion.pdf" title="external link to http://www.ucu.cam.ac.uk/resources/motion.pdf" class="http">here</a>.</p></div> <div class="para"><p>The motion was passed by the local branch - unfortunately the relevant meeting was not quorate. However, the situation can be remedied if a majority of 35 members vote in favour of the motion by email. So, if you're in a position to vote (ie, you're a member of Cambridge UCU), then please send an email to <a href="mailto:admin@ucu.cam.ac.uk" title="e-mail to mailto:admin@ucu.cam.ac.uk" class="mail">admin@ucu.cam.ac.uk</a>, offering your support, before Wednesday noon!</p></div> <div class="para"><p>If the motion is passed, this lets us take it forward to the national conference, where it can be voted on by the union as a whole.</p></div> <br/><small><a href="http://uszla.me.uk/space/blog/2008/03/31" title="link to http://uszla.me.uk/space/blog/2008/03/31">@</a></small> Mon, 31 Mar 2008 17:28:56 GMT Toby White Uszla blog http://uszla.me.uk/space/blog/2008/03/31 http://uszla.me.uk/space/blog/2008/03/31 FoX 4.0 http://feedproxy.google.com/~r/Uszla/blog/~3/KQCsRx-WAwA/43 <div class="para"><p>I'm actually quite delighted to be able to announce that I finally put the finishing touches to FoX version 4.0 today, and released it to the big bad world.</p></div> <div class="para"><p>It gets a bump to its major version number because not only are there extensive internal changes, but quite a lot of new features as well.</p></div> <div class="para"><p>The code for the input parser in versions 2.x and 3.x was not very pleasant to work with, mostly because it was the first large parser I'd ever written. It largely worked, but it had a lot of warts, and failed some of the W3C testcases in a way that was practically impossible to fix, given its original structure.</p></div> <div class="para"><p>So over the last few months I rewrote the parser into a much nicer structure, with the result that not only was I able to fix the few failing testcases, but it became relatively easy to extend it to read external entities, and check for all the validity constraints mandated by the XML standard; further it was fairly easy to also pull in support for xml:id, and xml:base, the latter of which let me finish off a few more of the DOM 3 interfaces.</p></div> <div class="para"><p>So as a result, FoX is significantly more robust, and I can hold my head high and say that FoX implements <strong>all</strong> of XML.</p></div> <div class="para"><p>(With, of course, the irritating exception of full Unicode support - though see <a href="http://uszla.me.uk/space/blog/2008/03/13" title="external link to http://uszla.me.uk/space/blog/2008/03/13" class="http">my F2003 Unicode library</a> for progress on that front.)</p></div> <br/><small><a href="http://uszla.me.uk/space/blog/2008/03/28/18/43" title="link to http://uszla.me.uk/space/blog/2008/03/28/18/43">@</a></small> Fri, 28 Mar 2008 18:43:45 GMT Toby White Uszla blog http://uszla.me.uk/space/blog/2008/03/28/18/43 http://uszla.me.uk/space/blog/2008/03/28/18/43 FoX and Vamp http://feedproxy.google.com/~r/Uszla/blog/~3/Ou9l53Tgin0/28 <div class="para"><p>A couple of weeks ago I <a href="http://uszla.me.uk/space/blog/2008/02/08/16/14" title="external link to http://uszla.me.uk/space/blog/2008/02/08/16/14" class="http">mentioned</a> that we CML-ized Dalton. As part of a related project, we had a visitor this week and last, <a href="http://www.zib.de/steinke/" title="external link to http://www.zib.de/steinke/" class="http">Thomas Steinke</a> of the <a href="http://www.zib.de/" title="external link to http://www.zib.de/" class="http">Zuse Institute, Berlin</a>.</p></div> <div class="para"><p>With his help we have now also converted <a href="http://accelrys.com/products/materials-studio/modules/VAMP.html" title="external link to http://accelrys.com/products/materials-studio/modules/VAMP.html" class="http">VAMP</a>, another quantum chemistry code, using FoX to produce <a href="http://cmlcomp.org" title="external link to http://cmlcomp.org" class="http">CMLComp</a>-encoded data. This will be initally used as part of a workflow for doing parameter sweep studies of NMR calculations.</p></div> <div class="para"><p>More importantly, though, it's yet another atomistics code on board the <a href="http://cmlcomp.org" title="external link to http://cmlcomp.org" class="http">CMLComp</a> train. We now have at least two major, widely-used, independent codes from each of the</p></div> <div class="ilist"><ul> <li> <p> Classical Molecular Dynamics </p> </li> <li> <p> Solid-state, physics-oriented Density Functional Theory </p> </li> <li> <p> Quantum chemistry </p> </li> </ul></div> <div class="para"><p>communities - in addition to several other codes.</p></div> <div class="para"><p>This is a confirmation of the fact that we have got a good grasp on the level of abstraction that can usefully be deployed within CMLComp, and is a ringing endorsement of the microformat-based approach to CML that I pioneered, and that we are basing this all upon.</p></div> <div class="technorati_tags" align="right"><small>Technorati Tags: <a href="http://technorati.com/tag/cml" rel="tag">cml</a>, <a href="http://technorati.com/tag/cmlcomp" rel="tag">cmlcomp</a>, <a href="http://technorati.com/tag/fox" rel="tag">fox</a>, <a href="http://technorati.com/tag/microformats" rel="tag">microformats</a></small></div><br/><small><a href="http://uszla.me.uk/space/blog/2008/03/28" title="link to http://uszla.me.uk/space/blog/2008/03/28">@</a></small> Fri, 28 Mar 2008 14:31:37 GMT Toby White Uszla blog http://uszla.me.uk/space/blog/2008/03/28 http://uszla.me.uk/space/blog/2008/03/28 Accessing unicode data in Fortran http://feedproxy.google.com/~r/Uszla/blog/~3/4vwD-oALPlM/13 <div class="para"><p>Historically, it was impossible to do anything useful with Unicode data in Fortran.</p></div> <div class="para"><p>While few languages come bundled with Unicode support (although increasingly these days they either do, or have an easily accessible additional Unicode library) the UTF decoding schemes were written with an eye to ease of implementation.</p></div> <div class="para"><p>However, implementing UTF en-/de-coding requires reading a file byte-by-byte - which standard Fortran never had the ability to do. (The reasons are arcane and buried in Fortran's history as a cross-platform language, back when cross-platform meant you couldn't rely on having a file-system …)</p></div> <div class="para"><p>So while it would be possible to implement an entire Unicode processor in Fortran, operating on in-memory strings of Unicode characters, it would be impossible to ever read or write those strings externally.</p></div> <div class="para"><p>Luckily, though, Fortran 2003 finally adds support for byte-wise reading of files (under the name of "stream I/O"), which means that for any compilers which support stream IO, UTF transcoding is now possible.</p></div> <div class="para"><p>So, I wrote a module to do this - full source, example and documentation <a href="http://uszla.me.uk/space/software/f-unicode" title="external link to http://uszla.me.uk/space/software/f-unicode" class="http">are all available</a>.</p></div> <br/><small><a href="http://uszla.me.uk/space/blog/2008/03/13" title="link to http://uszla.me.uk/space/blog/2008/03/13">@</a></small> Thu, 13 Mar 2008 16:15:28 GMT Toby White Uszla blog http://uszla.me.uk/space/blog/2008/03/13 http://uszla.me.uk/space/blog/2008/03/13 WKML RC-2 http://feedproxy.google.com/~r/Uszla/blog/~3/UIgASN4oUXo/11 <div class="para"><p>Following a couple of separate queries from users, I was motivated enough to update the version of <a href="http://uszla.me.uk/space/software/FoX/wkml/" title="external link to http://uszla.me.uk/space/software/FoX/wkml/" class="http">wkml</a> which is <a href="http://source.uszla.me.uk/FoX/wkml/" title="external link to http://source.uszla.me.uk/FoX/wkml/" class="http">available</a>.</p></div> <div class="para"><p>If you haven't come across it before, WKML is an output module for <a href="http://uszla.me.uk/space/software/FoX" title="external link to http://uszla.me.uk/space/software/FoX" class="http">FoX</a> which generates <a href="http://code.google.com/apis/kml/documentation/" title="external link to http://code.google.com/apis/kml/documentation/" class="http">KML</a> output. This lets you write <a href="http://earth.google.com" title="external link to http://earth.google.com" class="http">Google Earth</a> input files directly as Fortran output.</p></div> <div class="para"><p>(Large parts of it were written by <a href="http://scispace.net/gtniees/" title="external link to http://scispace.net/gtniees/" class="http">Gen-Tao Chiang</a>)</p></div> <div class="para"><p>It's still in release-candidate status (rather than full release with the rest of FoX) because of some annoying bugs. It will give wrong results when trying to draw contour plots that span the international date line; and in some corner cases for complex contours. Also, the documentation is far short of ideal.</p></div> <div class="para"><p>However, most of its functionality (for drawing points, lines, and polygons, is complete &amp; (as far as I know) free of bugs, and it has <a href="http://www.uszla.me.uk/trac/FoX/wiki/WkmlApi/" title="external link to http://www.uszla.me.uk/trac/FoX/wiki/WkmlApi/" class="http">basic documentation</a>.</p></div> <div class="para"><p>Anyway - it's there for use, subject to the caveats above.</p></div> <br/><small><a href="http://uszla.me.uk/space/blog/2008/02/11" title="link to http://uszla.me.uk/space/blog/2008/02/11">@</a></small> Mon, 11 Feb 2008 15:27:42 GMT Toby White Uszla blog http://uszla.me.uk/space/blog/2008/02/11 http://uszla.me.uk/space/blog/2008/02/11 FoX and Dalton http://feedproxy.google.com/~r/Uszla/blog/~3/O5Dc4ccuh6I/14 <div class="para"><p>This week, <a href="http://theochem.ki.ku.dk/:" title="external link to http://theochem.ki.ku.dk/:" class="http">Kurt Mikkelsen</a> of the University of Copenhagen came to visit, to talk about CML</p></div> <div class="para"><p>He's one of the developers of <a href="http://www.kjemi.uio.no/software/dalton/" title="external link to http://www.kjemi.uio.no/software/dalton/" class="http">Dalton</a>, one of the biggest quantum chemistry codes. He's interested in taking advantage of CML to manage data coming out from large-scale sets of jobs; running similar Dalton jobs over thousands of molecules, to build databases of calculated properties.</p></div> <div class="para"><p>This is very much congruent of course to some of the things that we've been doing through <a href="http://www.eminerals.org" title="external link to http://www.eminerals.org" class="http">eMinerals</a> here in Earth Sciences, and that <a href="http://wwmm.ch.cam.ac.uk/blogs/murrayrust/" title="external link to http://wwmm.ch.cam.ac.uk/blogs/murrayrust/" class="http">Peter Murray-Rust</a> has been doing in Chemistry.</p></div> <div class="para"><p>So the obvious first step was to equip Dalton with CML output. And I'm happy to announce that in a total of under 7 hours, we:</p></div> <div class="ilist"><ul> <li> <p> ported Dalton to a new platform, since the most convenient compiler to hand was <a href="http://www.g95.org" title="external link to http://www.g95.org" class="http">g95</a> on Mac OS X. </p> </li> <li> <p> updated its whole configure/build/job-submission process to allow for compiling with FoX, and dealing with an additional XML output file </p> </li> <li> <p> went through Dalton, and added CML output such that the most important quantities (molecular structure and related quantities, basis set metadata, and calculated polarizabilities up to the 3rd harmonic) are all now output to CML. </p> </li> </ul></div> <div class="para"><p>Kurt went home with a version of the Dalton source code ready to be used for his database calculations immediately (although we compiled on g95, the result is portable to any existing Dalton platform). There will be more to be done before it makes it to a public release of Dalton, of course (which only happens every three or four years anyway) - but we can welcome Dalton to the CML stable now.</p></div> <div class="para"><p>And of course, it's yet another code to add to FoX's roll of honour.</p></div> <br/><small><a href="http://uszla.me.uk/space/blog/2008/02/08/16/14" title="link to http://uszla.me.uk/space/blog/2008/02/08/16/14">@</a></small> Fri, 08 Feb 2008 16:14:15 GMT Toby White Uszla blog http://uszla.me.uk/space/blog/2008/02/08/16/14 http://uszla.me.uk/space/blog/2008/02/08/16/14