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

<channel>
	<title>Rosio Pavoris</title>
	<atom:link href="http://cairnarvon.rotahall.org/feed/" rel="self" type="application/rss+xml" />
	<link>http://cairnarvon.rotahall.org</link>
	<description>Unscientific and ultimately destructive.</description>
	<lastBuildDate>Thu, 19 Apr 2012 23:12:12 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>Adventures on the grey market</title>
		<link>http://cairnarvon.rotahall.org/2012/04/07/adventures-on-the-grey-market/</link>
		<comments>http://cairnarvon.rotahall.org/2012/04/07/adventures-on-the-grey-market/#comments</comments>
		<pubDate>Sat, 07 Apr 2012 00:16:08 +0000</pubDate>
		<dc:creator>Cairnarvon</dc:creator>
				<category><![CDATA[Miscellany]]></category>
		<category><![CDATA[Personal]]></category>

		<guid isPermaLink="false">http://cairnarvon.rotahall.org/?p=2136</guid>
		<description><![CDATA[Look at this picture, and try to guess how many of these cartridges are genuine: Hint: the correct answer is &#8220;not a damn one&#8221;. Yes, I&#8217;ve been playing a lot of Pokémon in the past year or so, so yes, it was inevitable I&#8217;d eventually attempt to acquire some of the GBA games. Belgian toy [...]]]></description>
			<content:encoded><![CDATA[<p>Look at this picture, and try to guess how many of these cartridges are genuine:</p>
<p><center><a href="/pics/pokemon-gba/emeralds_big.jpg"><img src="/pics/pokemon-gba/emeralds.jpg" alt="Emeralds" title="Money well spent" class="image" /></a></center></p>
<p>Hint: the correct answer is &#8220;not a damn one&#8221;.</p>
<p><span id="more-2136"></span></p>
<p>Yes, I&#8217;ve been playing a lot of Pokémon in the past year or so, so yes, it was inevitable I&#8217;d eventually attempt to acquire some of the GBA games. Belgian toy stores don&#8217;t tend to do trade-ins or sell old second-hand games, and I hate interacting directly with people (so eBay or the local equivalent, 2dehands.be, are out), and Amazon doesn&#8217;t deliver here, so it took me a bit to find an actual place to get them, but eventually I did find <a href="http://www.play.com/">this Amazon clone</a>, which has the added bonus of free shipping to most of Europe.<br />
I&#8217;d like to make it clear my misadventures involving Pokémon Emerald are no reflection on the website itself or most sellers using it; several sellers refunded my money when I pointed out the games were bootlegs, and I&#8217;ve had few to no issues with the other things I&#8217;ve ordered there (including three DS games and a GameCube game, controller, and memory card).</p>
<p>For Pokémon Emerald, though, holy fuck. I&#8217;ve made <i>seven</i> attempts to buy this game; the four bootlegs pictured, two orders that were refused because the seller was out of stock but forgot to take down his listing, and my personal favourite, this fucking thing:</p>
<p><center><a href="/pics/pokemon-gba/notemerald_big.jpg"><img src="/pics/pokemon-gba/notemerald.jpg" alt="Not Emerald" title="Quality" class="image" /></a></center></p>
<p>Apart from the fact that it&#8217;s not the right game, look at the effort that went into it. They wrote a (six-page, admittedly) manual. They printed a box with fancy metallic sparkles. They actually folded a cardboard thing to keep the cartridge in place as if it were the real deal. At no point did it occur to them to look at the actual box art to ensure their efforts weren&#8217;t ludicrously misdirected.<br />
The real Pokémon LeafGreen comes with a GBA wireless adaptor, by the way (because link cables are passé). This one obviously didn&#8217;t, but the manual, <i>which they wrote themselves, from scratch</i>, still promises it.</p>
<p>I do actually own a legitimate copy of LeafGreen (also without wireless adaptor, but that&#8217;s to be expected). Here it is with my legitimate copy of FireRed,<sup><a href="#f_adventures-on-the-grey-market_0" id="adventures-on-the-grey-market_0">0</a></sup> and the bootleg copy of FireRed I got on my first attempt (fucker didn&#8217;t even send me a box for that one):</p>
<p><center><a href="http://cairnarvon.rotahall.org/pics/pokemon-gba/frlg_big.jpg"><img src="http://cairnarvon.rotahall.org/pics/pokemon-gba/frlg.jpg" alt="FRLG" title="FRLG" class="image" /></a></center></p>
<p>Obvious things to notice: the bootleg has a battery (that round thing partially visible through the plastic), the real ones don&#8217;t; the Nintendo seal is oval on the bootleg; the label has a metallic effect on the genuine cartridges.<br />
One thing all of my bootlegs have in common is that when they&#8217;re started, they give a pointless message. All of the Emeralds give the following:</p>
<blockquote><p><tt>The save file will be loaded.<br />
The game can be played.</tt></p></blockquote>
<p>Except for the one that used to give that but now gives this one:</p>
<blockquote><p><tt>The save file has been erased due to corruption or damage.<br />
The game can be played.</tt></p></blockquote>
<p>(In case you were wondering why it matters to me that I have a genuine cartridge. And oh: none of the bootlegs I&#8217;ve bothered to test allow migration of Pokémon to the fourth-gen games.)</p>
<p>The bootleg FireRed and LeafGreen are terser:</p>
<blockquote><p><tt>The save file is ok.</tt></p></blockquote>
<p>Real games don&#8217;t give any message when there&#8217;s no problem. I suspect the reason bootlegs do is because the save mechanism is so closely tied to the hardware of the cartridge itself that it has to be reimplemented by the bootleggers (unlike the rest of the game, which is just a ROM ripped from a legitimate cartridge, obviously), and bootleggers don&#8217;t give a shit. Further evidence for this hypothesis is the fact that my bootleg FireRed and LeafGreen have batteries, which they presumably use to save to volatile memory, in the same way old Game Boy and Game Boy Color games did, but the GBA games no longer do (they use flash memory).</p>
<p>Incidentally, the presence of a battery on an <i>Emerald</i> cartridge is not automatic evidence of bootleggery: legitimate Ruby, Sapphire, and Emerald cartridges all have batteries, which they use to keep time, because the GBA doesn&#8217;t. When those batteries run out, you don&#8217;t lose your save (unlike you would for GB and GBC games), but you&#8217;ll lose events that rely on the clock, like berry growing and tides in the Shoal Cave. It can be replaced with relatively little risk to your game.</p>
<p>For science, here&#8217;s the backs of those Emerald cartridges, in the same order as above:</p>
<p><center><a href="http://cairnarvon.rotahall.org/pics/pokemon-gba/emeralds_back_big.jpg"><img src="http://cairnarvon.rotahall.org/pics/pokemon-gba/emeralds_back.jpg" alt="backs" title="Backs" class="image" /></a></center></p>
<p>Note that despite differing labels and cartridge plastic, three of those are actually the same circuit boards. And to give the bootleggers credit, they actually did bother to print &#8220;Nintendo&#8221; on the board just above the connectors, which is a thing that&#8217;s often mentioned in guides about spotting bootlegs; it&#8217;s in the wrong font (which annoys me in its gratuitous indifference), but a pretty casual consumer might not notice.</p>
<p>My point, I suppose, is caveat emptor. And if you&#8217;re going to buy Pokémon GBA games second-hand, ignore the guides and just check if it gives you a startup message; that seems to be the easiest and only sure-fire way to know.<br />
But my secondary point is that you should mail me your copy of Emerald if you aren&#8217;t playing it anymore. After the first two bootlegs I told myself I&#8217;d keep buying them until I either got a genuine one or spent €50, and unless one of the three most recent scammers refunds my money, I&#8217;ve hit that limit.</p>
<p>Maybe I&#8217;ll try for Ruby and Sapphire instead.</p>
<hr />
<p class="footnote"><sup><a href="#adventures-on-the-grey-market_0" id="f_adventures-on-the-grey-market_0">0</a></sup> Both of those genuine cartridges came from the same seller. Unfortunately, she doesn&#8217;t have Emerald.</p>
]]></content:encoded>
			<wfw:commentRss>http://cairnarvon.rotahall.org/2012/04/07/adventures-on-the-grey-market/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>2011 in books</title>
		<link>http://cairnarvon.rotahall.org/2012/02/15/2011-in-books/</link>
		<comments>http://cairnarvon.rotahall.org/2012/02/15/2011-in-books/#comments</comments>
		<pubDate>Wed, 15 Feb 2012 15:23:20 +0000</pubDate>
		<dc:creator>Cairnarvon</dc:creator>
				<category><![CDATA[Books]]></category>
		<category><![CDATA[Personal]]></category>

		<guid isPermaLink="false">http://cairnarvon.rotahall.org/?p=2124</guid>
		<description><![CDATA[Fine, let&#8217;s do this. Last year&#8217;s entry is here, though both it and that of the year before are still on the front page, too. Apparently I finished 64 books in 2011. Specifically, these: The Selected Works of T.S. Spivet Reif Larsen The Stuff of Thought Steven Pinker Hard-boiled Wonderland and the End of the [...]]]></description>
			<content:encoded><![CDATA[<p>Fine, let&#8217;s do this. Last year&#8217;s entry is <a href="http://cairnarvon.rotahall.org/2010/12/31/2010-in-books/">here</a>, though both it and that of the year before are still on the front page, too.<br />
Apparently I finished 64 books in 2011. Specifically, these:</p>
<p><span id="more-2124"></span></p>
<ul>
<b>The Selected Works of T.S. Spivet</b> Reif Larsen<br />
<b>The Stuff of Thought</b> Steven Pinker<br />
<b>Hard-boiled Wonderland and the End of the World</b> Haruki Murakami<br />
<b>The Humans Who Went Extinct</b> Clive Finlayson<br />
<b>Chronic City</b> Jonathan Lethem<br />
<b>Why Beauty Is Truth</b> Ian Stewart<br />
<b>The Remains of the Day</b> Kazuo Ishiguro<br />
<b>Norwegian Wood</b> Haruki Murakami<br />
<b>Letters to a Young Mathematician</b> Ian Stewart<br />
<b>The Jungle Books</b> Rudyard Kipling<br />
<b>Die Verwandlung</b> Franz Kafka<br />
<b>South of the Border, West of the Sun</b> Haruki Murakami<br />
<b>The Brain that Changes Itself</b> Norman Doidge<br />
<b>Special Topics in Calamity Physics</b> Marisha Pessl<br />
<b>A Wild Sheep Chase</b> Haruki Murakami<br />
<b>Kafka on the Shore</b> Haruki Murakami<br />
<b>Oblivion: Stories</b> David Foster Wallace<br />
<b>Sputnik Sweetheart</b> Haruki Murakami<br />
<b>The Adventures of Huckleberry Finn</b> Mark Twain<br />
<b>1089 and All That: a Journey Into Mathematics</b> David Acheson<br />
<b>Bad Science</b> Ben Goldacre<br />
<b>The Lightness of Being</b> Frank Wilczek<br />
<b>Dance Dance Dance</b> Haruki Murakami<br />
<b>Birthday Stories</b> Haruki Murakami (ed.)<br />
<b>Lights Out in Wonderland</b> Peter &#8220;DBC Pierre&#8221; Finlay<br />
<b>The Great Gatsby</b> F. Scott Fitzgerald<br />
<b>Underground</b> Haruki Murakami<br />
<b>Artificial Intelligence: A Modern Approach</b> Stuart Russell, Peter Norvig<br />
<b>McSweeney&#8217;s Thirty-Two</b> Dave Eggers (ed.)<br />
<b>The Corrections</b> Jonathan Franzen<br />
<b>Content and Consciousness</b> Daniel Dennett<br />
<b>De Eeuwige Terugkeer van het Fascisme</b> Rob Riemen<br />
<b>The Ascent of Man</b> Jacob Bronowski<br />
<b>after the quake</b> Haruki Murakami<br />
<b>The Bottom Billion</b> Paul Collier<br />
<b>Haroun and the Sea of Stories</b> Salman Rushdie<br />
<b>The Crucible</b> Arthur Miller<br />
<b>Remarkable Creatures</b> Sean B. Carroll<br />
<b>Flaubert&#8217;s Parrot</b> Julian Barnes<br />
<b>What I Talk About When I Talk About Running</b> Haruki Murakami<br />
<b>Foundation</b> Isaac Asimov<br />
<b>Blind Willow, Sleeping Woman</b> Haruki Murakami<br />
<b>After Dark</b> Haruki Murakami<br />
<b>Taming the Infinite</b> Ian Stewart<br />
<b>The Grand Design</b> Stephen Hawking, Leonard Mlodinow<br />
<b>Schaum&#8217;s Outlines: Logic</b> John Nolt, Dennis Rohatyn, Achille Varzi<br />
<b>Hitch-22</b> Christopher Hitchens<br />
<b>I Shall Wear Midnight</b> Terry Pratchett<br />
<b>The Discomfort Zone</b> Jonathan Franzen<br />
<b>Alex&#8217;s Adventures in Numberland</b> Alex Bellos<br />
<b>The Magic of Reality</b> Richard Dawkins<br />
<b>1000 Years of Annoying the French</b> Stephen Clarke<br />
<b>Mathematics Without Fear</b> Lawrence Potter<br />
<b>Mathematics of Life</b> Ian Stewart<br />
<b>Ubik</b> Philip K. Dick<br />
<b>Naked Lunch</b> William S. Burroughs<br />
<b>Go the Fuck to Sleep</b> Adam Mansbach<br />
<b>Chaos</b> James Gleick<br />
<b>Fury</b> Salman Rushdie<br />
<b>I Am Number Four</b> James Frey, Jobie Hughes<br />
<b>Warped Passages</b> Lisa Randall<br />
<b>The Emperor of All Maladies</b> Siddhartha Mukherjee<br />
<b>The Beetle</b> Richard Marsh<br />
<b>The Rational Optimist</b> Matt Ridley
</ul>
<p>Would&#8217;ve been more, except I bought a DS in July and Pokémon has interfered with my reading. My goal for the year was 50, as it always is, so I did at least make that.</p>
<p>I also said 2011 was going to be the year in which I read everything Haruki Murakami has ever written (that I hadn&#8217;t read the year before), and while I didn&#8217;t do that, I got a lot closer than I did for Margaret Atwood in 2010; I read everything he&#8217;s ever written that&#8217;s been translated to English and released outside of Japan (<i>Hear the Wind Sing</i> and <i>Pinball, 1973</i> have been translated into English, but those translations were never released outside of Japan), except for <i>1Q84</i>, which I did buy and start in, but didn&#8217;t manage to finish.<br />
I can&#8217;t recommend you try to do this. Any individual book of Murakami&#8217;s is pretty good to great, but reading all of them that quickly will make you dislike either the books or Murakami himself. His non-fiction is merely boring for the most part, but the shared aspects of his fiction show him to be an unpleasant, frustrated little man.</p>
<p>I&#8217;ve written reviews of nearly everything I&#8217;ve read, so if you&#8217;re looking for those I suggest you <a href="http://www.goodreads.com/review/list/3452722-koen-crolla?order=a&#038;read_at=2011&#038;sort=date_read">go to GoodReads</a>.<br />
Since I did this last year, I might as well do it now:</p>
<h3>Better than expected</h3>
<p><i><a href="http://www.goodreads.com/review/show/224367157">The Emperor of All Maladies</a></i>, by Siddhartha Mukherjee, was surprisingly good. It&#8217;s about cancer and the history of cancer research, and it&#8217;s pretty US-centric but otherwise very interesting. Since everyone will either get cancer themselves or be close to someone who will, there&#8217;s really nobody who can afford not to read it.</p>
<p><i><a href="http://www.goodreads.com/review/show/225907450">Warped Passages</a></i> by Lisa Randall is possibly the best pop-sci treatment of modern physics I&#8217;ve seen, despite Lisa Randall being a pretty unpleasant person. As I said in my review, it&#8217;s possibly the first book in its genre that I&#8217;ve read that didn&#8217;t leave me feeling like modern physics is just too complicated and esoteric now to be viable subject matter for pop sci.</p>
<p><i><a href="http://www.goodreads.com/review/show/238246009">The Beetle</a></i> by Richard Marsh is the only fiction entry here; a decade or so ago my expectations of it would have been spot on, but years of Lovecraft and Stoker and (even worse) their imitators have destroyed my expectations of classic horror and left me cynical.</p>
<h3>Worse than expected</h3>
<p>Matt Ridley&#8217;s <i><a href="http://www.goodreads.com/review/show/238246760">The Rational Optimist</a></i>. This is the same Ridley who wrote <i>The Red Queen</i>, which I gave five stars in 2008. Apparently he&#8217;s like Penn &#038; Teller in that he&#8217;s only capable of intelligent discourse on subjects on which his political masters have no opinion; for P&#038;T this is the Cato Institute, for Ridley it&#8217;s the British Tory party.</p>
<p>Oh, and <i><a href="http://www.goodreads.com/review/show/166954308">Hitch-22</a></i>, by Christopher Hitchens, I guess. I never really cared for him and my expectations weren&#8217;t <i>too</i> high, but he still managed to be worse than I imagined. I&#8217;m not even talking about the casual misogyny everyone has come to expect of him by now; I&#8217;m talking about how every position Hitchens has ever held he has only held because his father or his brother have held the opposite. He sure wasted shit-tons of paper on rationalisations trying to convince himself otherwise, though.</p>
<p>Like last year, there are also a lot of books that were shit that I expected to be, and books that were good that I expected to be. GoodReads lets you sort by rating, if you&#8217;re interested.<br />
Either way, discuss.</p>
<p><b>tl;dr:</b> <a href="http://www.goodreads.com/review/list/3452722-koen-crolla?read_at=2011&#038;sort=date_read&#038;order=a">GoodReads</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://cairnarvon.rotahall.org/2012/02/15/2011-in-books/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>So I got a switch for Christmas&#8230;</title>
		<link>http://cairnarvon.rotahall.org/2012/02/09/so-i-got-a-switch-for-christmas/</link>
		<comments>http://cairnarvon.rotahall.org/2012/02/09/so-i-got-a-switch-for-christmas/#comments</comments>
		<pubDate>Thu, 09 Feb 2012 22:33:11 +0000</pubDate>
		<dc:creator>Cairnarvon</dc:creator>
				<category><![CDATA[Personal]]></category>

		<guid isPermaLink="false">http://cairnarvon.rotahall.org/?p=2116</guid>
		<description><![CDATA[&#8230; and things got a bit out of hand. Building a LackRack is some sort of rite of passage for sysadmins, I think, and I am, after all a sys- and network admin first and a programmer second. Initially the idea was just to have the switch, and the second table was just to make [...]]]></description>
			<content:encoded><![CDATA[<p>&#8230; and things got a bit out of hand.</p>
<p><center><a href="/pics/lackrack/lackrack_front.jpg"><img src="/pics/lackrack/small/lackrack_front.jpg" alt="LackRack" class="image" /></a></center></p>
<p><span id="more-2116"></span></p>
<p>Building a <a href="http://lackrack.org/">LackRack</a> is some sort of rite of passage for sysadmins, I think, and I am, after all a sys- and network admin first and a programmer second. Initially the idea was just to have the switch, and the second table was just to make it look like a respectable piece of furniture instead of a €5 Ikea table (<a href="http://twitpic.com/839ntk">as per this picture I posted a month ago</a>), but then I figured a power strip would be useful, and in the process of locating a Belgian supplier I found <a href="http://flightcase-brico.be/index.php?categoryID=26">more things I wanted</a>.<br />
I did add the power strip; I added two, in fact. Here&#8217;s the front one:</p>
<p><center><a href="/pics/lackrack/power_front.jpg"><img src="/pics/lackrack/small/power_front.jpg" alt="front power strip" class="image" /></a></center></p>
<p>It&#8217;s sunken not to protect plugs or even to help support the 4U drawer above it (which needs the support; it&#8217;s solid steel and weighs 17 kg), but because the power cable is to the side and there was no other way to mount it. Still, it was the only power strip available, and we make do.<br />
(Notice that it also has Schuko sockets rather than the more sensible CEE 7/5. Fortunately everything I wanted to use it for has either CEE 7/7 plugs or Europlugs.)</p>
<p>Here&#8217;s the view from the back, showing the second power strip:</p>
<p><center><a href="/pics/lackrack/lackrack_back.jpg"><img src="/pics/lackrack/small/lackrack_back.jpg" alt="LackRack back" class="image" /></a></center></p>
<p>Note the connector plates with which I <i>expertly</i> affixed the top table to the bottom. There&#8217;s four such plates because that&#8217;s all I could find in our basement. On the front legs they&#8217;re on the side, for looks.<br />
The dorsal power strip faces inward, because there&#8217;s no reason for it not to. It holds everything that needs to have power 24/7, including the front power strip, the switch, my electric toothbrush, and the laptop on the shelf under the switch.<br />
The frontal power strip is meant to be switched off at night, because I have a lot of things that have too many bright lights to keep them on in my bedroom, including my Wii, the inductive charger for the Wii remote, and the Roomba, for which there&#8217;s just enough space underneath.</p>
<p><center><a href="/pics/lackrack/power_back.jpg"><img src="/pics/lackrack/small/power_back.jpg" alt="back power strip" class="image" /></a></center></p>
<p>That&#8217;s the switch&#8217;s power cable, plugged into the dorsal strip. The duct tape shows it&#8217;s professional.<br />
Here&#8217;s the whole thing from the side:</p>
<p><center><a href="/pics/lackrack/lackrack_side.jpg"><img src="/pics/lackrack/small/lackrack_side.jpg" alt="side view" class="image" /></a></center></p>
<p>Ignore the dust and the fingerprints.<br />
The shelf doesn&#8217;t look too stable, which may be a problem. The table legs are hollow at the point where it&#8217;s attached, and it&#8217;s not particularly light-weight, being entirely steelen as well. Still, it seems to be holding. I&#8217;ll add some sort of reinforcing bracket if I find one.<br />
It slides out, too!</p>
<p><center><a href="/pics/lackrack/shelf.jpg"><img src="/pics/lackrack/small/shelf.jpg" alt="shelf!" class="image" /></a></center></p>
<p>And here&#8217;s what the whole thing looks like when it&#8217;s running:</p>
<p><center><a href="/pics/lackrack/running.jpg"><img src="/pics/lackrack/small/running.jpg" alt="on" class="image" /></a></center></p>
<p>Again, ignore the dust and general grime. My room needs cleaning and will get it tomorrow. Also ignore the quality of the connector attachment on the leftmost cable. I didn&#8217;t do it, though I will redo it, also tomorrow.<br />
The point of the laptop is to have a shell server (as I&#8217;m apparently graduating this year, which means I won&#8217;t have access to the one I&#8217;ve been using for the past half-decade anymore) and, as soon as the new hard drive arrives, a backup server. I was initially going to get a proper rack-mounted server instead, but my old laptop still works, so why not use it?</p>
<p>The total cost of this is €568.81 (€289.90 for the switch, €45.98 for the cable and connectors (admittedly I have 98 meters and 44 connectors left, which is what the drawer is for), €222.95 for the shelf, drawer, and power strips (including automatic discount and shipping; LackRack or not, 19-inch equipment isn&#8217;t cheap), and €9.98 for the tables), plus whatever the old laptop and the handful of screws I found in the basement cost. I&#8217;d say it&#8217;s worth it.</p>
<p>Haskell is less impressed.</p>
<p><center><a href="/pics/lackrack/hasks.jpg"><img src="/pics/lackrack/small/hasks.jpg" alt="gog" class="image" /></a></center></p>
<p>(If you&#8217;re in Belgium and want to do something like this, I recommend both <a href="http://www.tones.be/">Tones</a>, where I got the switch, the cable, and the connectors (not to mention my Thinkpad and my mom&#8217;s inexplicable iPad), and <a href="http://flightcase-brico.be/">Flightcase-brico.be</a>, where I got the other things. The former has free shipping for orders over €200 and the latter is much faster than you&#8217;d expect. Be aware that the latter lists prices without BTW, and BTW is 21% on everything. You don&#8217;t need a credit card for either one.)</p>
]]></content:encoded>
			<wfw:commentRss>http://cairnarvon.rotahall.org/2012/02/09/so-i-got-a-switch-for-christmas/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>ClusterDebian 1.0</title>
		<link>http://cairnarvon.rotahall.org/2011/05/28/clusterdebian-1-0/</link>
		<comments>http://cairnarvon.rotahall.org/2011/05/28/clusterdebian-1-0/#comments</comments>
		<pubDate>Sat, 28 May 2011 00:23:53 +0000</pubDate>
		<dc:creator>Cairnarvon</dc:creator>
				<category><![CDATA[Miscellany]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://cairnarvon.rotahall.org/?p=2036</guid>
		<description><![CDATA[So that thing I hinted at earlier is about as done as I care to get it. Officially the point of this project was for the school to have something with which to replace ClusterKnoppix for their Besturingssystemen II class, but really I just wanted to have something nicer to make use of my ever-growing [...]]]></description>
			<content:encoded><![CDATA[<p>So <a href="http://cairnarvon.rotahall.org/2011/05/01/so/">that thing</a> I hinted at earlier is <a href="https://github.com/Cairnarvon/ClusterDebian">about as done as I care to get it.</a></p>
<p><center><a href="/pics/clusterdebian.png"><img src="/pics/clusterdebian_small.png" class="image" alt="ClusterDebian" /></a></center></p>
<p>Officially the point of this project was for the school to have something with which to replace ClusterKnoppix for their Besturingssystemen II class, but really I just wanted to have something nicer to make use of my ever-growing pile of old computers, which is why I finished it. The README explains. (HPC there stands for &#8220;high-performance computing&#8221; rather than &#8220;Hasty Pudding cipher&#8221;.)<br />
What I need now is people to test it, ideally by building images and then trying them.</p>
<p>If you&#8217;d rather not put that kind of effort in, I&#8217;ve also <a href="/misc/clusterdebian.iso">pre-built an image</a> (291 MB). It doesn&#8217;t come with X to save space, but it does come with (what else?) <a href="https://gist.github.com/994114">this Open MPI tripcode finder</a> I wrote a while ago. It&#8217;s not particularly fast, but it reports its progress if you poke it with SIGUSR1 (as in <code>pkill -USR1 tripfind</code>).<br />
The unprivileged user is called <code>gjs</code>, and the password for both him and root is <code>t</code>. I&#8217;ve also included the <a href="http://www.bindshell.net/tools/johntheripper.html">MPI-patched JtR</a> tarball in the home directory for you to build, if that&#8217;s less pointless.</p>
<p>Feedback appreciated, even if you don&#8217;t find any problems. If you find this project useful at all, or if you have any suggestions, I&#8217;d like to hear about it.</p>
]]></content:encoded>
			<wfw:commentRss>http://cairnarvon.rotahall.org/2011/05/28/clusterdebian-1-0/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Automatic language classification, the slow way</title>
		<link>http://cairnarvon.rotahall.org/2011/05/10/automatic-language-classification/</link>
		<comments>http://cairnarvon.rotahall.org/2011/05/10/automatic-language-classification/#comments</comments>
		<pubDate>Mon, 09 May 2011 22:18:23 +0000</pubDate>
		<dc:creator>Cairnarvon</dc:creator>
				<category><![CDATA[CompSci]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://cairnarvon.rotahall.org/?p=1977</guid>
		<description><![CDATA[#!/usr/bin/python2 import sys import bz2 def classify(text, langs=('english', 'german', 'french')): results = {} for lang in langs: with open(lang + '.txt') as f: corpus = f.read() compressed = len(bz2.compress(corpus)) results[lang] = len(bz2.compress(corpus + text)) - compressed return sorted(results, key=results.__getitem__) if __name__ == '__main__': print "Most likely %s." % classify(sys.stdin.read())[0].capitalize() $ wget -qO - http://www.gutenberg.org/ebooks/31469.txt.utf8 &#124; [...]]]></description>
			<content:encoded><![CDATA[<pre style="font-size: inherit"><span style="color: #999988"><i>#!/usr/bin/python2</i></span>

<b>import</b> <span style="color: #555555">sys</span>
<b>import</b> <span style="color: #555555">bz2</span>

<b>def</b> <span style="color: #990000"><b>classify</b></span>(text, langs<b>=</b>(<span style="color: #bb8844">'<a href="/misc/corpora/english.txt">english</a>'</span>, <span style="color: #bb8844">'<a href="/misc/corpora/german.txt">german</a>'</span>, <span style="color: #bb8844">'<a href="/misc/corpora/french.txt">french</a>'</span>)):
    results <b>=</b> {}
    <b>for</b> lang <b>in</b> langs:
        <b>with</b> <span style="color: #999999">open</span>(lang <b>+</b> <span style="color: #bb8844">'.txt'</span>) <b>as</b> f:
            corpus <b>=</b> f<b>.</b>read()

        compressed <b>=</b> <span style="color: #999999">len</span>(bz2<b>.</b>compress(corpus))
        results[lang] <b>=</b> <span style="color: #999999">len</span>(bz2<b>.</b>compress(corpus <b>+</b> text)) <b>-</b> compressed

    <b>return</b> <span style="color: #999999">sorted</span>(results, key<b>=</b>results<b>.</b>__getitem__)

<b>if</b> __name__ <b>==</b> <span style="color: #bb8844">'__main__'</span>:
    <b>print</b> <span style="color: #bb8844">"Most likely </span><span style="color: #bb8844">%s</span><span style="color: #bb8844">."</span> <b>%</b> classify(sys<b>.</b>stdin<b>.</b>read())[<span style="color: #009999">0</span>]<b>.</b>capitalize()</pre>
<hr />
<p><code>$ wget -qO - http://www.gutenberg.org/ebooks/31469.txt.utf8 | ./classific.py<br />
Most likely English.<br />
$ wget -qO - http://www.gutenberg.org/ebooks/22367.txt.utf8 | ./classific.py<br />
Most likely German.<br />
$ wget -qO - http://www.gutenberg.org/ebooks/4968.txt.utf8 | ./classific.py<br />
Most likely French.</code></p>
]]></content:encoded>
			<wfw:commentRss>http://cairnarvon.rotahall.org/2011/05/10/automatic-language-classification/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>So.</title>
		<link>http://cairnarvon.rotahall.org/2011/05/01/so/</link>
		<comments>http://cairnarvon.rotahall.org/2011/05/01/so/#comments</comments>
		<pubDate>Sun, 01 May 2011 18:53:01 +0000</pubDate>
		<dc:creator>Cairnarvon</dc:creator>
				<category><![CDATA[Miscellany]]></category>

		<guid isPermaLink="false">http://cairnarvon.rotahall.org/?p=1971</guid>
		<description><![CDATA[If you were a USB/PXE-bootable Linux distro for HPC, what kind of features would you want to have?]]></description>
			<content:encoded><![CDATA[<p>If you were a USB/PXE-bootable Linux distro for HPC, what kind of features would you want to have?</p>
]]></content:encoded>
			<wfw:commentRss>http://cairnarvon.rotahall.org/2011/05/01/so/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>2010 in books</title>
		<link>http://cairnarvon.rotahall.org/2010/12/31/2010-in-books/</link>
		<comments>http://cairnarvon.rotahall.org/2010/12/31/2010-in-books/#comments</comments>
		<pubDate>Fri, 31 Dec 2010 18:34:48 +0000</pubDate>
		<dc:creator>Cairnarvon</dc:creator>
				<category><![CDATA[Books]]></category>
		<category><![CDATA[Personal]]></category>

		<guid isPermaLink="false">http://cairnarvon.rotahall.org/?p=1883</guid>
		<description><![CDATA[Let&#8217;s do this while I&#8217;m still sort of sober. Looks like I didn&#8217;t blog a lot this year. Last year&#8217;s book post is still on the front page. Anyway, I didn&#8217;t finish quite as many books this year as I did then, but I surpassed my annual target of fifty; I finished fifty-eight: On the [...]]]></description>
			<content:encoded><![CDATA[<p>Let&#8217;s do this while I&#8217;m still sort of sober.<br />
Looks like I didn&#8217;t blog a lot this year. Last year&#8217;s book post is still on the front page. Anyway, I didn&#8217;t finish quite as many books this year as I did <a href="/2009/12/31/overshot-a-bit/">then</a>, but I surpassed my annual target of fifty; I finished fifty-eight:</p>
<p><span id="more-1883"></span></p>
<ul>
<b>On the Road</b> Jack Kerouac<br />
<b>The Robber Bride</b> Margaret Atwood<br />
<b>Does God Play Dice?</b> Ian Stewart<br />
<b>The Pickwick Papers</b> Charles Dickens<br />
<b>Prolog Programming for Articial Intelligence</b> Ivan Bratko<br />
<b>Eating Animals</b> Jonathan Safran Foer<br />
<b>Alias Grace</b> Margaret Atwood<br />
<b>A Strange Manuscript Found in a Copper Cylinder</b> James De Mille<br />
<b>The People&#8217;s Train</b> Thomas Keneally<br />
<b>Le tour du monde en 80 jours</b> Jules Verne<br />
<b>Wuthering Heights</b> Emily Brontë<br />
<b>You Are a Mathematician</b> David Wells<br />
<b>Why Evolution is True</b> Jerry Coyne<br />
<b>The Adventures of Sherlock Holmes</b> Arthur Conan Doyle<br />
<b>Cinq semaines en ballon</b> Jules Verne<br />
<b>The Good Man Jesus and the Scoundrel Christ</b> Philip Pullman<br />
<b>The Blind Assassin</b> Margaret Atwood<br />
<b>Northanger Abbey</b> Jane Austen<br />
<b>A Clockwork Orange</b> Anthony Burgess<br />
<b>And Another Thing&#8230;</b> Eoin Colfer<br />
<b>The Graveyard Book</b> Neil Gaiman<br />
<b>Cloud Atlas</b> David Mitchell<br />
<b>River Out of Eden</b> Richard Dawkins<br />
<b>The City Curious</b> Jean de Bosschère<br />
<b>Discrete Mathematics</b> Seymour Lipschutz, Marc Lipson<br />
<b>Byzantium</b> Judith Herrin<br />
<b>Oryx and Crake</b> Margaret Atwood<br />
<b>Hard Times</b> Charles Dickens<br />
<b>Cradle to Cradle</b> Michael Braungart, William McDonough<br />
<b>The Penguin Dictionary of Curious and Interesting Numbers</b> David Wells<br />
<b>Surfacing</b> Margaret Atwood<br />
<b>Blood Meridian</b> Cormac McCarthy<br />
<b>The Book Thief</b> Markus Zusak<br />
<b>Little Women</b> Louisa M. Alcott<br />
<b>Year of the Flood</b> Margaret Atwood<br />
<b>Unseen Academicals</b> Terry Pratchett<br />
<b>The Adventures of Tom Sawyer</b> Mark Twain<br />
<b>Moral Disorder</b> Margaret Atwood<br />
<b>Bodily Harm</b> Margaret Atwood<br />
<b>Cows in the Maze</b> Ian Stewart<br />
<b>The Lottery and Other Stories</b> Shirley Jackson<br />
<b>Brave New World Revisited</b> Aldous Huxley<br />
<b>Who Moved My Cheese?</b> Spencer Johnson<br />
<b>Reading Lolita in Tehran</b> Azar Nafisi<br />
<b>Writing Scientific Software</b> Suely Oliveira, David Stewart<br />
<b>Science: a Four Thousand Year History</b> Patricia Fara<br />
<b>Professor Stewart&#8217;s Hoard of Mathematical Treasures</b> Ian Stewart<br />
<b>My Man Jeeves</b> P.G. Wodehouse<br />
<b>Linear Algebra</b> Seymour Lipschutz, Marc Lipson<br />
<b>The Bro Code</b> Matt Kuhn<br />
<b>Cat&#8217;s Eye</b> Margaret Atwood<br />
<b>The Black Cloud</b> Fred Hoyle<br />
<b>The Fry Chronicles</b> Stephen Fry<br />
<b>The Wind-Up Bird Chronicle</b> Haruki Murakami<br />
<b>Fight Club</b> Charles Palahniuk<br />
<b>The Language Instinct</b> Steven Pinker<br />
<b>The Elephant Vanishes</b> Haruki Murakami<br />
<b>Two Treatises of Government and a Letter Concerning Toleration</b> John Locke
</ul>
<p>I said that 2010 was going to be the year in which I read everything Margaret Atwood has ever written, but I didn&#8217;t manage that. I read everything she wrote that was available in Leuven&#8217;s bookstores, but she&#8217;s just written too damn much. Maybe I&#8217;ll round off the remainder next year, but I think I&#8217;m going to focus on Haruki Murakami instead; while his books haven&#8217;t changed my mind about reading in translation, the two I&#8217;ve read have been good enough to justify it.<br />
As before, I&#8217;ve written individual reviews of nearly everything I read this year, but here&#8217;s a round-up anyway:</p>
<h3>Better than expected</h3>
<p>As said, Murakami. Despite its fanbase, <a href="http://www.goodreads.com/review/show/126429540"><i>The Wind-Up Bird Chronicle</i></a> is legitimately good, and the short stories in <a href="http://www.goodreads.com/review/show/136530677"><i>The Elephant Varnishes</i></a> were excellent as well.<br />
<a href="http://www.goodreads.com/review/show/95186140"><i>Why Evolution is True</i></a> by Jerry Coyne was also surprisingly good. I didn&#8217;t expect it to be bad, but I also didn&#8217;t expect it to be better than, say, Dawkins&#8217; own <i>The Greatest Show on Earth</i>, which set out to do much the same thing as WEIT; but it is.<br />
Judith Herrin&#8217;s <a href="http://www.goodreads.com/review/show/102245599"><i>Byzantium</i></a> was nice as well, and a good introduction to what is often a blind spot in world history. I picked it up on impulse, because it was there rather than because I&#8217;d heard of it, and that usually doesn&#8217;t turn out well. It did this time.<br />
Also better than expected was Fred Hoyle&#8217;s <a href="http://www.goodreads.com/review/show/131504540"><i>The Black Cloud</i></a>, but my expectations of that were very low because I know what kind of a person Fred Hoyle was, and my opinion of science fiction is justifiably low to begin with.<br />
And finally, Jane Austen&#8217;s <a href="http://www.goodreads.com/review/show/99831228"><i>Northanger Abbey</i></a>. I wouldn&#8217;t necessarily call it excellent in its own right, but it&#8217;s a lot better than Austen usually is.</p>
<h3>Worse than expected</h3>
<p>Probably just Patricia Fara&#8217;s <a href="http://www.goodreads.com/review/show/124868312"><i>Science: a Four Thousand Year History</i></a>. I only expected it to be good because of the pleasing heaviness of the paper and the quality of the print and the illustrations, but it turned out to be Mary Midgley&#8217;s strain of science- and scientist-bashing.<br />
It&#8217;s by no means the only terrible book I read this year, but my expectations are very low in general. Maybe there should be another category.</p>
<h3>Offensively but expectedly terrible</h3>
<p><a href="http://www.goodreads.com/review/show/94562938"><i>On the Road</i></a>, Jack Kerouac; <a href="http://www.goodreads.com/review/show/99149405"><i>And Another Thing&#8230;</i></a>, Eoin Colfer; <a href="http://www.goodreads.com/review/show/94562934"><i>Cloud Atlas</i></a>, David Mitchell; <a href="http://www.goodreads.com/review/show/102245556"><i>Blood Meridian</i></a>, Cormac McCarthy; <a href="http://www.goodreads.com/review/show/125016289"><i>Who Moved My Cheese?</i></a>, Spencer Johnson; <a href="http://www.goodreads.com/review/show/135453278"><i>Fight Club</i></a>, Charles Palahniuk; <a href="http://www.goodreads.com/review/show/136530562"><i>The Language Instinct</i></a>, Steven Pinker.</p>
<p>Everything else was either &#8220;merely&#8221; and expectedly bad (Dickens, Burgess, &#038;c.), expectedly alright (Atwood, Dawkins, &#038;c.), or just pretty unremarkable (Keneally, Verne, &#038;c.). More reviews at <a href="http://www.goodreads.com/Cairnarvon">GoodReads</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://cairnarvon.rotahall.org/2010/12/31/2010-in-books/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Processing constraints is easy</title>
		<link>http://cairnarvon.rotahall.org/2010/06/20/processing-constraints-is-easy/</link>
		<comments>http://cairnarvon.rotahall.org/2010/06/20/processing-constraints-is-easy/#comments</comments>
		<pubDate>Sun, 20 Jun 2010 04:39:44 +0000</pubDate>
		<dc:creator>Cairnarvon</dc:creator>
				<category><![CDATA[CompSci]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://cairnarvon.rotahall.org/?p=1816</guid>
		<description><![CDATA[Alright, we&#8217;ve covered search trees in some detail, and they work great for problems where we have clear states and rules of production to move from one state to the next. Sometimes that&#8217;s not a very convenient way to state a problem, though, and a more natural way to think about things is as a [...]]]></description>
			<content:encoded><![CDATA[<p>Alright, we&#8217;ve covered search trees in some detail, and they work great for problems where we have clear states and rules of production to move from one state to the next. Sometimes that&#8217;s not a very convenient way to state a problem, though, and a more natural way to think about things is as a bunch of variables which can take values in a certain <b>domain</b>, and a number of <b>constraints</b> which describe the relationships of these variables to each other.<br />
The canonical example here is Dijkstra&#8217;s <b>eight queens problem</b>. However, that&#8217;s been done to death, so let&#8217;s instead have two queens and seven knights, and instead of the usual 8×8 chess board, let&#8217;s have a 6×6 one.</p>
<p><center><img src="/pics/notqueens.png" alt="not queens problem" class="image" /></center></p>
<p><span id="more-1816"></span></p>
<p>In case you aren&#8217;t familiar with the problem, the idea is to place all the pieces on the board in such a way that none of them threatens any other.<br />
Clearly we have nine variables (two queens and seven knights), and the domain for each of them is any of the thirty-six positions on the board, represented as a tuple of numbers to indicate the row and column. In Python, we could represent this like this:</p>
<pre>&gt; domains = {&#39;Q1&#39;: set(&#91;(a, b) for a in range(6) for b in range(6)&#93;),
&gt;            &#39;Q2&#39;: set(&#91;(a, b) for a in range(6) for b in range(6)&#93;),
&gt;            &#39;K1&#39;: set(&#91;(a, b) for a in range(6) for b in range(6)&#93;),
&gt;            &#39;K2&#39;: set(&#91;(a, b) for a in range(6) for b in range(6)&#93;),
&gt;            &#39;K3&#39;: set(&#91;(a, b) for a in range(6) for b in range(6)&#93;),
&gt;            &#39;K4&#39;: set(&#91;(a, b) for a in range(6) for b in range(6)&#93;),
&gt;            &#39;K5&#39;: set(&#91;(a, b) for a in range(6) for b in range(6)&#93;),
&gt;            &#39;K6&#39;: set(&#91;(a, b) for a in range(6) for b in range(6)&#93;),
&gt;            &#39;K7&#39;: set(&#91;(a, b) for a in range(6) for b in range(6)&#93;)}
&gt;
&gt; pieces = set(domains.keys())
&gt; queens = set(&#91;&#39;Q1&#39;, &#39;Q2&#39;&#93;)
&gt; knights = pieces - queens</pre>
<p>(Using <code>set</code>s not (primarily) because I&#8217;m worried there would be duplicate entries there, but because Python&#8217;s <code>set</code>s have some useful operations defined on them that <code>list</code>s don&#8217;t, as will become clear.)</p>
<p>Representing the constraints may be a bit trickier. We&#8217;ll only be working with <b>arc constraints</b> (that is, constraints that apply to exactly two variables), because that makes sense, and it turns out that higher-order constraints aren&#8217;t much more useful.<sup><a href="#f_processing-constraints-is-easy_0" id="processing-constraints-is-easy_0">0</a></sup> Should you have any single-variable constraints, those can be applied directly to reduce the domains in advance, obviously.<br />
There are a lot of ways to represent this, but I&#8217;m going to go with a class that stores the two variables the constraint applies to, plus a constraint function, which operates on two values from the domains of the variables and tells you whether the constraint is satisfied or not. The class also has a <code>valid</code> method, which just applies the constraint function.</p>
<pre>&gt; class Constraint():
&gt;     def __init__(self, p1, p2, constr_fun):
&gt;         self.p1, self.p2, self.constr_fun = p1, p2, constr_fun
&gt;
&gt;     def valid(self, a, b):
&gt;         return self.constr_fun(a, b)</pre>
<p>Now for the constraint functions themselves. Remember, these functions take two values from two domains, and return <code>False</code> if the first piece threatens the second (because we&#8217;re looking for situations where that doesn&#8217;t happen), and <code>True</code> otherwise.<br />
A queen threatens everything on her row, column and diagonals, so her function looks like this:</p>
<pre>&gt; def queen_cf(queen, other):
&gt;     return abs(queen&#91;0&#93; - other&#91;0&#93;) != abs(queen&#91;1&#93; - other&#91;1&#93;) &#92;
&gt;        and queen&#91;0&#93; != other&#91;0&#93; &#92;
&gt;        and queen&#91;1&#93; != other&#91;1&#93;</pre>
<p>The knight threatens everything two moves in the horizontal or vertical direction plus one in the orthogonal, so its function looks like this:</p>
<pre>&gt; def knight_cf(knight, other):
&gt;     if other&#91;0&#93; in (knight&#91;0&#93; - 2, knight&#91;0&#93; + 2):
&gt;         return other&#91;1&#93; not in (knight&#91;1&#93; - 1, knight&#91;1&#93; + 1)
&gt;
&gt;     if other&#91;1&#93; in (knight&#91;1&#93; - 2, knight&#91;1&#93; + 2):
&gt;         return other&#91;0&#93; not in (knight&#91;0&#93; - 1, knight&#91;0&#93; + 1)
&gt;
&gt;     return True</pre>
<p>(Does it matter that it ignores the limits of the board? Not really: there will never be a piece outside of the board, but it does no harm to look. Explicitly checking board limits isn&#8217;t going to save any time.)</p>
<p>Finally, an optional constraint. Consider the following two solutions to our problem:</p>
<p><center><img src="/pics/constr1.png" class="image" /> <img src="/pics/constr2.png" class="image" /></center></p>
<p>These are equivalent in every way that matters, of course, but will be returned as different solutions by our algorithm as written. You might think this isn&#8217;t a big deal, but there are 2! × 7! identical variants of every possible solution, and there are (it turns out) twenty-two legitimate solutions; paring down 221,760 solutions to find the twenty-two unique ones would be a challenge in its own right.<br />
So let&#8217;s enforce the constraint that the position of <code>Q1</code> must be strictly less than that of <code>Q2</code>, for some unambiguous ordering of the board&#8217;s squares, and the same for any knights compared to knights with a higher index. This will ensure that each solution found is genuinely unique. Fortunately, Python makes this easy.</p>
<pre>&gt; def index_cf(low, high):
&gt;     return low &#60; high</pre>
<p>(Notice that this also implies that no two pieces can ever occupy the same square; otherwise we&#8217;d have to introduce another constraint for that, or modify our knight function (the queen function already implies it).)</p>
<p>Building our list of constraints is then relatively straightforward.</p>
<pre>&gt; constraints = &#91;Constraint(q, p, queen_cf) for q in queens &#92;
&gt;                                           for p in pieces - set(&#91;q&#93;)&#93; &#92;
&gt;             + &#91;Constraint(k, p, knight_cf) for k in knights &#92;
&gt;                                            for p in pieces - set(&#91;k&#93;)&#93; &#92;
&gt;             + &#91;Constraint(&#34;Q1&#34;, &#34;Q2&#34;, index_cf)&#93; &#92;
&gt;             + &#91;Constraint(a, b, index_cf) for a in knights &#92;
&gt;                                           for b in filter(lambda n: n &#62; a,
&gt;                                                           knights)&#93;</pre>
<p>And hey, that last constraint function means we can pare down our domains already: <code>Q1</code> will never be in the highest square, because if there&#8217;s a queen there, it will be <code>Q2</code>. Similarly, <code>Q2</code> will never be in the lowest, and any given knight will never occupy six squares at the ends of the board. By pruning our domains now, we&#8217;ll reduce our potential search space from 36<sup>9</sup> to 35<sup>2</sup> × 30<sup>7</sup>, which is a savings of over 76 <i>trillion</i>.<sup><a href="#f_processing-constraints-is-easy_1" id="processing-constraints-is-easy_1">1</a></sup><br />
Since each constraint has the potential to prune the domains of the variables it affects, it makes sense to do this as a method of the <code>Constraint</code> class.</p>
<pre>&gt;     def prune_domains(self):
&gt;         p1_domain, p2_domain = domains&#91;self.p1&#93;, domains&#91;self.p2&#93;
&gt;         p1_new_domain, p2_new_domain = set(), set()
&gt;
&gt;         for v1 in p1_domain:
&gt;             for v2 in p2_domain:
&gt;                 if self.constr_fun(v1, v2):
&gt;                     p1_new_domain |= set(&#91;v1&#93;)
&gt;                     p2_new_domain |= set(&#91;v2&#93;)
&gt;
&gt;         deleted = len(p1_domain) != len(p1_new_domain) or &#92;
&gt;                   len(p2_domain) != len(p2_new_domain)
&gt;
&gt;         return {self.p1: p1_new_domain, self.p2: p2_new_domain}, deleted</pre>
<p>Just having each constraint prune once isn&#8217;t enough of course, because one constraint&#8217;s pruning may have repercussions for the pruning of another. The naïve way to deal with this would just be to keep letting all constraints prune until the domains don&#8217;t change anymore. This is a valid way of doing things, and known as the <b>AC-1</b> algorithm (for <i>Arc Consistency</i>).<br />
Smarter might be to have a queue of all constraints, remove one, have it prune, and if it affects the domain, add all constraints involving the variables of the affected domains that aren&#8217;t already in the queue to the queue; repeat until the queue is empty. That one is <b>AC-3</b>. (Both are courtesy of Alan Mackworth, incidentally).<br />
It doesn&#8217;t matter a huge deal which we use; because we don&#8217;t have an easy way of getting the constraints on a given variable, AC-3 is going to be slower than it has to be, to the point where it might even be slower than AC-1. We could deal with this, but it&#8217;s not worth it. Let&#8217;s just do something.</p>
<pre>&gt; def ac3():
&gt;     queue = constraints&#91;:&#93;
&gt;
&gt;     while len(queue) &#62; 0:
&gt;         c = queue&#91;0&#93;
&gt;
&gt;         new_domains, d = c.prune_domains()
&gt;         domains.update(new_domains)
&gt;
&gt;         if d:
&gt;             new_constraints = &#91;&#93;
&gt;
&gt;             for con in constraints:
&gt;                 if (con.p1 == c.p1 or con.p2 == c.p1 or &#92;
&gt;                     con.p1 == c.p2 or con.p2 == c.p2) and con not in queue:
&gt;                     new_constraints.append(con)
&gt;
&gt;             queue = queue&#91;1:&#93; + new_constraints
&gt;
&gt;         else:
&gt;             queue = queue&#91;1:&#93;</pre>
<p>Alright! Now that our affairs are in order, we can start with the algorithm in earnest. What we&#8217;ll be doing basically amounts to a depth-first search of the search space. We&#8217;ll need an unambiguous ordering of our pieces, so let&#8217;s convert our <code>set</code> to a <code>list</code>.<br />
To keep track of our state, we&#8217;ll just use a dictionary that our algorithm will be modifying directly.</p>
<pre>&gt; pieces = list(pieces)
&gt; z = {}</pre>
<p>The search algorithm itself is really straightforward: we&#8217;ll fix a variable to a domain value, make sure it doesn&#8217;t violate any constraints, and then move on to the next variable. If it does violate a constraint, we move on to the next domain value. If we&#8217;re out of domain values, we move back to the previous variable and change that.</p>
<pre>&gt; def backtrack(depth):
&gt;     for a in domains&#91;pieces&#91;depth&#93;&#93;:
&gt;         z&#91;pieces&#91;depth&#93;&#93; = a
&gt;
&gt;         for c in constraints:
&gt;             if (c.p1 == pieces&#91;depth&#93; and c.p2 in pieces&#91;:depth&#93;) or &#92;
&gt;                (c.p2 == pieces&#91;depth&#93; and c.p1 in pieces&#91;:depth&#93;):
&gt;                 if not c.valid(z&#91;c.p1&#93;, z&#91;c.p2&#93;):
&gt;                     break
&gt;
&gt;         else:
&gt;             if depth == len(pieces) - 1:
&gt;                 print &#34;Solution:&#34;, z
&gt;             else:
&gt;                 backtrack(depth + 1)</pre>
<p>As written, this will just keep looking for solutions until it&#8217;s exhausted the search space, but it&#8217;s trivial to make it so that it stops after the first result is found, of course.</p>
<p>And that&#8217;s that. Now we just invoke everything and let it run.</p>
<pre>&gt; ac3()
&gt; backtrack(0)</pre>
<p>And we&#8217;re done!<br />
As usual, all of the code can be found <a href="/misc/constraints.py.html">here</a>, in case you want to try it yourself. If you want an exercise to try at home, find a sensible representation for the eight queens problem and solve that. (Hint: there&#8217;s a better one than <code>(row, column)</code>.)</p>
<p>Now, is constraint processing a good alternative to the search tree algorithms previously discussed? Obviously not the algorithm I&#8217;ve just described; that&#8217;s just a naïve DFS without heuristics. It can be improved in a lot of ways: you could sort the list of variables so that the variables with the smallest domains and the most constraints affecting them are first, for example. Or you could go a step further and do <b>dynamic search tree rearrangement</b> using some heuristic, making sure that the variables more likely to cause a constraint violation are filled in first. You could prevent a whole lot of redundant checks using a variety of techniques, like backmarking or backjumping or intelligent backtracking or what have you; there&#8217;s a million things you could do.<sup><a href="#f_processing-constraints-is-easy_2" id="processing-constraints-is-easy_2">2</a></sup> There&#8217;s no shortage of research on constraint processing, and the state of the art is surprisingly advanced.<br />
I&#8217;m not terribly fond of constraint processing algorithms, myself, because I get the impression that they&#8217;re more complex to implement for no significant gain, but I can see why some people would be.</p>
<p>In the end, the most significant factor is probably what the most natural way to express your problem is. Any problem that can be solved using vanilla search trees can be solved as a constraint problem and vice versa, but most problems are just easier to express one way or the other.</p>
<p>(My AI exam is on Monday, so this will probably be the last post in this series. The only course subject I haven&#8217;t covered is version spaces, anyway, and that&#8217;s not hugely interesting. Oh, and automated reasoning, but that&#8217;s more suited to a book than a blog post.)</p>
<hr />
<p class="footnote"><sup><a href="#processing-constraints-is-easy_0" id="f_processing-constraints-is-easy_0">0</a></sup> Most algorithms only bother with two variables, but it&#8217;s entirely possible to formulate this problem as a single constraint on nine variables. Enforcing 9-consistency (see the domain pruning bit later on) would be equivalent to solving it the way we&#8217;re doing now, though.</p>
<p class="footnote"><sup><a href="#processing-constraints-is-easy_1" id="f_processing-constraints-is-easy_1">1</a></sup> In fact, we&#8217;ll only look at a small fraction of that even when we do an exhaustive search, but any advantage is nice to have at this point.</p>
<p class="footnote"><sup><a href="#processing-constraints-is-easy_2" id="f_processing-constraints-is-easy_2">2</a></sup> You could even use a language other than Python and implement it in a way that isn&#8217;t dumb!</p>
]]></content:encoded>
			<wfw:commentRss>http://cairnarvon.rotahall.org/2010/06/20/processing-constraints-is-easy/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>I say this after every election</title>
		<link>http://cairnarvon.rotahall.org/2010/06/14/i-say-this-after-every-election/</link>
		<comments>http://cairnarvon.rotahall.org/2010/06/14/i-say-this-after-every-election/#comments</comments>
		<pubDate>Mon, 14 Jun 2010 20:10:19 +0000</pubDate>
		<dc:creator>Cairnarvon</dc:creator>
				<category><![CDATA[Politics]]></category>

		<guid isPermaLink="false">http://cairnarvon.rotahall.org/?p=1793</guid>
		<description><![CDATA[But people are fucking morons upon whom democracy is wasted. Yes, we had federal elections yesterday. I was summoned as a bijzitter, which meant I had to get up at 7 to help open a polling station and then put 1,242 stamps onto 1,242 ballots (621 each for Kamer and Senaat) and about five hundred [...]]]></description>
			<content:encoded><![CDATA[<p>But people are fucking morons upon whom democracy is wasted.</p>
<p>Yes, we had federal elections yesterday. I was summoned as a <i><abbr title="bee sitter">bijzitter</abbr></i>, which meant I had to get up at 7 to help open a polling station and then put 1,242 stamps onto 1,242 ballots (621 each for <abbr title="Kamer van Volksvertegenwoordigers; Chamber of Representatives (Lower House)">Kamer</abbr> and <abbr title="Senate (Upper House)">Senaat</abbr>) and about five hundred on as many election summons (compulsory voting, dontchaknow), and I didn&#8217;t even get to keep the stamp afterwards. Then at the end we all got to wait around for two more hours because apparently the problem with selecting members of the public to help manage elections is that the vast majority of the public is terminally innumerate, so our ballot count was off by one.<br />
It eventually got resolved, but the upshot of this is that I was too tired to bother with writing this post last night, when the votes were counted (we count more quickly than the Americans or the British or even the Dutch).</p>
<p>You may be wondering why we&#8217;re having federal elections in 2010 when the last time I complained about federal elections was <a href="http://cairnarvon.rotahall.org/2007/06/11/the-end-of-progressive-belgium/">in 2007</a>. A lot of countries have been having elections lately, but Belgium&#8217;s wasn&#8217;t planned for another year.<br />
The reason for that is that Alexander De Croo felt he wasn&#8217;t getting enough media attention, so he took his ball (the Flemish liberal party) and went home, thereby imploding the Leterme government for, what, the eighth time now? Even the King couldn&#8217;t pretend there was no problem this time, so in the good tradition of Christian democrat majority governments, emergency elections had to be called.<sup><a href="#f_i-say-this-after-every-election_0" id="i-say-this-after-every-election_0">0</a></sup></p>
<p>You can find all results <a href="http://www.deredactie.be/cm/vrtnieuws/verkiezingen2010/uitslagen">here</a>, as usual, and as usual I don&#8217;t know how long they&#8217;ll last, so I&#8217;ll steal some graphics.</p>
<p><span id="more-1793"></span></p>
<p><center><br />
<h2>Flanders<sup><a href="#f_i-say-this-after-every-election_1" id="i-say-this-after-every-election_1">1</a></sup></h2>
<p></center></p>
<p><center><img src="/pics/2010kamervl.png" title="Kamer (Vlaanderen)" class="image" /></center><br />
<center><img src="/pics/2010senaatvl.png" title="Senaat (Vlaanderen)" class="image" /></center></p>
<p>It&#8217;s not <i>all</i> bad, so let&#8217;s start with the good news.</p>
<p>It&#8217;s the worst result for the Flemish Christian democrats in the history of the country. For the Kamer, <b><abbr title="Christen-Democratisch en Vlaams">CD&#038;V</abbr></b> went from 29.6% of the Flemish vote in 2007 to 17.3% now, going from being by far the largest party in the country to being third behind N-VA and the Walloon PS, and losing six of their 23 seats. In the Senaat, they went from 31.4% to 16.2%, losing four of their eight seats.</p>
<p>The second bit of good news is that Jean-Marie Dedecker&#8217;s far-right temper tantrum of a party (slash retirement home for washed-up Flemish celebrities, about which I&#8217;ve complained before), <b><abbr title="Lijst Dedecker">LDD</abbr></b>, got trounced and slipped well below the electoral threshold of 5% nearly everywhere. They lose all of their Kamer seats except for one (Dedecker&#8217;s own), and never had any in de Senaat. Dedecker said he was going to quit politics if this happened, but is now backpedalling and has just &#8220;resigned&#8221; as president of the party. In fact, he&#8217;s still president until &#8220;a solution is found&#8221;. Ho hum.<br />
I hope this means we&#8217;ll be seeing a lot less of him in the media. The party is now only marginally more popular than the Trotskyists, and they <i>never</i> get invited to debates or interviews or what have you.</p>
<p>Speaking of the Trotskyists, <b><abbr title="Partij van de Arbeid PLUS!">PVDA+</abbr></b><sup><a href="#f_i-say-this-after-every-election_2" id="i-say-this-after-every-election_2">2</a></sup> just keeps growing! In the Kamer they went from 0.9% of the Flemish vote to 1.3%, and in the Senaat from 0.9% to <i>1.4%</i>! If they keep this up for another century, they may even get a representative in!</p>
<p><b><abbr title="Socialistische Partij Anders">sp.a</abbr></b> (the Flemish social democrats, of which I am <a href="/pics/sossen.jpg">a member</a>), meanwhile, is holding relatively steady. Kamer went from 10.3% to 9.2%, and Senaat went from 16.2% to 15.3%. This seems bad, but compared to the losses suffered by every other traditional party, it&#8217;s really very good. I was certainly expecting worse. They&#8217;re now the third biggest Flemish party, behind, of course, N-VA and CD&#038;V. Last time even Vlaams Belang was doing better than them.<br />
It&#8217;s worth keeping in mind that for the last federal elections, sp.a was in a cartel with Spirit, another lefty social-democratic party, so maybe you could argue their losses are attributable to the fact that they&#8217;re alone now. Given the drama surrounding Spirit (now LSP; I forget what that stands for) and the fact that they got very nearly 0% of the vote now, though, I&#8217;m not sure how tenable that is.<br />
They did slightly better than they did during the <a href="http://cairnarvon.rotahall.org/2009/06/08/democracy-2/">regional elections last year</a>, anyway, even if Tienen is no longer the most socialist canton in Flanders (though for the Kamer it&#8217;s one of very few cantons where sp.a won; see map below). For the Senaat, sp.a isn&#8217;t even the most popular party here anymore (that would be, inevitably, N-VA).</p>
<p>Speaking of <b>Vlaams Belang</b>, the neo-Nazis continue the heartening slide into irrelevancy they started in the regional elections, going from 12% to 7.8% in the Kamer and 19.2% to 12.3% in the Senaat.</p>
<p><b>Groen!</b>, the Flemish green party, actually gains a bit, going from 4% to 4.4% in the Kamer (actually gaining a seat there) and from 5.9% to 6.3% in the Senaat.</p>
<p><b>Open <abbr title="Vlaamse Liberalen en Democraten">VLD</abbr></b>, the Flemish liberals, lost quite a bit, going from 18.8% to 13.6% in the Kamer and 20.1% to 13.3% in the Senaat. Normally I would consider this bad news; I voted for VLD at least once before, and I still think Verhofstadt I was the best government Belgium has ever had. However, post Verhofstadt, VLD has been a ridiculous embarrassment. Alexander De Croo, who replaced Verhofstadt as party president, is an inexperienced, barely competent, smug, fils-à-papa douchebag who only got the job because Herman De Croo has been a liberal party high-up since long before it was called VLD. In addition to this, while VLD used to be centrist, lately it has swung so far to the right it is no longer a party I can support.<br />
Verhofstadt used to be known as <i>Baby Thatcher</i> in the &#8217;80s, but it wasn&#8217;t until he cleaned up and stopped being a moron that he got elected. You&#8217;d think De Croo would take a hint.</p>
<p><center><img src="/pics/2010nvakamer.png" title="Flemish results by canton: Kamer" class="image" /></center><br />
<center><img src="/pics/2010nvasenaat.png" title="Flemish results by canton: Senaat" class="image" /></center></p>
<p>Now for the bad news: <b><abbr title="Nieuw-Vlaamse Alliantie">N-VA</abbr></b> won. Overwhelmingly so.<br />
This time it looks like it was a legitimate victory. The first time N-VA got a lot of votes because it was in a cartel with CD&#038;V, the second time (in the regional elections) because Bart De Wever, the toad-faced party leader, was a funny man on some quiz show. This time you could put some of the blame on the reality-creating polls conducted before the elections, but you probably can&#8217;t explain away 27.8% and 31.7% of the Flemish vote like that.<br />
These are, of course, the Flemish nationalists and separatists. Their platform reads like Vlaams Belang <i>light</i> (except when it comes to gays, abortion, and euthanasia, on which they just don&#8217;t have a position, because they&#8217;re a gimmick party), but even De Wever hasn&#8217;t had the spine recently to stick to the single issue the party was created for, which is Flemish independence. Instead, they&#8217;ve been waffling and pretending that they just want more autonomy for the regional governments.</p>
<p>It should be obvious to anyone with half a brain that separatism or increased autonomy or confederalism or whatever you want to call this bullshit is a red herring. In 2009 N-VA blamed the international economic crisis on a unified Belgium and pretended it would go away if only <a href="http://cairnarvon.rotahall.org/pics/afrituitrit.jpg">Flanders would become an independent nation</a>. This election cycle the liberals did more or less the same thing, and N-VA pretended that moving social security from the federal level to the regional level would solve all of our (read: Flanders&#8217;) problems. It&#8217;s a straight-forward diversion tactic to stop people from noticing they don&#8217;t have any real policies. Sadly, it seems to work.</p>
<p>It&#8217;s true that Wallonia has been in an economic slump since the mines closed down, and is, compared to Flanders, basically broke. It&#8217;s also true that Flemish tax money is helping pay for social security and health care for Walloons, and that regionalising those things would mean more Flemish money is going to Flanders. However, it&#8217;s equally true that the Flemish rich are paying to support the Flemish poor, and making it so that only those who don&#8217;t need financial support could get it would mean nobody would benefit at the cost of anyone else. That&#8217;s <i>the entire fucking point</i> of social security and socialised medicine: the more fortunate help carry the less fortunate in their time of need, so they can get back on their feet more quickly.<br />
Cutting off Wallonia is no different from abandoning our own poor. Yes, to a short-sighted rich person it may make sense in that he&#8217;ll be paying less in the short term; however, by pulling away the safety net (and let&#8217;s not pretend this is doing anything else), we&#8217;re also kneecapping Wallonia in its attempts at getting their shit back together. I suppose it&#8217;s possible in theory for poor regions to pull themselves up by their bootstraps, but it&#8217;s almost unheard of. Wallonia&#8217;s economic recovery <i>depends</i> on Flemish help, just like Flanders&#8217; economic boom was built on the back of Wallonia back when it was still the wealthier.</p>
<p>You might say, &#8220;So what?&#8221;. After all, why should you care about Wallonia? You might be one of the very few Flemish people who has no friends or relatives in Wallonia, or you might not give a shit about those people. I could make the usual case from compassion and charity and altruism, but fuck it; you&#8217;re too selfish to understand it, and nothing bad could ever happen to you, so you&#8217;ll never need that kind of charity from others yourself. In fact, that line of argumentation isn&#8217;t even needed.<br />
The obvious question is, of course, how healthy it is for Flanders to border on a very poor region that is only going to get poorer. Regardless of whether Wallonia is part of Belgium or an independent nation or part of Luxembourg or France, how long is it going to be before Flanders will need a Mexican border fence along the language barrier? Even if we manage to keep all Walloons after our jobs (hah!) and health care and infrastructure and what have you out of Flanders, which would be better for us: an economically healthy Wallonia with which we could trade freely, or an economic black hole which might as well not exist?<br />
Investing in Wallonia is the surest way to economic recovery in Flanders as well.</p>
<p>Suppose, however, that N-VA gets everything they want: an independent Flanders, a Wallonia that somehow doesn&#8217;t affect us at all anymore, and some magical solution for the problem of Brussels. What&#8217;s next?<br />
There&#8217;s a lot of masturbation over the right to self-determination of ethnic groups and historical nations with a single language and cultural identity. Flanders, however, is very obviously not one of those. We all speak &#8220;Dutch&#8221;, sure; well, we do now. Historically and culturally and in many cases linguistically, however, the region now known as Flanders (and Wallonia, for that matter) is one of independent or semi-independent city states, duchies, and counties. Gent and Antwerpen and Leuven and Limburg and what have you: each of these has its own cultural identity, and its own dialect which, while certainly part of a large Dutch family, is usually unintelligible to other speakers of &#8220;Dutch&#8221;.<br />
If a case can be made for the confederalism of the liberals or, now, N-VA, it is <i>not</i> on the level of the current national regions, but on the level of these much smaller units.</p>
<p>All of N-VA&#8217;s arguments concerning Flemish independence are equally (or even better) applicable to independence from, say, Limburg. It too is economically significantly worse off than the rest of Flanders, and it too has its own cultural identity (which, like Wallonia, it shares with a region in a different country; specifically the Dutch province of Limburg and part of Germany) and language (Limburgs, which many would argue wouldn&#8217;t even be a <i>Dutch</i> dialect even if it were just a dialect). Historically, it&#8217;s even been an independent state as the Duchy of Limburg, unlike Wallonia, which was never a single unified entity.<br />
When are we going to secede from them? For how much longer must we, the successful, subsidise economic failure?</p>
<p>People anger me.</p>
<p>Anyway, it&#8217;s worth pointing out that <i>nobody wants Flemish independence</i>. Polls show this time and time again: nobody wants to dissolve Belgium, though most people believe it will be dissolved. Even De Wever realises this, which is why he&#8217;s been lying about N-VA&#8217;s platform. The <i>only</i> party serious about Flemish independence at this point is Vlaams Belang, and they only want it so they can create their Diets paradise, where speaking French will get you deported and being brown is a capital offense.</p>
<p><center><br />
<h2>Wallonia</h2>
<p></center></p>
<p><center><img src="/pics/2010chambrewa.png" title="Chambre (Wallonie)" class="image" /></center><br />
<center><img src="/pics/2010senatwa.png" title="Sénat (Wallonie)" class="image" /></center></p>
<p>Meanwhile, Wallonia seems to be a lot more sensible. They&#8217;re traditionally socialist, and while the liberal <abbr title="Mouvement Réformateur">MR</abbr> won last time, this time the social-democratic <b><abbr title="Parti Socialiste">PS</abbr></b> is back on top going from 29.5% to 37.5% in the Kamer and 26.8% to 35.7% in the Senaat, becoming the second largest party (after N-VA, obviously) on a national level.</p>
<p><b>Front National</b>, which is the only other Walloon party I care about, got trounced, so that&#8217;s nice.</p>
<p><img src="/pics/eliodirupo.jpg" alt="Elio Di Rupo" title="Elio Di Rupo" class="imageright" />There are rumors that PS party leader Elio Di Rupo<sup><a href="#f_i-say-this-after-every-election_3" id="i-say-this-after-every-election_3">3</a></sup> will become the next prime minister, which would be nice. Compared to its Flemish counterpart, PS has a few corruption issues, but I&#8217;d still much prefer them to De Wever. We haven&#8217;t had a Walloon prime minister <i>or</i> a socialist one since Leburton in 1973/1974, which was before the national parties fell apart into the regional ones (the Belgian Socialist Party became the Flemish SP and the Walloon PS in 1978). I&#8217;m not holding my breath, but the fact is that N-VA is an opposition party by design (they have no real policies, unless just whining about what everyone else does counts).<br />
There&#8217;s also the issue that N-VA (like Vlaams Belang, of course) is explicitly republican, and the King has a significant say over who becomes PM. Normally it&#8217;s bad form to suggest Albert II is anything but impartial, but given his performance with Leterme, I&#8217;m no longer inclined to pretend.<br />
We can only hope.<sup><a href="#f_i-say-this-after-every-election_4" id="i-say-this-after-every-election_4">4</a></sup> Either way, it&#8217;s going to take a long fucking time to put together a government.</p>
<p>Final conclusion: it&#8217;s bad, but not nearly as bad as it could have been, especially if Di Rupo becomes PM. I&#8217;m not moving to Finland over these elections, though I may move to Wallonia. I have some family in Nijvel, anyway.</p>
<p>Or Nivelles, I guess.</p>
<p>I don&#8217;t even speak French.</p>
<hr />
<p class="footnote"><sup><a href="#i-say-this-after-every-election_0" id="f_i-say-this-after-every-election_0">0</a></sup> Alright, the fuller story is that people were still whining about state reform, which still hadn&#8217;t been passed after two or three years of negotiating, because Leterme is a smug douchebag who hates the Walloons and N-VA and most recently the Flemish liberals have been obstructionist douchebags. De Croo wanted to pretend none of it was his fault (which is a lie), and he just left because he felt things were going anywhere (which may be true). Even most voters probably realised he was full of shit.</p>
<p class="footnote"><sup><a href="#i-say-this-after-every-election_1" id="f_i-say-this-after-every-election_1">1</a></sup> For non-Belgians who might not know: Belgium has a bi-cameral federal government, and is divided into three regions: Dutch-speaking Flanders (6 million people), French-speaking Wallonia (with a tiny German-speaking bit; 3.4 million people), and theoretically-bilingual-but-practically-French-speaking Brussels (1 million). For the most part, Flemish parties only appear on Flemish ballots and Walloon parties only appear on Walloon ballots, which is why there&#8217;s really two sets of results. The exception is the electoral region Brussel-Halle-Vilvoorde, which is half of the Flemish province of Flemish Brabant plus Brussels, which has both. Much of the recent drama has been about splitting that up, presumably so Brussels is its own electoral region, and Flemish Brabant is a unified region like every other province.<br />
As for why the situation is the way it is: blame the Christian democrats.</p>
<p class="footnote"><sup><a href="#i-say-this-after-every-election_2" id="f_i-say-this-after-every-election_2">2</a></sup> Not to be confused with the Dutch social-democratic PVDA, which is actually a mainstream party.</p>
<p class="footnote"><sup><a href="#i-say-this-after-every-election_3" id="f_i-say-this-after-every-election_3">3</a></sup> Son of Italian immigrants, as you may be able to tell. Until Moroccans overtook them a few years ago, Italians were the largest immigrant group in Belgium, because we imported them to work in our coal mines, mostly in Wallonia. As said, most of those ran out a while ago.</p>
<p class="footnote"><sup><a href="#i-say-this-after-every-election_4" id="f_i-say-this-after-every-election_4">4</a></sup> As the bow tie suggest, he is a homosexual. In Belgium that&#8217;s a non-issue, though; we&#8217;ve had gay marriage since 2003 (Verhofstadt I&#8217;s liberal/socialist government, of course), and the only party to oppose it then (and, indeed, now) was Vlaams Belang. If Di Rupo&#8217;s sexuality annoys Vlaams Belang it can only be a good thing, but even the King isn&#8217;t going to give a shit otherwise.</p>
]]></content:encoded>
			<wfw:commentRss>http://cairnarvon.rotahall.org/2010/06/14/i-say-this-after-every-election/feed/</wfw:commentRss>
		<slash:comments>24</slash:comments>
		</item>
		<item>
		<title>Towards a better BBCode</title>
		<link>http://cairnarvon.rotahall.org/2010/05/25/towards-a-better-bbcode/</link>
		<comments>http://cairnarvon.rotahall.org/2010/05/25/towards-a-better-bbcode/#comments</comments>
		<pubDate>Tue, 25 May 2010 15:16:14 +0000</pubDate>
		<dc:creator>Cairnarvon</dc:creator>
				<category><![CDATA[Academia]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Religion]]></category>
		<category><![CDATA[WordPress]]></category>

		<guid isPermaLink="false">http://cairnarvon.rotahall.org/?p=1776</guid>
		<description><![CDATA[Everyone knows BBCode is a pain to work with, and while WordPress supports limited HTML in user comments, it should be obvious HTML is no better. The unnecessary repetition of SGML-based languages and the insistence on the proper nesting of tags makes them all hideous and unnecessarily error-prone. We can do better. The discussions of [...]]]></description>
			<content:encoded><![CDATA[<p>Everyone knows BBCode is a pain to work with, and while WordPress supports limited HTML in user comments, it should be obvious HTML is no better. The unnecessary repetition of SGML-based languages and the insistence on the proper nesting of tags makes them all hideous and unnecessarily error-prone. We can do better.<br />
The discussions of learned societies on the subject have been less than satisfactory, so I decided to just implement my own mark-up language, based on the venerable S-expression:</p>
<blockquote><p><code>{b This} is {i {u expert} {o mark-up}}.</code></p></blockquote>
<p>This will turn into:</p>
<blockquote><p><b>This</b> is <i><u>expert</u> <span style="text-decoration: overline">mark-up</span></i>.</p></blockquote>
<p>The immediate effect is that nesting problems and text redundancy immediately disappear. The syntax also lends itself to easy function composition:</p>
<blockquote><p><code>{b.i.o.u EXPERT}</code></p></blockquote>
<blockquote><p><b><i><span style="text-decoration: overline"><u>EXPERT</u></span></i></b></p></blockquote>
<p>Finally, for this first version,<sup><a href="#f_towards-a-better-bbcode_0" id="towards-a-better-bbcode_0">0</a></sup> we also support function iteration:</p>
<blockquote><p><code>{sup*3 To the moon}{sub*3 and back.}</code></p></blockquote>
<blockquote><p><sup><sup><sup>To the moon</sup></sup></sup><sub><sub><sub>and back.</sub></sub></sub></p></blockquote>
<p>It goes without saying this can be combined with function composition in arbitrarily complex expressions, with the iteration operator having a higher precedence than the function composition operator.</p>
<p>I&#8217;ve elected to use curly braces rather than the more typical parentheses, because curly braces barely see any use in natural language, which is where this mark-up would generally be used. If you do need literal curly braces, you can escape them with a backslash (and if you need a literal <code>\{</code>, you can escape your backslash with a backslash).</p>
<p>As a proof of concept, and because I eat my own dog food, I&#8217;ve written (and enabled) a <a href="http://github.com/Cairnarvon/SexpCode-for-WordPress">WordPress plugin</a> that enables this <i>SexpCode</i> in blog comments. For sanity, iteration doesn&#8217;t go beyond <code>*3</code>. Supported tags are <code>b</code>, <code>i</code>, <code>u</code>, <code>s</code>, <code>o</code>, <code>sub</code>, <code>sup</code>, <code>code</code>, <code>spoiler</code>, <code>quote</code>, <code>blockquote</code>, and <code>m</code>. If you want to use it yourself, adding more tags or changing their definitions should be straightforward.<br />
Trying to use an unsupported or empty tag, or having unbalanced braces (except for closing braces at the end), will assume you&#8217;re actually trying to post C-like code, and disable SexpCode for your comment.</p>
<p>Ladies and gentlemen, BBCode was our COBOL. This is our Lisp.</p>
<p><b>Edit:</b> People who want to implement this themselves should be following <a href="/misc/sexpcode.html">this document</a> rather than this post.</p>
<p><b>Edit again:</b> <a href="http://cairnarvon.rotahall.org/misc/sexpcode_test.php">Play with it!</a></p>
<p><b>Edit again again:</b> More implementations:</p>
<ul>
<li><a href="https://github.com/Cairnarvon/sexpcode">sexpcode</a>, a CLI utility and a C library</li>
<li><a href="https://github.com/Cairnarvon/sexpcode.py">sexpcode.py</a>, Python bindings for that C library</li>
</ul>
<p>Know of another implementation (SexpCode<sup>+</sup> or SexpCode<sup>−</sup>)? Let me know!</p>
<hr />
<p class="footnote"><sup><a href="#towards-a-better-bbcode_0" id="f_towards-a-better-bbcode_0">0</a></sup> Future versions of the language are expected to add support for function arguments (for things like <code>url</code>, <code>img</code>, and <code>colour</code>) and the ability to define aliases (for example, <code>{define exp b.i.o.u}</code>, which would let you use a new <code>exp</code> function as if it were <code>b.i.o.u</code>).</p>
]]></content:encoded>
			<wfw:commentRss>http://cairnarvon.rotahall.org/2010/05/25/towards-a-better-bbcode/feed/</wfw:commentRss>
		<slash:comments>48</slash:comments>
		</item>
	</channel>
</rss>

<!-- Dynamic Page Served (once) in 0.376 seconds -->

