<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:blogger="http://schemas.google.com/blogger/2008" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;CkUNSX8zcSp7ImA9WhBTF0Q.&quot;"><id>tag:blogger.com,1999:blog-7770370347473031286</id><updated>2013-02-13T16:18:18.189-05:00</updated><category term="discussion" /><category term="finance" /><category term="web" /><category term="trolls" /><category term="latex" /><category term="brainstorm" /><category term="projects" /><category term="settings" /><category term="thermodynamics" /><category term="EA support commendation" /><category term="ezbl" /><category term="encryption" /><category term="dispatch" /><category term="minecraft" /><category term="nuclear" /><category term="summer" /><category term="rom" /><category term="ill-advised" /><category term="git" /><category term="intelligence" /><category term="rails" /><category term="org" /><category term="video" /><category term="cities" /><category term="droid" /><category term="greed" /><category term="barcode" /><category term="voting" /><category term="constitution" /><category term="facebook" /><category term="scheme" /><category term="system" /><category term="scala" /><category term="java" /><category term="problem solved" /><category term="distraction" /><category term="hate" /><category term="concurrency" /><category term="incentives" /><category term="milk" /><category term="patents" /><category term="boring" /><category term="ballroom" /><category term="android" /><category term="desktop" /><category term="emulator" /><category term="opinion" /><category term="software" /><category term="brown" /><category term="madoff" /><category term="ubuntu" /><category term="testing" /><category term="race" /><category term="hilarious" /><category term="json" /><category term="svn" /><category term="google" /><category term="n64" /><category term="sha1" /><category term="ruby" /><category term="gsoc" /><category term="cryptography" /><category term="packaging" /><category term="mupen64plus" /><category term="youtube" /><category term="benchmarks" /><category term="easy" /><category term="climate" /><category term="worst idea ever" /><category term="activism" /><category term="python" /><category term="browser" /><category term="internet" /><category term="elisp" /><category term="code" /><category term="invention" /><category term="advi" /><category term="science" /><category term="thinking" /><category term="mods" /><category term="linux" /><category term="rendering" /><category term="emacs" /><category term="cloud computing" /><category term="uzbl" /><category term="law" /><category term="financial crisis" /><category term="programming" /><category term="politics" /><category term="experience" /><category term="r" /><category term="wii" /><category term="music" /><category term="atheism" /><category term="lisp" /><category term="blog" /><category term="networks" /><category term="publishing" /><category term="mode" /><category term="copyright" /><category term="country" /><category term="languages" /><category term="intellectual property" /><category term="drupal" /><category term="god" /><category term="whizzytex" /><category term="lawsuits" /><category term="chainmail" /><title>This Week in Hax</title><subtitle type="html">I have carved out a small slice of the great Intarwebs to share with you my goings on.</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://www.haxney.org/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://www.haxney.org/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/7770370347473031286/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" /><author><name>Daniel Hackney</name><uri>https://plus.google.com/114139496531318962673</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-wADb4DtR17g/AAAAAAAAAAI/AAAAAAAAAoM/q9V58qhyP4w/s512-c/photo.jpg" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>83</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/haxney" /><feedburner:info uri="haxney" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><link rel="license" type="text/html" href="http://creativecommons.org/licenses/by-sa/3.0/" /><entry gd:etag="W/&quot;CkUNSX8yfSp7ImA9WhBTF0Q.&quot;"><id>tag:blogger.com,1999:blog-7770370347473031286.post-5223378205946171235</id><published>2013-02-13T15:56:00.000-05:00</published><updated>2013-02-13T16:18:18.195-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-02-13T16:18:18.195-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="climate" /><category scheme="http://www.blogger.com/atom/ns#" term="easy" /><category scheme="http://www.blogger.com/atom/ns#" term="problem solved" /><category scheme="http://www.blogger.com/atom/ns#" term="nuclear" /><title>Easy solution to the melting ice caps</title><content type="html">&lt;p&gt;People are always belly-aching about how the polar ice caps are melting. "Oh,
the sea level is going to rise and flood coastal cities!" Blah blah blah, as if
this is some unsolvable problem.&lt;/p&gt;

&lt;p&gt;But, as we all know, human ingenuity knows no bounds, and there is a simple,
  cost-effective solution to the "problem" of arctic ice melting: just re-freeze
  it. A quick back-of-the-envelope calculation reveals how simple this solution
  would be.&lt;/p&gt;

&lt;p&gt;&lt;ul&gt;
    &lt;li&gt;According to
    the &lt;a href="http://psc.apl.washington.edu/wordpress/research/projects/arctic-sea-ice-volume-anomaly/"&gt;
    Polar Science Center at the University of Washington&lt;/a&gt;, the arctic pole is
    losing an extra 280 km³ of ice per year beyond the seasonal
    fluctuations.&lt;/li&gt;

    &lt;li&gt;Ice has a density of 0.9167 g/cm³, so 280 km³ (2.8e17 cm³) is 2.56676e17
    grams of ice lost per year.&lt;/li&gt;

    &lt;li&gt;1 Watt can freeze 8 grams of water per hour, according to the
    ever-trustworthy &lt;a href="http://boards.straightdope.com/sdmb/showthread.php?t=534814"&gt;beowulff
    on the Straight Dope message boards&lt;/a&gt;.&lt;/li&gt;

    &lt;li&gt;The state-of-the-art nuclear reactor design is
    the &lt;a href="http://en.wikipedia.org/wiki/European_Pressurized_Reactor"&gt;European
    Pressurized Reactor&lt;/a&gt;, which, for the low-low price of $11 billion, pumps
    out a hefty 1,600 MW&lt;/li&gt;

    &lt;li&gt;A single EPR could freeze (assuming 100% efficiency) 1.28e10 grams of
    water per hour, or 1.12e14 grams per year.&lt;/li&gt;

    &lt;li&gt;It would therefore take 2.56676e17 / 1.12e14 = 2,291 EPRs to re-freeze
    the yearly arctic ice loss. At $11 billion a pop, that's $25 trillion to
    build enough power plants to stop the melting of the polar ice caps&lt;/li&gt;
&lt;/ul&gt;&lt;/p&gt;

&lt;p&gt;So all this worrying about melting ice caps just boils down to a lack of
  creativity. For a mere $25 trillion, we could build 2,291 nuclear reactors in
  the arctic circle and use them to run giant freezers. It's so obvious, I can't
  believe nobody's thought of it before.&lt;/p&gt;

&lt;p&gt;You're welcome, world.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/haxney/~4/GBV0kokQ_JQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.haxney.org/feeds/5223378205946171235/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.haxney.org/2013/02/easy-solution-to-melting-ice-caps.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7770370347473031286/posts/default/5223378205946171235?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7770370347473031286/posts/default/5223378205946171235?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/haxney/~3/GBV0kokQ_JQ/easy-solution-to-melting-ice-caps.html" title="Easy solution to the melting ice caps" /><author><name>Daniel Hackney</name><uri>https://plus.google.com/114139496531318962673</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-wADb4DtR17g/AAAAAAAAAAI/AAAAAAAAAoM/q9V58qhyP4w/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.haxney.org/2013/02/easy-solution-to-melting-ice-caps.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0EGRnw4fSp7ImA9WhNWF0o.&quot;"><id>tag:blogger.com,1999:blog-7770370347473031286.post-8043499318743444321</id><published>2012-12-17T15:20:00.000-05:00</published><updated>2012-12-17T15:20:27.235-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-12-17T15:20:27.235-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="n64" /><category scheme="http://www.blogger.com/atom/ns#" term="wii" /><category scheme="http://www.blogger.com/atom/ns#" term="linux" /><category scheme="http://www.blogger.com/atom/ns#" term="emulator" /><category scheme="http://www.blogger.com/atom/ns#" term="mupen64plus" /><category scheme="http://www.blogger.com/atom/ns#" term="ubuntu" /><title>Using a Wiimote in Mupen64plus</title><content type="html">&lt;p&gt;After much head-wall-banging, I got a Wiimote to pair successfully with my
computer and work as a controller in &lt;a
href="https://code.google.com/p/mupen64plus"&gt;Mupen64plus&lt;/a&gt;! There was a lot of
trial and error, so I've created a guide to getting a working setup so future
generations don't have to go through what I did. The details are in &lt;a
href="https://github.com/haxney/wiimote-mupen64"&gt;this git repo&lt;/a&gt;, which
includes detailed instructions and config files.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/haxney/~4/lHb3oAfOnKg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.haxney.org/feeds/8043499318743444321/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.haxney.org/2012/12/using-wiimote-in-mupen64plus.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7770370347473031286/posts/default/8043499318743444321?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7770370347473031286/posts/default/8043499318743444321?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/haxney/~3/lHb3oAfOnKg/using-wiimote-in-mupen64plus.html" title="Using a Wiimote in Mupen64plus" /><author><name>Daniel Hackney</name><uri>https://plus.google.com/114139496531318962673</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-wADb4DtR17g/AAAAAAAAAAI/AAAAAAAAAoM/q9V58qhyP4w/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.haxney.org/2012/12/using-wiimote-in-mupen64plus.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0INQHo_fyp7ImA9WhNWE08.&quot;"><id>tag:blogger.com,1999:blog-7770370347473031286.post-4857740040342240777</id><published>2012-12-12T11:25:00.000-05:00</published><updated>2012-12-12T11:26:31.447-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-12-12T11:26:31.447-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="ill-advised" /><category scheme="http://www.blogger.com/atom/ns#" term="android" /><category scheme="http://www.blogger.com/atom/ns#" term="rom" /><title>Trying an Android ROM</title><content type="html">&lt;p&gt;Against my better judgment, I am going to take another shot at installing a
ROM on my phone. The battery life could use some improvement, and people have
claimed that some of the 3rd-party ROMs can help with that. I know I have
promised myself not to play with ROMs on my phone again, since the result is
usually a big waste of time with nothing to show for it, but this time is
different.&lt;/p&gt;

&lt;p&gt;Brace yourselves for a follow-up in which I immediately regret this
decision.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/haxney/~4/gKisTPdwr18" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.haxney.org/feeds/4857740040342240777/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.haxney.org/2012/12/trying-android-rom.html#comment-form" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7770370347473031286/posts/default/4857740040342240777?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7770370347473031286/posts/default/4857740040342240777?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/haxney/~3/gKisTPdwr18/trying-android-rom.html" title="Trying an Android ROM" /><author><name>Daniel Hackney</name><uri>https://plus.google.com/114139496531318962673</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-wADb4DtR17g/AAAAAAAAAAI/AAAAAAAAAoM/q9V58qhyP4w/s512-c/photo.jpg" /></author><thr:total>2</thr:total><feedburner:origLink>http://www.haxney.org/2012/12/trying-android-rom.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkIDRX4yeCp7ImA9WhNWEkU.&quot;"><id>tag:blogger.com,1999:blog-7770370347473031286.post-6631520936205812016</id><published>2012-12-11T21:49:00.000-05:00</published><updated>2012-12-11T21:49:34.090-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-12-11T21:49:34.090-05:00</app:edited><title>Another Ubuntu update, another b0rked system</title><content type="html">&lt;p&gt;*sigh*&lt;/p&gt;

&lt;p&gt;I updated to 12.10, and Alt+middle-click to resize windows was broken. After about an hour of circular Googling, I found the correct incantation to sprinkle. For some strange reason, the setting &lt;code&gt;org.gnome.desktop.wm.preferences.resize-with-right-button&lt;/code&gt; was set to &lt;code&gt;true&lt;/code&gt;. Set it back to &lt;code&gt;false&lt;/code&gt; and the system returns to its former functioning state.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/haxney/~4/vFms8G3L_Cc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.haxney.org/feeds/6631520936205812016/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.haxney.org/2012/12/another-ubuntu-update-another-b0rked.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7770370347473031286/posts/default/6631520936205812016?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7770370347473031286/posts/default/6631520936205812016?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/haxney/~3/vFms8G3L_Cc/another-ubuntu-update-another-b0rked.html" title="Another Ubuntu update, another b0rked system" /><author><name>Daniel Hackney</name><uri>https://plus.google.com/114139496531318962673</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-wADb4DtR17g/AAAAAAAAAAI/AAAAAAAAAoM/q9V58qhyP4w/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.haxney.org/2012/12/another-ubuntu-update-another-b0rked.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DU8AQXY5eip7ImA9WhNQEkw.&quot;"><id>tag:blogger.com,1999:blog-7770370347473031286.post-6606620393232806138</id><published>2012-11-18T00:50:00.001-05:00</published><updated>2012-11-18T00:50:40.822-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-11-18T00:50:40.822-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="elisp" /><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><category scheme="http://www.blogger.com/atom/ns#" term="emacs" /><title>Better than "Understanding OOP"</title><content type="html">&lt;p&gt;I came across a &lt;a href=" http://www.csis.pace.edu/~bergin/patterns/ppoop.html"&gt;page talking about the joys of OOP&lt;/a&gt; via &lt;a href="http://irreal.org/blog/?p=1393"&gt;this blog post&lt;/a&gt;. The original page was a thing of horror. I modified the Elisp code from Irreal, adding a few additional features:&lt;/p&gt;

&lt;script src="https://gist.github.com/4103741.js"&gt; &lt;/script&gt;

&lt;p&gt;In addition to equality matches, it can match using regexps and arbitrary functions. Let's see Java do that in 20 SLOC.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/haxney/~4/yFUUp107TPs" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.haxney.org/feeds/6606620393232806138/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.haxney.org/2012/11/better-than-understanding-oop.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7770370347473031286/posts/default/6606620393232806138?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7770370347473031286/posts/default/6606620393232806138?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/haxney/~3/yFUUp107TPs/better-than-understanding-oop.html" title="Better than &quot;Understanding OOP&quot;" /><author><name>Daniel Hackney</name><uri>https://plus.google.com/114139496531318962673</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-wADb4DtR17g/AAAAAAAAAAI/AAAAAAAAAoM/q9V58qhyP4w/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.haxney.org/2012/11/better-than-understanding-oop.html</feedburner:origLink></entry><entry gd:etag="W/&quot;D0UFSXo9fCp7ImA9WhJbGUk.&quot;"><id>tag:blogger.com,1999:blog-7770370347473031286.post-3455765815934719364</id><published>2012-09-29T15:00:00.000-04:00</published><updated>2012-09-29T15:00:18.464-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-09-29T15:00:18.464-04:00</app:edited><title>Voting third party and government job "creation"</title><content type="html">&lt;p&gt;This is copy of an email I sent to my dad just now.&lt;/p&gt;

&lt;blockquote&gt;My concern about the libertarian candidate, besides the fact that he
cannot win,&lt;/blockquote&gt;

&lt;p&gt;That's no reason not to vote for him. A well-functioning democracy
requires a choice of more than the people who are "obviously" going to
win. Otherwise, it isn't democracy so much as a decree by the political
parties who will be the next president.&lt;/p&gt;

&lt;blockquote&gt;My is that his economic plans are hopelessly naive. He pretends
that, given Congressional cooperation, one could dramatically cut spending in
2013.&lt;/blockquote&gt;

&lt;p&gt;Again, for democracy to work, you need people who are going to
do more than what will easily pass.&lt;/p&gt;

&lt;blockquote&gt;My The prospect of a much smaller cut is labeled the fiscal cliff
and would send us into recession.&lt;/blockquote&gt;

&lt;p&gt;I'm not so sure it would be quite that bad. It strains credulity for a
trillion-dollar increase in federal spending to be little more than an
academic nuisance, but a symmetric decrease to bring about the
apocalypse.&lt;/p&gt;

&lt;blockquote&gt;I might love to see federal spending go down to 15% of GDP, but if
that happened in one day we would have a depression that would make the 1930's
look like the good old days.&lt;/blockquote&gt;

&lt;p&gt;It just seems weird that spending can shoot up by an enormous margin in
one year, but for it to drop by the exact same amount would throw the
country into ruin. As a counter-example, I would point to the
demobilization following WWII. Government spending fell through the
floor, yet the economy boomed, even as it had to absorb the mass of
people coming home from the war.&lt;/p&gt;

&lt;blockquote&gt;Since Obama will carry MA by a landslide, I want the message of my
protest vote to be unambiguous. Voting for Romney says my concern is economic.
Voting for a fringe candidate could mean anything.&lt;/blockquote&gt;

&lt;p&gt;Well, the fringe candidate has a much clearer message: that neither of
the two parties offer particularly attractive directions for the country
and that both parties are to blame for the mess we're in.&lt;/p&gt;

&lt;p&gt;Besides, whether you vote Democrat, Republican, Libertarian, Green, Wizard,
or not at all doesn't make a measurable difference in the outcome of the
election, so you might as well vote for your highest preference. See the &lt;a
href="https://en.wikipedia.org/wiki/Paradox_of_voting"&gt;paradox of voting&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Since you personally are never going to be the tiebreaker, vote for
the person who most closely matches your preferences. But what if
everyone thought that way? They don't. You are not a collective. And
your choice of candidate does not effect a change in other people's
voting behavior.&lt;/p&gt;

&lt;blockquote&gt;As long as the Republicans hold the House we may stave of the
Spanish food riots here. I have great sympathy for them, but they are still
thinking there is the alternative of just spending more of that free
money.&lt;/blockquote&gt;

&lt;p&gt;Incidentally, this is one of the reasons I am in favor of a smaller role
for government: there's no one to whom to complain when things don't go
your way. People riot against the government in the hopes that the
bureaucrats will deign to bestow to each according to his need. Against
whom do I riot if the ending of Mass Effect 3 is a major letdown? I can
raise money for charity in protest of the botched opportunity, or send
ending-related colored cupcakes to the developer's offices (both of
which people did), but that's about it. The most impactful thing I can
do is refuse to buy their products in the future, since I possess all of
the power in that relationship. I bear the burdens and benefits of my
actions.&lt;/p&gt;

&lt;p&gt;When the target of protest is the government, on the other hand, I can lobby or
attempt to vote myself a job and cash. Politicians can try to sell me a free
lunch, and since my vote is infinitesimal, which way I vote doesn't have any
personal ramifications. It is quite understandable that the Spanish and Greeks
want jobs, but when the government is seen to be the solution to unemployment,
the focus changes from job creation to job bestowment.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/haxney/~4/uStYPa97VCk" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.haxney.org/feeds/3455765815934719364/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.haxney.org/2012/09/voting-third-party-and-government-job.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7770370347473031286/posts/default/3455765815934719364?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7770370347473031286/posts/default/3455765815934719364?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/haxney/~3/uStYPa97VCk/voting-third-party-and-government-job.html" title="Voting third party and government job &quot;creation&quot;" /><author><name>Daniel Hackney</name><uri>https://plus.google.com/114139496531318962673</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-wADb4DtR17g/AAAAAAAAAAI/AAAAAAAAAoM/q9V58qhyP4w/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.haxney.org/2012/09/voting-third-party-and-government-job.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUYERX8zfSp7ImA9WhJbEUg.&quot;"><id>tag:blogger.com,1999:blog-7770370347473031286.post-8540920447399430906</id><published>2012-09-20T12:05:00.000-04:00</published><updated>2012-09-20T12:05:04.185-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-09-20T12:05:04.185-04:00</app:edited><title>Change GTK keybindings from Emacs back to default</title><content type="html">&lt;p&gt;Like any virtuous person, I use Emacs for everything, and so tried out using
Emacs key bindings for all GTK applications generally. After a year or so of
working like this, I have decided to go back. The main problem is that other
applications can't handle the awesome power of Emacs. Firefox, for example, uses
&lt;kbd&gt;C-k&lt;/kbd&gt; to jump to the search box, but if you are in the location bar,
&lt;kbd&gt;C-k&lt;/kbd&gt; will run the equivalent of &lt;code&gt;kill-line&lt;/code&gt; which means
that in order to get to the search bar, you have to remove focus from the
location bar. Not convenient.&lt;/p&gt;

&lt;p&gt;Since I do all serious typing within Emacs anyway (using the &lt;a
href="https://addons.mozilla.org/en-US/firefox/addon/its-all-text/"&gt;It's All
Text!&lt;/a&gt; addon to edit &lt;code&gt;textarea&lt;/code&gt;s in Emacs), I figured I might as
well take full advantage of the standard key bindings of the lesser
programs.&lt;/p&gt;

&lt;p&gt;A lot of the guides online talk about editing &lt;code&gt;.gtkrc-2.0&lt;/code&gt; or
setting &lt;code&gt;/desktop/gnome/interface/gtk_key_theme&lt;/code&gt; through Gconf, but
this has ceased to work under Gnome/GTK 3. To fix it, you need to set the value
through &lt;code&gt;gsettings&lt;/code&gt; (which uses &lt;code&gt;dconf&gt;&lt;/code&gt;) rather than
&lt;code&gt;gconf&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;
&lt;code&gt;$ gsettings reset org.gnome.desktop.interface gtk-key-theme&lt;/code&gt;
&lt;/pre&gt;

&lt;p&gt;Why would they break backwards compatibility? Who knows. Also, due to the
brilliance of the Gnome 3 developers, the data for &lt;code&gt;dconf&lt;/code&gt; is stored
in some opaque binary blob, rather than the straightforward XML files used by
&lt;code&gt;gconf&lt;/code&gt;. This is a huge step &lt;em&gt;backwards&lt;/em&gt; from the Unix
philosophy for what appears to be no change in functionality.&lt;/p&gt;

&lt;p&gt;It's things like this, along with brain-dead vomit that is Gnome Shell (or
Unity), that have convinced me that all of the Linux desktop developers have
simultaneously taken crazy pills and have gone insane. Why else break perfectly
good code and interfaces in favor of less functional and less useful
crap?&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/haxney/~4/QZrfAFLm4-A" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.haxney.org/feeds/8540920447399430906/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.haxney.org/2012/09/change-gtk-keybindings-from-emacs-back.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7770370347473031286/posts/default/8540920447399430906?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7770370347473031286/posts/default/8540920447399430906?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/haxney/~3/QZrfAFLm4-A/change-gtk-keybindings-from-emacs-back.html" title="Change GTK keybindings from Emacs back to default" /><author><name>Daniel Hackney</name><uri>https://plus.google.com/114139496531318962673</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-wADb4DtR17g/AAAAAAAAAAI/AAAAAAAAAoM/q9V58qhyP4w/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.haxney.org/2012/09/change-gtk-keybindings-from-emacs-back.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0UEQH86cCp7ImA9WhJVGUs.&quot;"><id>tag:blogger.com,1999:blog-7770370347473031286.post-972083903514617933</id><published>2012-09-06T18:04:00.000-04:00</published><updated>2012-09-06T18:06:41.118-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-09-06T18:06:41.118-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="internet" /><title>Those Dumb Pipes</title><content type="html">&lt;p&gt;
  This is an older idea which had been floating around in my head, half-finished
  for a few years.
&lt;/p&gt;

&lt;p&gt;
  I was inspired by &lt;a
  href="http://arstechnica.com/gadgets/news/2009/02/cellular-providers-want-nokia-to-drop-skype-from-cell-phones.ars"&gt;this
  Ars Technica article&lt;/a&gt; to think about the relationship between network
  operators &amp;mdash; both cellular and landline &amp;mdash; and consumers. The key
  quote from the article is by "one mobile operator" and is:
&lt;/p&gt;

&lt;blockquote&gt;
  Some people like 3 may be in a position where it could make sense to accept
  that. But if you spend upwards of £40m per year building your brand, you don't
  want to be just a dumb pipe do you?
&lt;/blockquote&gt;

&lt;p&gt;
  This is the fundamental tension between consumers and network operators: one
  wants internet access to be a commodity, the other doesn't. Why should I care
  about their brand? Electricity or water utilities don't have a brand. In most
  (all?) cases, they are government-granted monopolies, so there isn't any
  choice, but still, the only time I think about a water or electric company is
  once a month when the bill comes due. The only thing in the world I want from
  those companies is that when I plug in a lamp or turn the faucet, electricity
  or water comes out, (hopefully!) respectively. I want the same to be true of
  ISPs. It annoys me that the word "Verizon" is printed on back of my phone; we
  would think it bizarre if refrigerators had "National Grid" printed on the
  doors.
&lt;/p&gt;

&lt;p&gt;
  Luckily, we have been moving in this direction since the article was written.
  The incredible explosion of smartphones has put huge competitive pressure on
  text messaging, to the point where basically all plans have unlimited voice
  time and text messages, removing that significant avenue of differentiation.
  There's less and less room for the networks to do much of anything aside from
  providing a pipe to the public internet. Despite the fears of Network
  Neutrality advocates (of which I was formerly one) and a lack of legislative
  action, no traffic discrimination has taken place. Gradually, the carriers are
  being ground down into commodities, forced to compete only on quality,
  coverage, and price, and having their profit margins squeezed ever tighter.
&lt;/p&gt;

&lt;p&gt;
  We live in glorious times.
&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/haxney/~4/lo8kGv3eins" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.haxney.org/feeds/972083903514617933/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.haxney.org/2012/09/those-dumb-pipes.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7770370347473031286/posts/default/972083903514617933?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7770370347473031286/posts/default/972083903514617933?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/haxney/~3/lo8kGv3eins/those-dumb-pipes.html" title="Those Dumb Pipes" /><author><name>Daniel Hackney</name><uri>https://plus.google.com/114139496531318962673</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-wADb4DtR17g/AAAAAAAAAAI/AAAAAAAAAoM/q9V58qhyP4w/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.haxney.org/2012/09/those-dumb-pipes.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkUMQno8fCp7ImA9WhJQGUk.&quot;"><id>tag:blogger.com,1999:blog-7770370347473031286.post-169755943029314367</id><published>2012-08-02T17:50:00.001-04:00</published><updated>2012-08-02T17:51:23.474-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-08-02T17:51:23.474-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><category scheme="http://www.blogger.com/atom/ns#" term="dispatch" /><category scheme="http://www.blogger.com/atom/ns#" term="r" /><title>Correctly Dispatching on Generic Methods in `*apply()` in R</title><content type="html">I've been hacking in R recently for work, and it is a bizarrely amazing&lt;br /&gt;
language. I just ran into a situation in which I needed to apply an S3 generic&lt;br /&gt;
function to a list (actually, a row-wise iterator on a &lt;code&gt;data.frame&lt;/code&gt;)&lt;br /&gt;
and hit an annoying rough patch&lt;br /&gt;
&lt;br /&gt;
For those not as well-versed in R (I've been learning it for about two weeks at&lt;br /&gt;
this point), "method dispatch" is done in a quirky yet effective way. You define&lt;br /&gt;
a generic function, say &lt;code&gt;foo&lt;/code&gt; like this:&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/3240247.js?file=DefineGeneric.R"&gt;&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
Which means "when &lt;code&gt;foo()&lt;/code&gt; is called, dispatch to the function&lt;br /&gt;
matching the class of &lt;code&gt;bar&lt;/code&gt;". Setting the class and calling the&lt;br /&gt;
generic method is simply:&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/3240247.js?file=SetClassAndCall.R"&gt;&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
Calling &lt;code&gt;foo(bar)&lt;/code&gt; causes R to look for a function named&lt;br /&gt;
&lt;code&gt;foo.myClass&lt;/code&gt; and calls that. If &lt;code&gt;foo.myClass&lt;/code&gt; is not&lt;br /&gt;
defined, it will try to call &lt;code&gt;foo.otherClass&lt;/code&gt;, then&lt;br /&gt;
&lt;code&gt;foo.default&lt;/code&gt; and if none of those functions exist, it will throw an&lt;br /&gt;
error.&lt;br /&gt;
&lt;br /&gt;
You might have noticed that &lt;code&gt;UseMethod("foo")&lt;/code&gt; doesn't pass along the&lt;br /&gt;
arguments to &lt;code&gt;foo&lt;/code&gt;. R passes the arguments along automagically.&lt;br /&gt;
&lt;br /&gt;
If you want to apply a function to each element to a list, R makes it easy:&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/3240247.js?file=LapplyExample.R"&gt;&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;identity()&lt;/code&gt; and &lt;code&gt;identical()&lt;/code&gt; do what you would expect.&lt;br /&gt;
There are a bunch of variants of &lt;code&gt;apply&lt;/code&gt;; RTFM for the details.&lt;br /&gt;
&lt;br /&gt;
Now let's say we want to call &lt;code&gt;foo()&lt;/code&gt; within &lt;code&gt;lapply()&lt;/code&gt;&lt;br /&gt;
rather than &lt;code&gt;identity&lt;/code&gt;. There are some complications:&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/3240247.js?file=LapplyOnFoo.R"&gt;&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
This throws an error because &lt;code&gt;UseMethod()&lt;/code&gt; tries to dispatch on the&lt;br /&gt;
class of its &lt;em&gt;first&lt;/em&gt; argument, which is a string&lt;br /&gt;
(&lt;code&gt;"character"&lt;/code&gt;, in R parlance). One way to make this work is to&lt;br /&gt;
reverse the order of the arguments so the iteration variable comes first and&lt;br /&gt;
force &lt;code&gt;UseMethod()&lt;/code&gt; to dispatch on a different argument:&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/3240247.js?file=ComplicatedDispatch.R"&gt;&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
Yuck! Wouldn't it be great if there was an easier way? Preferably one which&lt;br /&gt;
doesn't involve hacking R's method dispatch system? Well luckily, there is. We&lt;br /&gt;
take advantage of the fact that R can use named arguments:&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/3240247.js?file=EasyDispatch.R"&gt;&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
It's a bit wonky when coming from normal languages, which wouldn't appreciate a&lt;br /&gt;
named argument being assigned to a variable &lt;em&gt;earlier&lt;/em&gt; in its argument&lt;br /&gt;
list. Again, R is amazingly bizarre and bizarrely amazing. The explicit naming&lt;br /&gt;
of &lt;code&gt;quux&lt;/code&gt; causes it to be "used up" from the argument list, so that&lt;br /&gt;
any remaining arguments are assigned to the "unclaimed" variables. Taking&lt;br /&gt;
advantage of this feature of R lets you apply a generic function to a list (or&lt;br /&gt;
other iterable R objects) without having to mess around with its&lt;br /&gt;
method-dispatching system.&lt;br /&gt;
&lt;br /&gt;
Hopefully this spares a fellow hacker the pain of digging through R's&lt;br /&gt;
documentation on method dispatch.&lt;br /&gt;&lt;img src="http://feeds.feedburner.com/~r/haxney/~4/c6BJvJRzMfY" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.haxney.org/feeds/169755943029314367/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.haxney.org/2012/08/correctly-dispatching-on-generic.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7770370347473031286/posts/default/169755943029314367?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7770370347473031286/posts/default/169755943029314367?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/haxney/~3/c6BJvJRzMfY/correctly-dispatching-on-generic.html" title="Correctly Dispatching on Generic Methods in `*apply()` in R" /><author><name>Daniel Hackney</name><uri>https://plus.google.com/114139496531318962673</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-wADb4DtR17g/AAAAAAAAAAI/AAAAAAAAAoM/q9V58qhyP4w/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.haxney.org/2012/08/correctly-dispatching-on-generic.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUADRX0yeSp7ImA9WhJSFUw.&quot;"><id>tag:blogger.com,1999:blog-7770370347473031286.post-1139856464486769696</id><published>2012-07-05T15:49:00.001-04:00</published><updated>2012-07-05T15:49:34.391-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-07-05T15:49:34.391-04:00</app:edited><title>Listing available monospace fonts in Emacs</title><content type="html">After finding out that the &lt;code&gt;Monospace&lt;/code&gt; font doesn't support italics, I set about trying to find a suitable replacement. &lt;a href="http://www.emacswiki.org/emacs/GoodFonts"&gt;This EmacsWiki page&lt;/a&gt; lists a way to print some example text in all of the fonts on the system, which is very helpful for comparing what's available. The problem with it is that it displays all fonts, not just the monospace fonts, which isn't useful. (For those of you not in the know, all programming is done with monospace or uniform-width fonts, meaning that &lt;code&gt;l&lt;/code&gt; and &lt;code&gt;m&lt;/code&gt; are the same size).&lt;br /&gt;
&lt;br /&gt;
I modified the code so that it displays only monospace fonts. There's probably a property on the font family which one could check, but I used a much more primitive method: measure the pixel width of 5 consecutive lowercase &lt;code&gt;L&lt;/code&gt; characters and 5 lowercase &lt;code&gt;M&lt;/code&gt; characters. If they are the same, then the font is monospaced.&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/3055728.js?file=gistfile1.el"&gt;&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
It isn't perfect (it has a couple of false positives, such as &lt;code&gt;courier 10 pitch&lt;/code&gt;), but it's close enough to be a big improvement.&lt;br /&gt;&lt;img src="http://feeds.feedburner.com/~r/haxney/~4/P98xQm2H29A" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.haxney.org/feeds/1139856464486769696/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.haxney.org/2012/07/listing-available-monospace-fonts-in.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7770370347473031286/posts/default/1139856464486769696?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7770370347473031286/posts/default/1139856464486769696?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/haxney/~3/P98xQm2H29A/listing-available-monospace-fonts-in.html" title="Listing available monospace fonts in Emacs" /><author><name>Daniel Hackney</name><uri>https://plus.google.com/114139496531318962673</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-wADb4DtR17g/AAAAAAAAAAI/AAAAAAAAAoM/q9V58qhyP4w/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.haxney.org/2012/07/listing-available-monospace-fonts-in.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkYBRnw5eyp7ImA9WhJTEUk.&quot;"><id>tag:blogger.com,1999:blog-7770370347473031286.post-1445840173868053510</id><published>2012-06-19T17:09:00.000-04:00</published><updated>2012-06-19T17:09:17.223-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-06-19T17:09:17.223-04:00</app:edited><title>Use FileMaker Web Publishing in Apache</title><content type="html">I've been tasked with nice-ifying the configuration and setup of the systems at work. They store a huge amount (244 GiB) of protein analysis data in a FileMaker database and have PHP scripts accessing the data through the FileMaker XML HTTP API. The problem is that the PHP scripts are running on Apache (as is an SVN repo), but FileMaker wants to publish its API only through IIS. Having spent more than a minute wrestling with configuring IIS, I want it out of my life ASAP. But that can't be done unless scripts have a way of talking XML to FileMaker on port 80. All hope seemed lost.&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
I thought about reverse proxying requests to FileMaker, since it exposes part of its API on a separate port (16020), but not all of the required functionality can be reverse proxied so easily. I could reverse proxy all of the FileMaker paths on IIS, but that doesn't help get rid of IIS and only makes things more complicated.&lt;br /&gt;
&lt;br /&gt;
The answer came from &lt;a href="http://www.techno-obscura.com/~delgado/blog/2009/04/proxy-for-filemaker-10-iwp/"&gt;this blog post from 2009&lt;/a&gt; about this very same issue. I couldn't quite get things to work by following his directions and dug into the FileMaker web server config files.&lt;br /&gt;
&lt;br /&gt;
The IIS module provided by FileMaker was nothing more than the generic &lt;a href="https://tomcat.apache.org/connectors-doc/webserver_howto/iis.html"&gt;IIS-to-Tomcat connector&lt;/a&gt;. There isn't anything IIS-specific about Tomcat, and the filter does nothing but point IIS towards a Jakarta config. That being the case, I read the &lt;a href="https://tomcat.apache.org/connectors-doc/reference/apache.html"&gt;Apache httpd docs&lt;/a&gt; and configured Apache the same way as IIS. Rather than replicating the Jakarta files, as the 2009 blog post did, I simply pointed Apache at them, leaving me with this configuration:&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/2956532.js"&gt; &lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
This was more hours of agony than it had any right to be, so I hope I can spare you, dear reader, some of the pain I felt.&lt;br /&gt;&lt;img src="http://feeds.feedburner.com/~r/haxney/~4/LZsI1Juzyrw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.haxney.org/feeds/1445840173868053510/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.haxney.org/2012/06/use-filemaker-web-publishing-in-apache.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7770370347473031286/posts/default/1445840173868053510?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7770370347473031286/posts/default/1445840173868053510?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/haxney/~3/LZsI1Juzyrw/use-filemaker-web-publishing-in-apache.html" title="Use FileMaker Web Publishing in Apache" /><author><name>Daniel Hackney</name><uri>https://plus.google.com/114139496531318962673</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-wADb4DtR17g/AAAAAAAAAAI/AAAAAAAAAoM/q9V58qhyP4w/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.haxney.org/2012/06/use-filemaker-web-publishing-in-apache.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0ENQX47cSp7ImA9WhJRFEg.&quot;"><id>tag:blogger.com,1999:blog-7770370347473031286.post-5398494595378318843</id><published>2012-06-18T23:32:00.001-04:00</published><updated>2012-07-16T11:14:50.009-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-07-16T11:14:50.009-04:00</app:edited><title>When European "Austerity" Isn't</title><content type="html">I've been skeptical of the rhetoric that there has been "brutal, crushing austerity" in Europe. When these claims are made, I have seldom heard any quantification of how brutal these "brutal" changes have been. So I &lt;a href="http://s.haxney.org/KNUnMw"&gt;looked it up&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Short version: there's been minimal to negative austerity since pre-meltdown 2008.&lt;br /&gt;
&lt;br /&gt;
Longer version:&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;There was a bump up in spending in the PIIGS (Portugal, Ireland, Italy, Greece, and Spain) countries now in the news and some of those countries went back to around their 2008 level of spending.&lt;br /&gt;
&lt;br /&gt;
I went ahead and looked at&amp;nbsp;&lt;a href="https://s.haxney.org/KNUnMw"&gt;the Eurostat data&lt;/a&gt; on Eurozone government spending, and it certainly does not paint a picture of a draconian, totalitarian decrease in state spending. I compiled the Eurostat data into a &lt;a href="https://docs.google.com/spreadsheet/ccc?key=0Ain9fnIYwc83dGFtTmZNb0FCVU9ldzI2NFcyR2NJa1E"&gt;spreadsheet&lt;/a&gt; &lt;strike&gt;(with &lt;a href="https://s.haxney.org/LXslj4"&gt;US data&lt;/a&gt; included for flavor)&lt;/strike&gt; and plotted out some charts.&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;Update&lt;/strong&gt;: I've removed the US data because they are for the federal government only whereas the EU data is for total spending across all levels of government. If anyone has a pointer to a source for aggregated US local, state, and federal spending, I'd be interested in that as well. The claim that US government spending cratered post-2008 seems too politically convenient to be true.&lt;br /&gt;
&lt;br /&gt;
First, the total government spending of the European Union, the Eurozone (those countries which use the Euro), &lt;strike&gt;and the US (Dollars converted to Euros)&lt;/strike&gt; since 2002:&lt;br /&gt;
&lt;br /&gt;
&lt;script type="text/javascript" src="//ajax.googleapis.com/ajax/static/modules/gviz/1.0/chart.js"&gt; {"dataSourceUrl":"//docs.google.com/a/haxney.org/spreadsheet/tq?key=0Ain9fnIYwc83dGFtTmZNb0FCVU9ldzI2NFcyR2NJa1E&amp;transpose=1&amp;headers=1&amp;merge=ROWS&amp;range=A1%3AK1%2CA15%3AT15%2CA18%3AT18&amp;gid=18&amp;pub=1","options":{"vAxes":[{"useFormatFromData":false,"title":"Spending (Billion \u20ac)","formatOptions":{"source":"none","scaleFactor":"1000"},"viewWindowMode":"pretty","viewWindow":{}},{"useFormatFromData":true,"viewWindowMode":"pretty","viewWindow":{}}],"series":{"2":{"color":"#0000ff","pointSize":5},"1":{"pointSize":5},"0":{"color":"#ff9900","pointSize":5}},"curveType":"","booleanRole":"certainty","title":"Region Economies","animation":{"duration":0},"lineWidth":2,"useFirstColumnAsDomain":true,"hAxis":{"useFormatFromData":true,"title":"Year","gridlines":{"count":"10"}},"width":"100%","height":"100%"},"state":{},"chartType":"LineChart","chartName":"Chart 3"} &lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
Next, the GPI (Greece, Portugal, Ireland) countries:&lt;br /&gt;
&lt;br /&gt;
&lt;script type="text/javascript" src="//ajax.googleapis.com/ajax/static/modules/gviz/1.0/chart.js"&gt; {"dataSourceUrl":"//docs.google.com/a/haxney.org/spreadsheet/tq?key=0Ain9fnIYwc83dGFtTmZNb0FCVU9ldzI2NFcyR2NJa1E&amp;transpose=1&amp;headers=1&amp;merge=ROWS&amp;range=A1%3AK1%2CA22%3AT22%2CA34%3AT34%2CA25%3AT25&amp;gid=18&amp;pub=1","options":{"vAxes":[{"useFormatFromData":false,"title":"Spending (Billion EUR)","formatOptions":{"source":"none","scaleFactor":"1000"},"viewWindowMode":"pretty","viewWindow":{}},{"useFormatFromData":true,"viewWindowMode":"pretty","viewWindow":{}}],"series":{"0":{"pointSize":5},"1":{"pointSize":5},"2":{"pointSize":5}},"curveType":"","booleanRole":"certainty","title":"Greece, Portugal, and Ireland","height":"100%","animation":{"duration":500},"width":"100%","lineWidth":2,"useFirstColumnAsDomain":true,"annotations":{"domain":{}},"hAxis":{"useFormatFromData":true,"title":"Year","gridlines":{"count":"10"}}},"state":{},"chartType":"LineChart","chartName":"Chart 3"} &lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
And finally, the biggest spenders in Europe. I included them separately from the GPI (or PIG) countries because the chart ends up mostly empty with all included.&lt;br /&gt;
&lt;br /&gt;
&lt;script type="text/javascript" src="//ajax.googleapis.com/ajax/static/modules/gviz/1.0/chart.js"&gt; {"dataSourceUrl":"//docs.google.com/a/haxney.org/spreadsheet/tq?key=0Ain9fnIYwc83dGFtTmZNb0FCVU9ldzI2NFcyR2NJa1E&amp;transpose=1&amp;headers=1&amp;merge=ROWS&amp;range=A1%3AK1%2CA20%3AT21%2CA26%3AT26%2CA38%3AT38%2CA41%3AT41&amp;gid=18&amp;pub=1","options":{"vAxes":[{"title":"Spending (Billion \u20ac)","useFormatFromData":false,"formatOptions":{"source":"none","scaleFactor":"1000"},"viewWindowMode":"pretty","viewWindow":{}},{"useFormatFromData":true,"title":"Spending (Billion \u20ac/$)","formatOptions":{"scaleFactor":"1000"},"viewWindowMode":"pretty","viewWindow":{}}],"series":{"0":{"pointSize":5},"1":{"pointSize":5},"2":{"pointSize":5},"3":{"pointSize":5},"4":{"pointSize":5}},"booleanRole":"certainty","curveType":"","title":"Large Economies","animation":{"duration":500},"legend":"right","lineWidth":2,"useFirstColumnAsDomain":true,"annotations":{"domain":{}},"hAxis":{"title":"Year","useFormatFromData":true,"formatOptions":{"source":"data"},"gridlines":{"count":"10"}},"width":"100%","height":"100%"},"state":{},"chartType":"LineChart","chartName":"Chart 3"} &lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
As you can see, not nearly the inhumane government takeover of governmental reduction that it's sometimes claimed to be.&lt;br /&gt;
&lt;br /&gt;
As a final piece of analysis, I looked at 2011 spending as a percentage of 2008 (as in pre-meltdown) spending. Only 10 out of the 41 countries (Switzerland didn't have 2011 numbers) had decreased spending since 2008: Iceland, Latvia, Greece, Romania, Hungary, Estonia, Lithuania, UK, Ireland, and Bulgaria. With the exceptions of Iceland and Latvia, all of the countries spent at least 90% as much in 2011 as they did in 2008. Take a look:&lt;br /&gt;
&lt;br /&gt;
&lt;script type="text/javascript" src="//ajax.googleapis.com/ajax/static/modules/gviz/1.0/chart.js"&gt; {"dataSourceUrl":"//docs.google.com/a/haxney.org/spreadsheet/tq?key=0Ain9fnIYwc83dGFtTmZNb0FCVU9ldzI2NFcyR2NJa1E&amp;transpose=0&amp;headers=1&amp;merge=COLS&amp;range=A1%3AB66%2CC1%3AC41&amp;gid=17&amp;pub=1","options":{"vAxes":[{"useFormatFromData":true,"title":"","viewWindowMode":"pretty","viewWindow":{},"gridlines":{"count":"5"}},{"useFormatFromData":true,"viewWindowMode":"pretty","viewWindow":{}}],"booleanRole":"certainty","title":"2011 Spending as a percentage of 2007/2008","animation":{"duration":0},"domainAxis":{"direction":1},"legend":"top","hAxis":{"useFormatFromData":true,"title":"","viewWindowMode":"pretty","viewWindow":{}},"isStacked":false,"width":"100%","height":"100%"},"state":{},"chartType":"ColumnChart","chartName":"Chart 4"} &lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;strong&gt;Update:&lt;/strong&gt; It was suggested that I compare 2011 spending to that of 2007 as well, since some countries peaked around then. It actually ends up being more of an argument against the existence of "austerity," with only three countries decreasing their spending over the period: Iceland, the UK, and Hungary.&lt;br /&gt;
&lt;br /&gt;
&lt;strike&gt;By the way, the US -- the pinnacle of ruthless Reganomics -- spent 120% of its 2008 level in 2011, third only to Luxembourg and Norway in governmental largess.&lt;/strike&gt;&lt;br /&gt;
&lt;br /&gt;
All of my raw data are available &lt;a href="https://docs.google.com/spreadsheet/ccc?key=0Ain9fnIYwc83dGFtTmZNb0FCVU9ldzI2NFcyR2NJa1E"&gt;here&lt;/a&gt;.&lt;img src="http://feeds.feedburner.com/~r/haxney/~4/HL0ptrP-300" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.haxney.org/feeds/5398494595378318843/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.haxney.org/2012/06/when-european-austerity-isnt.html#comment-form" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7770370347473031286/posts/default/5398494595378318843?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7770370347473031286/posts/default/5398494595378318843?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/haxney/~3/HL0ptrP-300/when-european-austerity-isnt.html" title="When European &quot;Austerity&quot; Isn't" /><author><name>Daniel Hackney</name><uri>https://plus.google.com/114139496531318962673</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-wADb4DtR17g/AAAAAAAAAAI/AAAAAAAAAoM/q9V58qhyP4w/s512-c/photo.jpg" /></author><thr:total>2</thr:total><feedburner:origLink>http://www.haxney.org/2012/06/when-european-austerity-isnt.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0EGRXY7fip7ImA9WhVaEUs.&quot;"><id>tag:blogger.com,1999:blog-7770370347473031286.post-6355510299213894704</id><published>2012-06-08T11:33:00.001-04:00</published><updated>2012-06-08T11:33:44.806-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-06-08T11:33:44.806-04:00</app:edited><title>Solving mod_dav_svn loading faliure on Apache in Windows</title><content type="html">Yesterday, I spent &lt;i&gt;way&lt;/i&gt; too much time trying to get Subversion working under Apache in Windows 7. I really have a new appreciation for GNU/Linux package managers; what would have been &lt;code&gt;sudo aptitude install libapache2-svn&lt;/code&gt; under Ubuntu turned into hours of staring at &lt;code&gt;Syntax error on line 270 of C:/Program Files (x86)/Apache Software Foundation/Apache2.2/conf/httpd.conf: Cannot load C:/Program Files (x86)/Apache Software Foundation/Apache2.2/modules/mod_dav_svn.so into server: The specified procedure could not be found.&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
I tried copying all of the SVN libraries into &lt;code&gt;bin&lt;/code&gt; within the server root, downloading different versions from the web, and "unblocking" the libraries (Windows blocks code downloaded from the internet. Nice idea; I only wish it would tell you about it). Finally, after &lt;b&gt;hours&lt;/b&gt; of Googling, I found some post on some forum somewhere that mentioned using the &lt;code&gt;libapr-1.dll&lt;/code&gt; from the Subversion distribution rather than Apache's would help. It did.&lt;br /&gt;
&lt;br /&gt;
This would seem to undermine somewhat the idea of the "Apache &lt;i&gt;Portable&lt;/i&gt; Runtime". But whatever; I have a working system. Now onto trying to get LDAP set up for SVN and Ubuntu. Wish me luck!&lt;br /&gt;
&lt;br /&gt;
TL;DR: If Apache in Windows fails to start with &lt;code&gt;mod_dav_svn.so&lt;/code&gt; loaded in your &lt;code&gt;conf/httpd.conf&lt;/code&gt; and you get this error in your Event Viewer: &lt;code&gt;Syntax error on line 270 of C:/Program Files (x86)/Apache Software Foundation/Apache2.2/conf/httpd.conf: Cannot load C:/Program Files (x86)/Apache Software Foundation/Apache2.2/modules/mod_dav_svn.so into server: The specified procedure could not be found.&lt;/code&gt;, you can solve it by copying &lt;code&gt;libapr-1.dll&lt;/code&gt; from &lt;code&gt;Subversion/bin&lt;/code&gt; to &lt;code&gt;Apache2.2/bin&lt;/code&gt;, replacing the version which ships with Apache.&lt;img src="http://feeds.feedburner.com/~r/haxney/~4/OxPTF-8_bw4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.haxney.org/feeds/6355510299213894704/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.haxney.org/2012/06/solving-moddavsvn-loading-faliure-on.html#comment-form" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7770370347473031286/posts/default/6355510299213894704?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7770370347473031286/posts/default/6355510299213894704?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/haxney/~3/OxPTF-8_bw4/solving-moddavsvn-loading-faliure-on.html" title="Solving mod_dav_svn loading faliure on Apache in Windows" /><author><name>Daniel Hackney</name><uri>https://plus.google.com/114139496531318962673</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-wADb4DtR17g/AAAAAAAAAAI/AAAAAAAAAoM/q9V58qhyP4w/s512-c/photo.jpg" /></author><thr:total>2</thr:total><feedburner:origLink>http://www.haxney.org/2012/06/solving-moddavsvn-loading-faliure-on.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CE8MSH0_cCp7ImA9WhVbGEo.&quot;"><id>tag:blogger.com,1999:blog-7770370347473031286.post-4266161943157126896</id><published>2012-06-05T01:08:00.000-04:00</published><updated>2012-06-05T01:08:09.348-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-06-05T01:08:09.348-04:00</app:edited><title>Metaphor for Europe's Troubles</title><content type="html">&lt;p&gt;Based on my decades of experience in the sovereign debt markets, I have
come up with a perfect metaphor for what is going on in the Eurozone. It
is as if the Grace government promised 200,000 people one boat each, but
now that the boats are due, it turns out that she doesn't have 200,000
boats anywhere, there are only 100,000. Grace tries telling half of the
people not to try to use their boat; to pretend that it is sitting in a
port somewhere, waiting for them. If some people use their boat half of
the week, other people can use it for the other half of the week, so it
is "like" having 200,000 boats. Uncle Jeremy has 1.5 million boats, but
he isn't so thrilled about just handing over a bunch of his boats to
Grace, who knew she promised more than she had. Jeremy says "I'll give
you 50,000 of my boats, but only if you tell 50,000 people that they
aren't getting a boat at all." Grace is furious, shouting "you're
forcing boat austerity on me! I need to implement boat-growth policies!"
Of course, "boat-growth policies" is a euphemism for "Jeremy gives me
more boats."&lt;/p&gt;

&lt;p&gt;Grace then proposes a consolidated "Euroboat" concept, in which all of
Grace's, Jeremy's, Ira's, Talia's, and Pete's boats are lumped together
and then given out to each of their citizens, regardless of how many
boats each person (government) has. It just so happens that Jeremy has
1.5 million boats and has promised 750k of his citizens one boat each,
but all of the other governments have promised more boats than they
have, and have even promised more than the 750k spare boats that Jeremy
has. Jeremy, understandably, doesn't want to give out all of the spare
boats he has to people who promised more than they had, but when he
tells the other people this, they get angry and call him mean names.
Jeremy tries to explain that even if he was to give out all of the extra
boats he has, and cut back on a bunch of the boats he already promised
to his citizens, there would still not be enough boats for all the
people who promised more boats than they knew they had.&lt;/p&gt;

&lt;p&gt;Some people want their acquaintance Mario to print them a bunch of
boats.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/haxney/~4/FbH1F0gjTuc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.haxney.org/feeds/4266161943157126896/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.haxney.org/2012/06/metaphor-for-europes-troubles.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7770370347473031286/posts/default/4266161943157126896?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7770370347473031286/posts/default/4266161943157126896?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/haxney/~3/FbH1F0gjTuc/metaphor-for-europes-troubles.html" title="Metaphor for Europe's Troubles" /><author><name>Daniel Hackney</name><uri>https://plus.google.com/114139496531318962673</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-wADb4DtR17g/AAAAAAAAAAI/AAAAAAAAAoM/q9V58qhyP4w/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.haxney.org/2012/06/metaphor-for-europes-troubles.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkQDRXg-fip7ImA9WhJTEU4.&quot;"><id>tag:blogger.com,1999:blog-7770370347473031286.post-6152814112777240482</id><published>2012-06-01T16:00:00.000-04:00</published><updated>2012-06-19T16:39:34.656-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-06-19T16:39:34.656-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="EA support commendation" /><title>EA support is wonderful</title><content type="html">I contacted EA support today to get my reward for participating in last weekend's Mass Effect 3 Bounty Weekend: &lt;a href="http://blog.bioware.com/2012/05/23/operation-shieldwall/"&gt;Operation Shieldwall&lt;/a&gt;. I achieved the individual goal, but didn't get the priiiize, so I went to EA for help. Maybe 10 minutes later, it was done. Thank you to "Larry S" for helping me. Here is the log of my chat with him; I want to give credit where credit is due for his professionalism and speed.&lt;br /&gt;
&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
You are now ready to chat with Larry S. &lt;br /&gt;
&lt;div class="chat-row convo"&gt;
&lt;b class="chat-by"&gt;Larry S: &lt;/b&gt;Thanks for contacting EA Help! My name is Larry S how may I help you?&lt;/div&gt;
&lt;div class="chat-row convo"&gt;
&lt;b class="chat-by self"&gt;you: &lt;/b&gt;I participated in the previous weekend challenge but haven't gotten my commendation pack&lt;/div&gt;
&lt;div class="chat-row convo"&gt;
&lt;b class="chat-by self"&gt;you: &lt;/b&gt;I'm pretty sure I promoted more than 3 classes within the time window&lt;/div&gt;
&lt;div class="chat-row convo"&gt;
&lt;b class="chat-by"&gt;Larry S: &lt;/b&gt;&lt;span dir="ltr"&gt;No problem. I will be glad to provide you the pack.&lt;/span&gt;&lt;/div&gt;
&lt;div class="chat-row convo"&gt;
&lt;b class="chat-by self"&gt;you: &lt;/b&gt;I certainly promoted more than 3 within the weekend, but I'm not sure it was exactly in the window&lt;/div&gt;
&lt;div class="chat-row convo"&gt;
&lt;b class="chat-by"&gt;Larry S: &lt;/b&gt;&lt;span dir="ltr"&gt;May I know the name of the weekend challenge?&lt;/span&gt;&lt;/div&gt;
&lt;div class="chat-row convo"&gt;
&lt;b class="chat-by self"&gt;you: &lt;/b&gt;I only started promoting after the operation description popped up&lt;/div&gt;
&lt;div class="chat-row convo"&gt;
&lt;b class="chat-by"&gt;Larry S: &lt;/b&gt;&lt;span dir="ltr"&gt;May I know the name of the weekend challenge?&lt;/span&gt;&lt;/div&gt;
&lt;div class="chat-row convo"&gt;
&lt;b class="chat-by self"&gt;you: &lt;/b&gt;Shieldwall, I believe&lt;/div&gt;
&lt;div class="chat-row convo"&gt;
&lt;b class="chat-by self"&gt;you: &lt;/b&gt;let me double check&lt;/div&gt;
&lt;div class="chat-row convo"&gt;
&lt;b class="chat-by self"&gt;you: &lt;/b&gt;yup, shieldwall&lt;/div&gt;
&lt;div class="chat-row convo"&gt;
&lt;b class="chat-by"&gt;Larry S: &lt;/b&gt;&lt;span dir="ltr"&gt;Okay. I can provide it. May I have the Origin email id in which you have registered the game?&lt;/span&gt;&lt;/div&gt;
&lt;div class="chat-row convo"&gt;
&lt;b class="chat-by self"&gt;you: &lt;/b&gt;the email I used is dan@haxney.org&lt;/div&gt;
&lt;div class="chat-row convo"&gt;
&lt;b class="chat-by self"&gt;you: &lt;/b&gt;my origin ID is "haxney"&lt;/div&gt;
&lt;div class="chat-row convo"&gt;
&lt;b class="chat-by"&gt;Larry S: &lt;/b&gt;&lt;span dir="ltr"&gt;Thank you.&lt;/span&gt;&lt;/div&gt;
&lt;div class="chat-row convo"&gt;
&lt;b class="chat-by self"&gt;you: &lt;/b&gt;Just about everything else related to me is "haxney" :)&lt;/div&gt;
&lt;div class="chat-row convo"&gt;
&lt;b class="chat-by"&gt;Larry S: &lt;/b&gt;&lt;span dir="ltr"&gt;May I know your first name and last name?&lt;/span&gt;&lt;/div&gt;
&lt;div class="chat-row convo"&gt;
&lt;b class="chat-by self"&gt;you: &lt;/b&gt;Daniel Hackney&lt;/div&gt;
&lt;div class="chat-row convo"&gt;
&lt;b class="chat-by self"&gt;you: &lt;/b&gt;the "haxney" is a play off my last name. I'm a hacker (original meaning of the word: computer programmer)&lt;/div&gt;
&lt;div class="chat-row convo"&gt;
&lt;b class="chat-by"&gt;Larry S: &lt;/b&gt;&lt;span dir="ltr"&gt;Would you mind holding for some time while I provide the pack in your account Daniel?&lt;/span&gt;&lt;/div&gt;
&lt;div class="chat-row convo"&gt;
&lt;b class="chat-by self"&gt;you: &lt;/b&gt;sure thing. Thank you very much&lt;/div&gt;
&lt;div class="chat-row convo"&gt;
&lt;b class="chat-by"&gt;Larry S: &lt;/b&gt;&lt;span dir="ltr"&gt;My pleasure.&lt;/span&gt;&lt;/div&gt;
&lt;div class="chat-row convo"&gt;
&lt;b class="chat-by"&gt;Larry S: &lt;/b&gt;&lt;span dir="ltr"&gt;Please check now in the game.&lt;/span&gt;&lt;/div&gt;
&lt;div class="chat-row convo"&gt;
&lt;b class="chat-by self"&gt;you: &lt;/b&gt;sure, give me a second for it to launch&lt;/div&gt;
&lt;div class="chat-row convo"&gt;
&lt;b class="chat-by"&gt;Larry S: &lt;/b&gt;&lt;span dir="ltr"&gt;No problem.&lt;/span&gt;&lt;/div&gt;
&lt;div class="chat-row convo"&gt;
&lt;b class="chat-by self"&gt;you: &lt;/b&gt;It's there! That was very quick&lt;/div&gt;
&lt;div class="chat-row convo"&gt;
&lt;b class="chat-by"&gt;Larry S: &lt;/b&gt;&lt;span dir="ltr"&gt;Great.&lt;/span&gt;&lt;/div&gt;
&lt;div class="chat-row convo"&gt;
&lt;b class="chat-by self"&gt;you: &lt;/b&gt;Thank you, you have been very helpful&lt;/div&gt;
&lt;div class="chat-row convo"&gt;
&lt;b class="chat-by"&gt;Larry S: &lt;/b&gt;&lt;span dir="ltr"&gt;My pleasure.&lt;/span&gt;&lt;/div&gt;
&lt;div class="chat-row convo"&gt;
&lt;b class="chat-by"&gt;Larry S: &lt;/b&gt;Thank you for contacting EA. Is there anything else I can help you with today?&lt;/div&gt;
&lt;div class="chat-row convo"&gt;
&lt;b class="chat-by self"&gt;you: &lt;/b&gt;That's it for today. I shall sing praises of your responsiveness and professionalism to the blogosphere&lt;/div&gt;
&lt;div class="chat-row convo"&gt;
&lt;b class="chat-by"&gt;Larry S: &lt;/b&gt;&lt;span dir="ltr"&gt;Thank you Daniel.&lt;/span&gt;&lt;/div&gt;
&lt;div class="chat-row convo"&gt;
&lt;b class="chat-by"&gt;Larry S: &lt;/b&gt;If you need help with anything else, please feel free to contact us anytime!&lt;/div&gt;
&lt;div class="chat-row convo"&gt;
&lt;b class="chat-by"&gt;Larry S: &lt;/b&gt;&lt;span dir="ltr"&gt;Have a nice day.&lt;/span&gt;&lt;/div&gt;
&lt;div class="chat-row convo"&gt;
&lt;b class="chat-by self"&gt;you: &lt;/b&gt;Have a great day!&lt;/div&gt;
&lt;div class="chat-row convo"&gt;
&lt;b class="chat-by"&gt;Larry S: &lt;/b&gt;&lt;span dir="ltr"&gt;Take care.&lt;/span&gt;&lt;/div&gt;
&lt;div class="chat-row convo"&gt;
&lt;b class="chat-by"&gt;Larry S: &lt;/b&gt;&lt;span dir="ltr"&gt;Bye.&lt;/span&gt;&lt;/div&gt;
&lt;div class="chat-row info"&gt;
&lt;b class="disabled margin"&gt;&lt;/b&gt;The chat session has ended. Please contact us again if you need further help.&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;img src="http://feeds.feedburner.com/~r/haxney/~4/77_DCWSpVkA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.haxney.org/feeds/6152814112777240482/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.haxney.org/2012/06/ea-support-is-wonderful.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7770370347473031286/posts/default/6152814112777240482?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7770370347473031286/posts/default/6152814112777240482?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/haxney/~3/77_DCWSpVkA/ea-support-is-wonderful.html" title="EA support is wonderful" /><author><name>Daniel Hackney</name><uri>https://plus.google.com/114139496531318962673</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-wADb4DtR17g/AAAAAAAAAAI/AAAAAAAAAoM/q9V58qhyP4w/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.haxney.org/2012/06/ea-support-is-wonderful.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEUGQnc7fCp7ImA9WhVWEU4.&quot;"><id>tag:blogger.com,1999:blog-7770370347473031286.post-8643376412488717061</id><published>2012-04-22T19:09:00.000-04:00</published><updated>2012-04-22T19:10:23.904-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-04-22T19:10:23.904-04:00</app:edited><title>Simple recursive file traversal in Elisp</title><content type="html">&lt;p&gt;
  Really quick: I wrote a simple bit of elisp to &lt;code&gt;eval&lt;/code&gt; a body over
  each of the files in a directory, recursively. Looking around for a little
  bit, I found a couple of options, including &lt;a
  href="http://www.emacswiki.org/emacs/FindrPackage"&gt;Findr&lt;/a&gt;, which has its
  own queue implementation (pretty short), and whose main function is a whopping
  55 lines!
&lt;/p&gt;

&lt;p&gt;
  &lt;emph&gt;There has to be a quicker way&lt;/emph&gt;, I thought. I didn't need anything
  terribly fancy, I just wanted something that worked cross-platform (which
  ruled out &lt;code&gt;find&lt;/code&gt;) and was simple. I ended up with this little guy:
&lt;/p&gt;

&lt;script src="https://gist.github.com/2467266.js?file=simple-recursive.el"&gt;&lt;/script&gt;

&lt;p&gt;
  11 lines for the main function, &lt;code&gt;recursive-files&lt;/code&gt; itself, and
  another 3 (including docstring) for simplifying macro. It's main weakness at
  this point is that it incorrectly ignores any files with leading dots. So not
  only does it (wisely) avoid &lt;code&gt;.&lt;/code&gt; and &lt;code&gt;..&lt;/code&gt;, it rather
  foolishly avoids &lt;code&gt;.foo&lt;/code&gt; as well. I couldn't easily figure out how
  to exclude &lt;code&gt;.&lt;/code&gt; and &lt;code&gt;..&lt;/code&gt; in a single regex easily without
  also excluding leading-dot files. For what I'm doing, it's not important.
&lt;/p&gt;

&lt;p&gt;
  Also, note that this barfs on symlinks. It thinks they're directories and
  tries to call &lt;code&gt;directory-files-and-attributes&lt;/code&gt; on them. Again, a
  more careful implementation would deal with this.
&lt;/p&gt;

&lt;p&gt;
  I was surprised that Emacs didn't have a "recursively visit files" function or
  macro built in, but this gets me close enough. Enjoy!
&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/haxney/~4/Gdjm4c5TnCo" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.haxney.org/feeds/8643376412488717061/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.haxney.org/2012/04/really-quick-i-wrote-simple-bit-of.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7770370347473031286/posts/default/8643376412488717061?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7770370347473031286/posts/default/8643376412488717061?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/haxney/~3/Gdjm4c5TnCo/really-quick-i-wrote-simple-bit-of.html" title="Simple recursive file traversal in Elisp" /><author><name>Daniel Hackney</name><uri>https://plus.google.com/114139496531318962673</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-wADb4DtR17g/AAAAAAAAAAI/AAAAAAAAAoM/q9V58qhyP4w/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.haxney.org/2012/04/really-quick-i-wrote-simple-bit-of.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkMBQXk_eCp7ImA9WhJTEU4.&quot;"><id>tag:blogger.com,1999:blog-7770370347473031286.post-7296075127036748439</id><published>2012-02-27T20:47:00.001-05:00</published><updated>2012-06-19T16:40:50.740-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-06-19T16:40:50.740-04:00</app:edited><title>The Ongoing Saga of Making Ubuntu 11.10 Usable</title><content type="html">Alright, I installed Ubuntu 11.10 (aka "lost all common sense" edition) on a   new computer, so I have the memory of trying to make it bearable still in my   head. The absolute necessary first thing to do is: &lt;br /&gt;
&lt;script src="https://gist.github.com/1926395.js?file=compiz.sh"&gt;
&lt;/script&gt;  &lt;br /&gt;
And set your login session to "Gnome fallback". This gives you a   &lt;i&gt;passable&lt;/i&gt; facsimile of Gnome 2 (aka "worked and was not useless"   edition). I am a little... offended is to strong, but miffed that "fallback"   means "what to use if you want to get work done and are not, in fact, a   hipster," but whatever.&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
You have to &lt;code&gt;Alt+right click&lt;/code&gt; (&lt;code&gt;M-&amp;lt;mouse-3&amp;gt;&lt;/code&gt; for   the enlightened Emacs users) in order to right click on the panels now. Now I   know what you're thinking, "what did they set to right click which   necessitated bumping &lt;code&gt;right click&lt;/code&gt; to &lt;code&gt;Alt+right   click&lt;/code&gt;?" The answer is "nothing". That's right, if you right click on   the panel in Gnome 3, nothing happens. Which naturally might lead you to   wonder "so why take something which worked and was simple and make it more   complicated while substituting nothing in return?" Because "liquid intuitive   natural human smooth &lt;i&gt;desktop metaphor&lt;/i&gt;", that's why. Probably   something to do with netbook/tablet/&lt;code&gt;$CURRENT_FAD&lt;/code&gt;. &lt;br /&gt;
Anywhoo, the next step is installing Compiz, which gives you more (read: any)   customization and, most importantly, wobbly windows. It used to be a simple   click in System → Preferences → Appearance → Effects and away   you wobbly went! Now, you have to dig into   &lt;code&gt;compiz-config-settings-manager&lt;/code&gt; a bit. First, install compiz and   the settings manager: &lt;br /&gt;
&lt;script src="https://gist.github.com/1926395.js?file=compiz.sh"&gt;
&lt;/script&gt;  &lt;br /&gt;
I won't go into all the options here, but if you open &lt;code&gt;ccsm&lt;/code&gt; (short   for "compiz config settings manager") and look around, you can fix the lack of   wobbly windows as well as focus-follows-mouse. I really can't use a computer   without those two. &lt;br /&gt;
To get rid of the global menu bar (in what drug-fueled rage did this seem like   a good idea), just run: &lt;br /&gt;
&lt;script src="https://gist.github.com/1926395.js?file=global-menu.sh"&gt;
&lt;/script&gt;  &lt;br /&gt;
Who doesn't love the idea of scroll bars which try their darnedest to evade   your mouse pointer? I know that it becomes even more of a &lt;strike&gt;huge   pain&lt;/strike&gt; metaphorical adventure with focus-follows-mouse. If you move   the mouse off of the scroll... thing, it changes your window focus. Oh, and   did I mention that "off of" can mean "above or below, if the scroll thing   thinks you shouldn't have moved your pointer that direction?" Well, it does.   If you anger the scroll-thing gods, they will become cross and punish you for   your wickedness by making the scroll thing forever evade your grasp. It's kind   of like Sisyphus, but you are forever chasing a scroll thing you can never   quite catch. &lt;br /&gt;
Anyway, to make it die the horrible flaming death it so rightly deserves, run   the following (you may need to log out and back in for it to take effect): &lt;br /&gt;
&lt;script src="https://gist.github.com/1926395.js?file=scroll-bars.sh"&gt;
&lt;/script&gt;  &lt;br /&gt;
Now, to make the window decorators okay again, like they were when everything   was fine, run this (you'll probably have to log out and back in again): &lt;br /&gt;
&lt;script src="https://gist.github.com/1926395.js?file=window-decorator.sh"&gt;
&lt;/script&gt;  &lt;br /&gt;
And no, I couldn't find an easier way to do this. The advantage the default   decorators have over the crappy (aka new) ones is that you can actually tell   the difference between the active window and background ones. In both   "Ambiance" and "Radiance" the (only) theme options, the difference between the   current and background windows is that the window title — not the window   &lt;i&gt;bar&lt;/i&gt;, but just the title text — goes from gray to grayish.   Thanks Ubuntu. &lt;br /&gt;
This also has the advantage of restoring the window borders, so that if, for   example, you are trying to resize a window, you don't have to hit the   one-pixel-wide target area in order to resize. Apparently, according to   the geniuses in charge of designing the new interface, being able to resize   windows easily is not &lt;i&gt;NEW INTERFACE METAPHOR&lt;/i&gt;-y enough. &lt;br /&gt;
At this point, you have restored your computer to a reasonably-functional   state. You may be wondering, as I did, why the developers of a distribution   would take something which was &lt;b&gt;just fine&lt;/b&gt;, did what you   needed, and was instantly familiar to everyone who has used a computer before,   and replace it with the user-interface version of &lt;a href="http://knowyourmeme.com/memes/interior-semiotics"&gt;Interior   Semiotics&lt;/a&gt;. I have two hypotheses: &lt;br /&gt;
&lt;ol&gt;&lt;li&gt;     A couple guys glanced at an iPad, saw that it couldn't do as many useful     things as a real computer, and thought "hey, we could make &lt;i&gt;our&lt;/i&gt; OS     not be as useful as a real computer too!" So they set out to build the worst     piece of useless filth they could imagine. One thing that sprung to mind     immediately was      &lt;blockquote&gt;I know! Let's make it so that to launch any application, the user has to       move the mouse over to the left of the screen, but not the top-left,       that's for the close-maximize-minimize buttons.     &lt;/blockquote&gt;But that was thinking too small. It took another act of     &lt;strike&gt;auto-lobotomy&lt;/strike&gt; brilliance to take it to the next level.      &lt;blockquote&gt;Oh, how about, when the user has opened an application, any indication of       other applications on the system or how to launch them disappears! Then,       in order to launch other applications, the user needs to go back over to       the "Dash" — which is &lt;i&gt;totally&lt;/i&gt; not a stupid name, concept,       or idea — and try to select something!     &lt;/blockquote&gt;The designers were proud of their progress, but frustrated that novice users     might still figure out how to launch applications not in the small list of     things included by default on the &lt;b&gt;DASH HOME DOCK METAPHOR     PANEL&lt;/b&gt;. Then came the final piece of brilliance:      &lt;blockquote&gt;Aha! How about instead of having an "Applications" menu which contains a       list of applications organized by their function — Graphics,       Internet, Sound &amp;amp; Video, etc. — we only have       &lt;b&gt;four&lt;/b&gt; applications, and if the user wants to launch       something else, they can start typing its name! No one will       &lt;b&gt;ever&lt;/b&gt; be able to get work done once we include that! We'll       finally be competitive with tablets in the "least amount of useful       functionality" race!     &lt;/blockquote&gt;Finally, they were satisfied. Nobody who had ever used a computer before     would be able to figure out this turd, and the designers could live their     life-long dream of turning something useful into a CES tech demo. Surely,     the highest aspiration of any piece of software is to look kind of novel     for a couple minutes when filmed over the shoulder of a PR representative at     a loud and crowded tech convention. In other words, you want this:      &lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-1qX5U91PkOQ/T0wmnnG_I-I/AAAAAAAAAMQ/EeZdfRqki3I/s1600/great.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="249" src="https://lh3.ggpht.com/-1qX5U91PkOQ/T0wmnnG_I-I/AAAAAAAAAMQ/EeZdfRqki3I/s320/great.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;Yeah. That's what people want.   &lt;/li&gt;
&lt;li&gt;     Drugs. &lt;b&gt;LOTS&lt;/b&gt; of drugs.   &lt;/li&gt;
&lt;/ol&gt;Now, armed with these tools, you can venture forth into the world and use your   computer like a computer, rather than an imitation magazine. If you want a   magazine you can read while you lean back on your postmodern sofa, go buy a   copy of &lt;i&gt;Clash&lt;/i&gt; magazine (it's pretty underground, you've probably   never heard of it). If you want to lean back and watch TV, then watch TV. If   you want to lean back and listen to music, get an iPod, or better yet, an   Android phone with a vast multitude of listening options. &lt;br /&gt;
But if you have any interest in &lt;b&gt;doing actual work&lt;/b&gt;, you get a   computer and pray to Turing that the Metaphor Brigade hasn't left the coffee   shop and ruined it yet. I suppose if your work entails filming a tech demo of   you performing the three tasks you can do with a hypothetical tablet that   nobody would pay (or even receive) money to acquire, then keeping up with the   latest fads might be important. For those of us who want to open up the   computer, start composing a document, and have characters appear on the screen   as buttons on the keyboard are pressed, we have been immensely harmed now that   "creative" people discovered they could ruin whole operating systems, not just   individual websites. &lt;br /&gt;
The one kernel of solace is that, because there are users of these   formerly-useful operating systems who posses the skills to fix these   monstrosities, solutions will continue to exist. And hopefully, once the   project leads sober up, all of the trash of the last year can safely be   discarded. &lt;br /&gt;
Anything is possible, I suppose.&lt;img src="http://feeds.feedburner.com/~r/haxney/~4/olhuY8XdyDo" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.haxney.org/feeds/7296075127036748439/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.haxney.org/2012/02/ongoing-saga-of-making-ubuntu-1110.html#comment-form" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7770370347473031286/posts/default/7296075127036748439?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7770370347473031286/posts/default/7296075127036748439?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/haxney/~3/olhuY8XdyDo/ongoing-saga-of-making-ubuntu-1110.html" title="The Ongoing Saga of Making Ubuntu 11.10 Usable" /><author><name>Daniel Hackney</name><uri>https://plus.google.com/114139496531318962673</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-wADb4DtR17g/AAAAAAAAAAI/AAAAAAAAAoM/q9V58qhyP4w/s512-c/photo.jpg" /></author><thr:total>3</thr:total><feedburner:origLink>http://www.haxney.org/2012/02/ongoing-saga-of-making-ubuntu-1110.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkMNRXg7eyp7ImA9WhJTEU4.&quot;"><id>tag:blogger.com,1999:blog-7770370347473031286.post-8190555292849356648</id><published>2012-02-15T23:46:00.001-05:00</published><updated>2012-06-19T16:41:34.603-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-06-19T16:41:34.603-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="projects" /><category scheme="http://www.blogger.com/atom/ns#" term="python" /><category scheme="http://www.blogger.com/atom/ns#" term="code" /><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><title>Set ordering in Python: why I didn't sleep last night</title><content type="html">&lt;p&gt;In yesterday's class of the &lt;a href="http://www.cs.brown.edu/courses/csci0530/"&gt;Python-infused&lt;/a&gt; Linear Algebra course I'm taking, a fellow student noted the strange ordering of items in a &lt;code&gt;set&lt;/code&gt; when printed. It seemed that the printed order of the set items always swapped the first two items, but left the rest unchanged. I don't know what sets he tried, but I was interested in the general behavior, and so began my quest through the Python source code...&lt;/p&gt;&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
&lt;h4&gt;BIG IMPORTANT WARNING!!!&lt;/h4&gt;&lt;blockquote&gt;&lt;p&gt;These are some interesting properties of the order of iterations over Python's &lt;code&gt;set&lt;/code&gt; objects. They are &lt;strong&gt;NOT&lt;/strong&gt; to be relied upon for the correctness of your program! There are a bunch of hardcoded, opaque magic numbers which determine the order, so it could easily change across micro version, platforms, or compilations with different options. &lt;strong&gt;Treat sets as having undefined ordering!&lt;/strong&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;All of this is looking at the tag "&lt;code&gt;v3.1.1&lt;/code&gt;" in the &lt;a href="http://hg.python.org/cpython/"&gt; &lt;code&gt;cpython&lt;/code&gt; &lt;/a&gt; repository on the &lt;a href="http://hg.python.org"&gt;Python repositories&lt;/a&gt; site. "3.1.1" is the version of &lt;code&gt;python3&lt;/code&gt; on the computers here, so I figured that would be the one to check, though I assume the set code hasn't changed that much. The root of that version is &lt;a href="http://hg.python.org/cpython/file/8b9c0f573ab2"&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Sets are defined in the source files &lt;code&gt;"&lt;a href="http://hg.python.org/cpython/file/8b9c0f573ab2/Include/setobject.h"&gt;Include/setobject.h&lt;/a&gt;"&lt;/code&gt; and &lt;code&gt;"&lt;a href="http://hg.python.org/cpython/file/8b9c0f573ab2/Objects/setobject.c"&gt;Objects/setobject.c&lt;/a&gt;"&lt;/code&gt; for the headers and implementation, respectively. The relevant part of sets is that their elements are stored in a hash table using &lt;a href="http://en.wikipedia.org/wiki/Open_addressing"&gt;open addressing&lt;/a&gt; for collision resolution. Python (version 3.1.1, anyway) uses the following algorithm for resolving collisions, in Python (with cheats):&lt;/p&gt;&lt;script type="text/javascript" src="https://gist.github.com/1841325.js?file=gistfile1.py"&gt;
&lt;/script&gt;  &lt;p&gt;&lt;code&gt;entry&lt;/code&gt; is actually a pointer (the whole function is in C); I'm fudging the specifics here a lot. &lt;code&gt;mask&lt;/code&gt; is &lt;code&gt;table.array_size() - 1&lt;/code&gt; where &lt;code&gt;table.array_size()&lt;/code&gt; is the size of the underlying C array. The essence is the updating of &lt;code&gt;index&lt;/code&gt;; it is intended to distribute keys all over the array, making collisions less likely. There are a bunch of trade-offs, and they are described in "&lt;a href="http://hg.python.org/cpython/file/8b9c0f573ab2/Objects/dictnotes.txt"&gt;dictnotes.txt&lt;/a&gt;" and "&lt;a href="http://hg.python.org/cpython/file/8b9c0f573ab2/Objects/dictobject.c"&gt;dictobject.c&lt;/a&gt;". One interesting fact is that basic integers hash to themselves (and are ANDed with &lt;code&gt;mask&lt;/code&gt; for indexing into the array).&lt;/p&gt;&lt;p&gt;The use of open addressing means it can get all objects simply by walking the table. Entries in the set are defined as:&lt;/p&gt;&lt;script type="text/javascript" src="https://gist.github.com/1841437.js?file=gistfile1.c"&gt;
&lt;/script&gt;  &lt;p&gt;The set object itself comprises an array of setentries and some additional fields, like the number of in-use entries and the size of the array.&lt;/p&gt;&lt;p&gt;Calling &lt;code&gt;list(o)&lt;/code&gt; converts a "sequence object" (there is an abstracted interface at the C level) by calling &lt;code&gt;PySequence_List&lt;/code&gt;, declared in &lt;code&gt;"&lt;a href="http://hg.python.org/cpython/file/8b9c0f573ab2/Include/abstract.h"&gt;Include/abstract.h&lt;/a&gt;"&lt;/code&gt; and implemented in &lt;code&gt;"&lt;a href="http://hg.python.org/cpython/file/8b9c0f573ab2/Objects/abstract.c"&gt;Objects/abstract.c&lt;/a&gt;"&lt;/code&gt;. &lt;code&gt;PySequence_List&lt;/code&gt; does some basic checks and calls &lt;code&gt;_PyList_Extend&lt;/code&gt;, in &lt;code&gt;"&lt;a href="http://hg.python.org/cpython/file/8b9c0f573ab2/Objects/listobject.c"&gt;Objects/listobject.c&lt;/a&gt;"&lt;/code&gt;, which creates a new list and calls &lt;code&gt;listextend(self, iter(o))&lt;/code&gt; for the real work. It then simply walks through the iterator, appending the items returned to itself, doubling its length if it runs out of space. So the ordering is determined by the iterator for sets.&lt;/p&gt;&lt;p&gt;The work is done in the &lt;code&gt;setiter_iternext()&lt;/code&gt; function, which walks through the backing array until it finds a non-NULL entry and returns that. So the order of objects from the result of &lt;code&gt;list(s)&lt;/code&gt; is determined by the order of elements in the table. That is determined by &lt;code&gt;PySet_Add&lt;/code&gt; which calls &lt;code&gt;set_add_key&lt;/code&gt; which uses &lt;code&gt;PyObject_Hash&lt;/code&gt; to get the hash of the object to add.&lt;/p&gt;&lt;p&gt;&lt;code&gt;PyObject_Hash&lt;/code&gt; looks into the object's vtable (Python doesn't call it that, it's stored in the object's &lt;code&gt;ob_type&lt;/code&gt; field) to find its &lt;code&gt;tp_hash&lt;/code&gt; function and calls that. &lt;code&gt;tp_hash&lt;/code&gt; returns a &lt;code&gt;long&lt;/code&gt;. Each object has its own hash function; this is what is used for a couple of common types: &lt;/p&gt;&lt;ul&gt;&lt;li&gt;     &lt;code&gt;double&lt;/code&gt;: uses the integer part of the float (with some extra   stuff)&lt;/li&gt;
&lt;li&gt;     &lt;code&gt;pointer&lt;/code&gt;: rotates the pointer right by 4 bits (since the lower   3-4 bits are likely to be zero)&lt;/li&gt;
&lt;li&gt;     &lt;code&gt;int&lt;/code&gt;: the absolute value of the int modulo the platform's     maximum &lt;code&gt;long&lt;/code&gt; value. This actually can get interesting, since Python     &lt;code&gt;long&lt;/code&gt;s are arbitrary precision. The hash is computed through some   additions, rotations, and fun stuff like that.&lt;/li&gt;
&lt;li&gt;     &lt;code&gt;tuple&lt;/code&gt;: the hashes of its objects, XORed together and multiplied     by a sequence of constants to mix up the value, and something having to do with   primes.&lt;/li&gt;
&lt;li&gt;   &lt;code&gt;string&lt;/code&gt;: XOR of bytes (not "characters"! Know your Unicode!).&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;  So the order items from &lt;code&gt;list(s)&lt;/code&gt; is "mostly" stable for sets containing the same objects. The exception is when objects with the same hash are inserted in different orders; because of open addressing, the order of insertion determines their place in the array. The following case &lt;strong&gt;should&lt;/strong&gt; hold true:&lt;/p&gt;&lt;script type="text/javascript" src="https://gist.github.com/1841760.js?file=gistfile1.py"&gt;&lt;/script&gt; &lt;p&gt;  So it is possible for sets with the same contents to have different orderings, but it requires a collision of &lt;code&gt;hash(a) % mask&lt;/code&gt;. Remember, (for ints) &lt;code&gt;hash(i) == i&lt;/code&gt; when &lt;code&gt;i&lt;/code&gt; is not an arbitrary-precision numeric. You can create a collision easily by exploiting knowledge of the initial size of the internal array. Rather cleverly, the set object includes an immediate array of &lt;code&gt;PySet_MINSIZE&lt;/code&gt; elements (defaulting to 8) within the structure itself. This means that if your set doesn't grow beyond 5 elements (the hard-coded load factor is 2/3), there is no extra memory allocated for the table. Given those two facts, all you need is &lt;code&gt;(a, b)&lt;/code&gt; such that &lt;code&gt;a &amp;amp; 7 == b &amp;amp; 7&lt;/code&gt;. How about &lt;code&gt;(0, 8)&lt;/code&gt;?&lt;/p&gt;&lt;p&gt;  You can then do:&lt;/p&gt;&lt;script type="text/javascript" src="https://gist.github.com/1841863.js?file=gistfile1.py"&gt;&lt;/script&gt;  &lt;p&gt;  I'm not sure why the order of the elements is reversed; this only happens for certain combinations:&lt;/p&gt;&lt;script type="text/javascript" src="https://gist.github.com/1841869.js?file=gistfile1.py"&gt;&lt;/script&gt;  &lt;p&gt;  I started investigating deeper into how Python fills its hash tables, but I decided to stop after a dozen hours, reading through Python's parser code, and trying to figure out pixel offsets to pass to PyCairo during visualization. My progress thus far is &lt;a href="https://github.com/haxney/set-investigate"&gt;here&lt;/a&gt;. I'm trying to get a visualization of exactly how the entries are being added, but porting Brandon Rhodes' dictionary code to work for sets is non-trivial. Also, getting the visualization to display in a Gtk window rather than writing to a file took some fiddling around with PyGtk and PyCairo.&lt;/p&gt;&lt;p&gt;  &lt;strong&gt;tl;dr&lt;/strong&gt;: the order of objects in a set when converted to a list (such as during display on the repl) is dependent on the hash of the object and the collision resolution strategy. The pattern found by the student in which the first two elements of the set were reversed was a coincidence, as the indexing function attempts to distribute keys uniformly over the table.&lt;/p&gt;&lt;p&gt;  I spent &lt;strong&gt;WAY&lt;/strong&gt; too much time on this. Interesting, though.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/haxney/~4/D9J9yu-zvIs" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.haxney.org/feeds/8190555292849356648/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.haxney.org/2012/02/set-ordering-in-python-why-i-didnt.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7770370347473031286/posts/default/8190555292849356648?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7770370347473031286/posts/default/8190555292849356648?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/haxney/~3/D9J9yu-zvIs/set-ordering-in-python-why-i-didnt.html" title="Set ordering in Python: why I didn't sleep last night" /><author><name>Daniel Hackney</name><uri>https://plus.google.com/114139496531318962673</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-wADb4DtR17g/AAAAAAAAAAI/AAAAAAAAAoM/q9V58qhyP4w/s512-c/photo.jpg" /></author><thr:total>0</thr:total><georss:featurename>217 Thayer St, Providence, RI 02906, USA</georss:featurename><georss:point>41.82755473872867 -71.40027523040771</georss:point><georss:box>41.82163873872867 -71.41014573040772 41.83347073872867 -71.39040473040771</georss:box><feedburner:origLink>http://www.haxney.org/2012/02/set-ordering-in-python-why-i-didnt.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkcFSXs4eSp7ImA9WhRQGE8.&quot;"><id>tag:blogger.com,1999:blog-7770370347473031286.post-3728655170917790413</id><published>2011-12-13T21:00:00.001-05:00</published><updated>2011-12-13T21:00:18.531-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-12-13T21:00:18.531-05:00</app:edited><title>What a functional desktop looks like</title><content type="html">As a followup to my first &lt;a href="http://www.haxney.org/2011/10/un-terrible-ize-ubuntu-1110.html"&gt;Un-Terrible-ize&lt;br /&gt;
Ubuntu 11.10&lt;/a&gt; post, I thought I'd show everyone what my computer looks like&lt;br /&gt;
after reverting the desktop to a working state.&lt;br /&gt;
&lt;br /&gt;
Here is what it looks like now:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-kV-S6royhK8/TufZMxU52PI/AAAAAAAAAFE/2we8do9zs68/s1600/working.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="480" src="http://3.bp.blogspot.com/-kV-S6royhK8/TufZMxU52PI/AAAAAAAAAFE/2we8do9zs68/s640/working.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
Nice, neat, with all of the things I want and none of the things I don't want. I&lt;br /&gt;
have a couple of customizations for Firefox (like the tabs on the side), and&lt;br /&gt;
along the top is the "System Monitor" applet, which displays (from left to&lt;br /&gt;
right) the current CPU usage, memory usage, network activity, swap space, load&lt;br /&gt;
average, and disk usage. That's undoubtedly overly geeky for many people, but I&lt;br /&gt;
find it quite useful.&lt;br /&gt;
&lt;br /&gt;
Now, for comparison, here is what the default Ubuntu 11.10 interface looks like:&lt;br /&gt;
&lt;br /&gt;
&lt;table align="center" cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-1JTlSKQlp98/TugCX7WgKuI/AAAAAAAAAFU/AyhKYC-a2Ow/s1600/unity.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="358" src="http://4.bp.blogspot.com/-1JTlSKQlp98/TugCX7WgKuI/AAAAAAAAAFU/AyhKYC-a2Ow/s640/unity.png" width="640" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;This is a direct screen shot. True story.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;br /&gt;
Later on, I may post a step-by-step description or even a script for getting&lt;br /&gt;
from the bottom image to the top.&lt;br /&gt;&lt;img src="http://feeds.feedburner.com/~r/haxney/~4/YpZmWo8xWb4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.haxney.org/feeds/3728655170917790413/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.haxney.org/2011/12/what-functional-desktop-looks-like.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7770370347473031286/posts/default/3728655170917790413?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7770370347473031286/posts/default/3728655170917790413?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/haxney/~3/YpZmWo8xWb4/what-functional-desktop-looks-like.html" title="What a functional desktop looks like" /><author><name>Daniel Hackney</name><uri>https://plus.google.com/114139496531318962673</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-wADb4DtR17g/AAAAAAAAAAI/AAAAAAAAAoM/q9V58qhyP4w/s512-c/photo.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/-kV-S6royhK8/TufZMxU52PI/AAAAAAAAAFE/2we8do9zs68/s72-c/working.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://www.haxney.org/2011/12/what-functional-desktop-looks-like.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DE4BQXszeyp7ImA9WhRQGEw.&quot;"><id>tag:blogger.com,1999:blog-7770370347473031286.post-7018654767675824727</id><published>2011-12-13T17:55:00.002-05:00</published><updated>2011-12-13T17:55:50.583-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-12-13T17:55:50.583-05:00</app:edited><title>Configuring Printers in Ubuntu 11.10</title><content type="html">Welcome back to my ongoing adventures in &lt;a href="http://www.haxney.org/2011/10/un-terrible-ize-ubuntu-1110.html"&gt;making&lt;br /&gt;
Ubuntu work&lt;/a&gt; once again. Today's episode features printing!&lt;br /&gt;
&lt;br /&gt;
So upon trying to print a document, I found that my printer hadn't been set up.&lt;br /&gt;
No problem! I guess I had forgotten to do so. So I jetted on over to the "System&lt;br /&gt;
Settings" application, which helpfully had a "Printers" button. "Why hello Mr.&lt;br /&gt;
Printers button," I said. "Let's go on a magical printer-configuring adventure,&lt;br /&gt;
just the two of us!" Clicking on Mr. Printers, I was greeted with the Nice™,&lt;br /&gt;
Shiny™, Sexy™ Interface below:&lt;br /&gt;
&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/--ByLQQu_iN4/TufKgpyTZRI/AAAAAAAAAEc/smcvt3LuWVo/s1600/Screenshot+at+2011-12-13+16%253A57%253A52.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="180" src="http://2.bp.blogspot.com/--ByLQQu_iN4/TufKgpyTZRI/AAAAAAAAAEc/smcvt3LuWVo/s320/Screenshot+at+2011-12-13+16%253A57%253A52.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
Since my objective was to add a new printer to Mr. Printers' Magic List™, I&lt;br /&gt;
thought I'd click the "+" button.&lt;br /&gt;
&lt;br /&gt;
"Not so fast!" Mr. Printers said gleefully. "That button is grayed out, so&lt;br /&gt;
clicking on it does nothing!" I should confess that he didn't actually say this,&lt;br /&gt;
since clicking the grayed-out button did exactly nothing, but I like to think&lt;br /&gt;
that this is what he meant, in his silence.&lt;br /&gt;
&lt;br /&gt;
Despondent, I searched for a clue. My eye caught sight of the "Unlock" button in&lt;br /&gt;
the upper-right corner of Mr. Printers' window:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-c5exv-aD-oU/TufNkf6RSWI/AAAAAAAAAEk/fDlTlyoHAwU/s1600/Screenshot+at+2011-12-13+16%253A57%253A52.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="180" src="http://2.bp.blogspot.com/-c5exv-aD-oU/TufNkf6RSWI/AAAAAAAAAEk/fDlTlyoHAwU/s320/Screenshot+at+2011-12-13+16%253A57%253A52.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
"Aha!" I exclaimed with joy, "I bet this will unlock the secrets of the&lt;br /&gt;
printer!" I clicked on the button, entered my password to confirm that yes, I&lt;br /&gt;
did want to modify system settings, and lo and behold, the "+" button was no&lt;br /&gt;
longer grayed out! Being the masterful designers they are, the team responsible&lt;br /&gt;
for the "+" button saw fit to make the difference between "stubborn, indignant&lt;br /&gt;
Mr. Printers" and "helpful, charitable Mr. Printers" as clear as day. Just take&lt;br /&gt;
a look!&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-XfaEuV1Nv6o/TufUNeUZPrI/AAAAAAAAAEs/6UK5ig9vVjc/s1600/together.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://4.bp.blogspot.com/-XfaEuV1Nv6o/TufUNeUZPrI/AAAAAAAAAEs/6UK5ig9vVjc/s320/together.png" width="198" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
What could be clearer?!&lt;br /&gt;
&lt;br /&gt;
After that, I clicked on the now-enabled "+" button which whisked me away to&lt;br /&gt;
this lovely dialog:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-Qvd5y2ravY0/TufU8OB4tBI/AAAAAAAAAE0/HbUKmPeBI0c/s1600/add.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="236" src="http://2.bp.blogspot.com/-Qvd5y2ravY0/TufU8OB4tBI/AAAAAAAAAE0/HbUKmPeBI0c/s320/add.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
Now, I should clarify, in older versions of Ubuntu, the "Add Printer" dialog&lt;br /&gt;
would automatically detect any printers on the network, allow you to connect&lt;br /&gt;
with them, and figure out which driver to use, all without needing to wade&lt;br /&gt;
through lists of devices. Now, with Mark Shuttleworth's Amazing&lt;br /&gt;
Intuit-Interface™, that pesky problem of things working has finally been solved!&lt;br /&gt;
&lt;br /&gt;
So after a bit of Googling, I found out that you could use the old, Actually&lt;br /&gt;
Working™ printer-adding interface by opening a terminal (yes, yes, I know) and&lt;br /&gt;
running the program &lt;code&gt;system-config-printer&lt;/code&gt;. That opens this old&lt;br /&gt;
friend:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-sT9Volr3Gqo/TufWtpls36I/AAAAAAAAAE8/_PJKLKCwpNc/s1600/working.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="189" src="http://1.bp.blogspot.com/-sT9Volr3Gqo/TufWtpls36I/AAAAAAAAAE8/_PJKLKCwpNc/s320/working.png" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
Whose "Add" button actually works!&lt;br /&gt;
&lt;br /&gt;
So thank you, Mark Shuttleworth, for once again taking something that worked and&lt;br /&gt;
turning it into something that doesn't work. This clearly is progress.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;TL;DR&lt;/b&gt; If you want to add a printer, skip the "Printers" option&lt;br /&gt;
in System Settings and run &lt;code&gt;system-config-printer&lt;/code&gt; instead.&lt;img src="http://feeds.feedburner.com/~r/haxney/~4/rIn-Y4NykIw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.haxney.org/feeds/7018654767675824727/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.haxney.org/2011/12/configuring-printers-in-ubuntu-1110.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7770370347473031286/posts/default/7018654767675824727?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7770370347473031286/posts/default/7018654767675824727?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/haxney/~3/rIn-Y4NykIw/configuring-printers-in-ubuntu-1110.html" title="Configuring Printers in Ubuntu 11.10" /><author><name>Daniel Hackney</name><uri>https://plus.google.com/114139496531318962673</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-wADb4DtR17g/AAAAAAAAAAI/AAAAAAAAAoM/q9V58qhyP4w/s512-c/photo.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/--ByLQQu_iN4/TufKgpyTZRI/AAAAAAAAAEc/smcvt3LuWVo/s72-c/Screenshot+at+2011-12-13+16%253A57%253A52.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://www.haxney.org/2011/12/configuring-printers-in-ubuntu-1110.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkMFQnw4eyp7ImA9WhdaFE4.&quot;"><id>tag:blogger.com,1999:blog-7770370347473031286.post-6058877871310265071</id><published>2011-10-24T01:33:00.000-04:00</published><updated>2011-10-24T01:33:33.233-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-10-24T01:33:33.233-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="worst idea ever" /><title>Un-Terrible-ize Ubuntu 11.10</title><content type="html">Oh my god. After years of being a great, easy-to-use Linux distribution, Ubuntu finally has failed me and may need to be dumped. I just upgraded to 11.10 (Oneiric Ocelot) and they have made it more difficult than before to return to a not-terrible window manager. I think the idea behind Ubuntu's new "Unity" interface are cute, but is just god-awful for people who want to use their computer for things and don't like desperately trying to hunt them down. What was wrong with an "applications" menu that had an "Office" tab under it with office-related applications? Now, you open the side panel overlay bar thing and it takes up the whole screen but presents you with almost exactly zero useful information. It has something like 3 applications along the top and then says "fuck you, go figure it out" if you want anything more. Alt-F2 doesn't work to open a launcher to launch an application. Alt + middle-click doesn't resize windows any more. Just getting out of my damn way and letting me use the computer like I have for years doesn't even close to work.&lt;br /&gt;
&lt;br /&gt;
GNOME 2 was just fine. Why did you have to take something which worked, in a non-terrible fashion, and remove all of the useful, discoverable, productive parts of it? I've spent a couple hours at this point trying to get back to the level of non-uselessness I had with Ubuntu 11.04, which was not useless. I even tried installing GNOME 3 in the hope that it would have a "stop doing stupid bullshit" mode, but it only kind of does. I've gotten close, but the "system" menu is AWOL, and I can't figure out how to get it back. It doesn't seem to want to let you customize the theme at all or even have something as simple as focus-follows-mouse. Yes, I've opened &lt;code&gt;gconf-editor&lt;/code&gt; and set &lt;code&gt;/apps/metacity/general/focus_mode&lt;/code&gt; to &lt;code&gt;mouse&lt;/code&gt;, which seems to be the closest thing to focus-follows-mouse available, but it doesn't do it.&lt;br /&gt;
&lt;br /&gt;
I'll post what information I've found to get it to the minimally-crappy state it's in now, but I'm still searching for how to de-terrible-ize it further. Alternatively, I might just dump Ubuntu altogether until it gets some sense beaten into it. I hear &lt;a href="http://http://www.linuxmint.com/"&gt;Linux Mint&lt;/a&gt; is supposed to have remained safe from the "enshittening" of Linux user interfaces of late. Also, I could try Xubuntu, though I've never really been a fan of XFCE. It's a heck of a lot better than Unity or GNOME 3.&lt;br /&gt;
&lt;br /&gt;
No, nevermind. Not using XFCE.&lt;br /&gt;
&lt;br /&gt;
Okay, after a few more hours of wasted time, I'm going to bite the bullet and back up all of my documents, wipe 11.10 off of my computer, and go back to 11.04, aka "the last sane version of Ubuntu". It really sucks because I used to recommend Ubuntu to my relatively non-technical friends, but with the crap they're pulling now, there's no way I'd let their first Linux experience be with this trash. Sad day.&lt;img src="http://feeds.feedburner.com/~r/haxney/~4/hRixrA8MBXg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.haxney.org/feeds/6058877871310265071/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.haxney.org/2011/10/un-terrible-ize-ubuntu-1110.html#comment-form" title="12 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7770370347473031286/posts/default/6058877871310265071?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7770370347473031286/posts/default/6058877871310265071?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/haxney/~3/hRixrA8MBXg/un-terrible-ize-ubuntu-1110.html" title="Un-Terrible-ize Ubuntu 11.10" /><author><name>haxney</name><uri>http://www.blogger.com/profile/02301593085374030863</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>12</thr:total><feedburner:origLink>http://www.haxney.org/2011/10/un-terrible-ize-ubuntu-1110.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEEHRnYyfyp7ImA9WhdbGUo.&quot;"><id>tag:blogger.com,1999:blog-7770370347473031286.post-887143604803534288</id><published>2011-10-18T17:17:00.000-04:00</published><updated>2011-10-18T17:17:17.897-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-10-18T17:17:17.897-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="blog" /><category scheme="http://www.blogger.com/atom/ns#" term="settings" /><category scheme="http://www.blogger.com/atom/ns#" term="boring" /><title>Changing up the style</title><content type="html">You may have noticed a change in the style of the site. That's because I changed the style of the site.&lt;br /&gt;
&lt;br /&gt;
Okay, seriously, I switched to the new Blogger interface/template, so things look a bit different. I tried fiddling around with some things, and hopefully nothing broke. To all of you massive numbers of readers of this blog, let me know if anything went wrong in the upgrade.&lt;img src="http://feeds.feedburner.com/~r/haxney/~4/WZr9lCq-71k" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.haxney.org/feeds/887143604803534288/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.haxney.org/2011/10/changing-up-style.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7770370347473031286/posts/default/887143604803534288?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7770370347473031286/posts/default/887143604803534288?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/haxney/~3/WZr9lCq-71k/changing-up-style.html" title="Changing up the style" /><author><name>Daniel Hackney</name><uri>https://plus.google.com/114139496531318962673</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-wADb4DtR17g/AAAAAAAAAAI/AAAAAAAAAoM/q9V58qhyP4w/s512-c/photo.jpg" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.haxney.org/2011/10/changing-up-style.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C08NQXs9fip7ImA9WhdQGUU.&quot;"><id>tag:blogger.com,1999:blog-7770370347473031286.post-8885122031364127402</id><published>2011-08-21T22:18:00.000-04:00</published><updated>2011-08-21T22:58:10.566-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-08-21T22:58:10.566-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="ruby" /><category scheme="http://www.blogger.com/atom/ns#" term="rendering" /><category scheme="http://www.blogger.com/atom/ns#" term="rails" /><category scheme="http://www.blogger.com/atom/ns#" term="code" /><category scheme="http://www.blogger.com/atom/ns#" term="json" /><title>Genericizing Rails view templates</title><content type="html">In keeping with my previous post, I have put together a way of greatly reducing the redundant code in Rails views. On the HTML side, this really only applies to the simple case of rendering the default REST views provided by Rails' scaffolding mechanism.&lt;br /&gt;
&lt;br /&gt;
Rather than have an &lt;code&gt;index.html.haml&lt;/code&gt; (or &lt;code&gt;erb&lt;/code&gt; if you're a bad person ;) for every model you have, why not consolidate all of those into a single template? They all do the same thing anyway: render a table of objects along with a few actions. Using the wonderful &lt;a
href="https://github.com/codez/render_inheritable"&gt;&lt;code&gt;render_inheritable&lt;/code&gt;&lt;/a&gt; gem, you can define a single &lt;code&gt;index.html.x&lt;/code&gt; file in a central location (such as &lt;code&gt;app/views/application&lt;/code&gt;) and have all of the customization occur at runtime.&lt;a name='more'&gt;&lt;/a&gt; Thanks to &lt;code&gt;render_inheritable&lt;/code&gt;, the 4 index files for my 4 models can be reduced to this:&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/1161502.js?file=index.html.haml"&gt;&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
You'll need to define a &lt;code&gt;entry_class&lt;/code&gt; method in each of your controllers which returns the model's class. So in the &lt;code&gt;UsersController&lt;/code&gt; you would have:&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/1161502.js?file=users_controller.rb"&gt;&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
The same applies to the &lt;code&gt;_form.html.x&lt;/code&gt; file. Using the wonderful &lt;a
href="https://github.com/justinfrench/formtastic"&gt;&lt;code&gt;formtastic&lt;/code&gt;&lt;/a&gt; gem, creating a form which works for all of the models is as simple as this:&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/1161502.js?file=_form.html.haml"&gt;&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
These are all pretty trivial and contrived; in any real application you wouldn't reuse the exact same view for all of your models. Where it becomes more useful is when crafting API responses, which tend to have more regular formats. Using the great &lt;a href="https://github.com/nesquena/rabl"&gt;&lt;code&gt;rabl&lt;/code&gt;&lt;/a&gt; gem, you can create view templates for JSON responses like you would for HTML responses. Instead of mucking about with &lt;code&gt;to_json&lt;/code&gt; in your models or controllers, define the format of responses in a view, where it belongs.&lt;br /&gt;
&lt;br /&gt;
Used with &lt;code&gt;render_inheritable&lt;/code&gt;, you can do some truly awesome things with your JSON (or XML) output. To create an index template which returns a per-model customizable collection of objects, simply create a file at e.g. &lt;code&gt;app/views/application/index.json.rabl&lt;/code&gt; with the following contents:&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/1161502.js?file=index.json.rabl"&gt;&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
You'll need to define a function called &lt;code&gt;entry_views_folder_path&lt;/code&gt; in your &lt;code&gt;ApplicationController&lt;/code&gt; which returns e.g. &lt;code&gt;users&lt;/code&gt; for responses concerning &lt;code&gt;User&lt;/code&gt; objects endpoint or &lt;code&gt;groups&lt;/code&gt; for responses with &lt;code&gt;Group&lt;/code&gt; objects.&lt;br /&gt;
&lt;br /&gt;
Doesn't look like much, but mix that together with &lt;code&gt;base.json.rabl&lt;/code&gt; files for each one of your models, such as:&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/1161502.js?file=base.json.rabl"&gt;&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
you now have a set of templates which render a collection of models, specialized for each class. That's pretty cool if you ask me.&lt;br /&gt;
&lt;br /&gt;
Stay tuned for a way to render these customized API templates when errors are encountered, while still preserving the original error codes. It took me hours of digging through the Rails source to figure out.&lt;img src="http://feeds.feedburner.com/~r/haxney/~4/gpPLOnb3PQI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.haxney.org/feeds/8885122031364127402/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.haxney.org/2011/08/genericizing-rails-view-templates.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7770370347473031286/posts/default/8885122031364127402?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7770370347473031286/posts/default/8885122031364127402?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/haxney/~3/gpPLOnb3PQI/genericizing-rails-view-templates.html" title="Genericizing Rails view templates" /><author><name>Daniel Hackney</name><uri>https://plus.google.com/114139496531318962673</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-wADb4DtR17g/AAAAAAAAAAI/AAAAAAAAAoM/q9V58qhyP4w/s512-c/photo.jpg" /></author><thr:total>0</thr:total><georss:featurename>382-394 Eddy St, Providence, RI 02903, USA</georss:featurename><georss:point>41.81712886667111 -71.4065408706665</georss:point><georss:box>41.814170366671114 -71.4114763706665 41.82008736667111 -71.4016053706665</georss:box><feedburner:origLink>http://www.haxney.org/2011/08/genericizing-rails-view-templates.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C08BQHsycCp7ImA9WhdQGUU.&quot;"><id>tag:blogger.com,1999:blog-7770370347473031286.post-5451979296231006953</id><published>2011-08-21T21:25:00.002-04:00</published><updated>2011-08-21T22:57:31.598-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-08-21T22:57:31.598-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><category scheme="http://www.blogger.com/atom/ns#" term="android" /><category scheme="http://www.blogger.com/atom/ns#" term="scala" /><title>Scala on Android with Eclipse</title><content type="html">Yes, I'm back from the dead. I've been busy starting a &lt;a href="http://getrenown.com"&gt;company&lt;/a&gt; of late and have been pretty much full speed ahead on that, leaving less (read: none) time for blogging.&lt;br /&gt;
&lt;br /&gt;
Anyway, on with the main event: a working setup for developing Android applications in &lt;a href="http://www.scala-lang.org/"&gt;Scala&lt;/a&gt;. I spent about 3-4 days total trying to get this setup working, using various different schemes such as the &lt;a href="https://code.google.com/p/treeshaker/"&gt;Treeshaker&lt;/a&gt; plugin for Eclipse, the &lt;a href="https://code.google.com/p/maven-android-plugin"&gt;Maven Android plugin&lt;/a&gt; and others. After hours and hours of fiddling, I finally found a solution that works: a custom &lt;a href="https://code.google.com/p/simple-build-tool"&gt;SBT&lt;/a&gt; setup with the &lt;a href="https://github.com/jberkel/android-plugin"&gt;SBT Android&lt;/a&gt; plugin. The key is to avoid building the Android app in Eclipse itself, but to use SBT for the heavy lifting.&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Eclipse seems to have some very non-deterministic behavior when building applications, especially Android applications. When you add Scala and Treeshaker into the mix, the whole thing falls apart. Furthermore, the build process is very opaque, so it's hard to figure out what is even going wrong, let alone to try to fix it. A build which was fine before might suddenly stop working, raising some exception or simply pegging the processor and making Eclipse totally unresponsive. There doesn't seem to be any pattern to the madness, so it's impossible to fix.&lt;br /&gt;
&lt;br /&gt;
Anyway, as I mentioned, SBT with the Android plugin works beautifully for building apps, but as much as I love Emacs, it is easier to work with Scala in an environment that gives you clear and immediate feedback about type failures and requirements. On the downside, in order to do all of this wonderfulness along with the Android helpers, Eclipse expects a very specific directory layout, and will complain if it does not exist. SBT, by default, uses a completely wacky layout, with the Android manifest files (usually at the root of the project) in &lt;code&gt;src/main/&lt;/code&gt;. This means that the actual source code files are in &lt;code&gt;src/main/src/main/java/com/example/...&lt;/code&gt;. For a single project without references to other projects, this is unnecessarily complicated and destroys the tiny brain of Eclipse. So the solution is to change SBT's layout to something sane.&lt;br /&gt;
&lt;br /&gt;
Note: I'm using SBT 0.7.x since the SBT Android plugin hasn't yet been ported to 0.10.x&lt;br /&gt;
&lt;br /&gt;
First of all, you need to declare the plugins you will be using (for now just the SBT Android plugin) in &lt;code&gt;project/plugins/plugins.scala&lt;/code&gt;. The actual filename doesn't matter, as long as it is in the &lt;code&gt;project/plugins&lt;/code&gt; folder. The &lt;code&gt;plugins.scala&lt;/code&gt; looks like this:&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/1161421.js?file=plugins.scala"&gt;&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
Standard fare for SBT plugins.&lt;br /&gt;
&lt;br /&gt;
Next is the SBT project file. This is where the magic happens, though there isn't really that much magic to it. It simply changes some paths so that SBT looks in the correct place. Here's the file:&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/1161421.js?file=project.scala"&gt;&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
The keys are the five lines in the middle setting the path info. The &lt;code&gt;androidManifestPath&lt;/code&gt; assignment causes SBT to look for &lt;code&gt;AndroidManifest.xml&lt;/code&gt; in the project root, as do &lt;code&gt;mainResPath&lt;/code&gt; and &lt;code&gt;mainAssetsPath&lt;/code&gt;. Setting the scala and java source paths to &lt;code&gt;src&lt;/code&gt; means that SBT will look in that folder instead of the redundantly redundant &lt;code&gt;src/main/src&lt;/code&gt; directory. Finally, overriding &lt;code&gt;aaptGenerateTask&lt;/code&gt; simply makes &lt;code&gt;aapt&lt;/code&gt; write the generated resource files (&lt;code&gt;R.java&lt;/code&gt; and friends) to the &lt;code&gt;gen&lt;/code&gt; folder, as the Android Eclipse plugin expects.&lt;br /&gt;
&lt;br /&gt;
With the hard stuff out of the way, you "simply" need to configure Eclipse to use the appropriate builders and classpaths, included in the &lt;code&gt;.project&lt;/code&gt; and &lt;code&gt;.classpath&lt;/code&gt; files, respectively. Here they are:&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;.project&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/1161421.js?file=.project"&gt;&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
and &lt;code&gt;.classpath&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;script src="https://gist.github.com/1161421.js?file=.classpath"&gt;&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
Obviously, since the config files include the Scala libraries and builder, you'll need to install the &lt;a href="http://www.scala-ide.org/"&gt;Scala Eclipse IDE&lt;/a&gt;. With all of this in place, you should be able to issue a simple &lt;code&gt;sbt start-emulator&lt;/code&gt; to build, Proguard, package, deploy and start your application.&lt;br /&gt;
&lt;br /&gt;
Hopefully this post will save you from the pain I endured of trying to get Scala working on the one hand, and the thought of having to use Java on the other.&lt;img src="http://feeds.feedburner.com/~r/haxney/~4/I1zaQ5keEOI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.haxney.org/feeds/5451979296231006953/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.haxney.org/2011/08/scala-on-android-with-eclipse.html#comment-form" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7770370347473031286/posts/default/5451979296231006953?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7770370347473031286/posts/default/5451979296231006953?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/haxney/~3/I1zaQ5keEOI/scala-on-android-with-eclipse.html" title="Scala on Android with Eclipse" /><author><name>Daniel Hackney</name><uri>https://plus.google.com/114139496531318962673</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-wADb4DtR17g/AAAAAAAAAAI/AAAAAAAAAoM/q9V58qhyP4w/s512-c/photo.jpg" /></author><thr:total>2</thr:total><feedburner:origLink>http://www.haxney.org/2011/08/scala-on-android-with-eclipse.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUYHQnkyfip7ImA9Wx9UFEg.&quot;"><id>tag:blogger.com,1999:blog-7770370347473031286.post-572806442087266336</id><published>2011-02-11T15:45:00.000-05:00</published><updated>2011-02-11T15:45:33.796-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-02-11T15:45:33.796-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="mods" /><category scheme="http://www.blogger.com/atom/ns#" term="programming" /><category scheme="http://www.blogger.com/atom/ns#" term="minecraft" /><title>MineCabinet - a database-backed chunk manager for Minecraft</title><content type="html">As I alluded to in my &lt;a href="http://www.haxney.org/2011/02/size-of-minecraft-chunk-files.html"&gt;last post&lt;/a&gt;, I have been working on modding &lt;a href="http://www.minecraft.net"&gt;Minecraft&lt;/a&gt; to use the excellent &lt;a href="http://1978th.net/tokyocabinet"&gt;Tokyo Cabinet&lt;/a&gt; database to store the chunk data. I have finally gotten it to the point where it is ready to be released to the masses.&lt;br /&gt;
&lt;a name='more'&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Here is a &lt;a href="http://db.tt/HOq9W9a"&gt;link&lt;/a&gt; to the zip file. It contains installation instructions in the README.txt. All of the basic installation information is contained there, so if you're really interested in how it works, hit that download link! :)&lt;br /&gt;
&lt;br /&gt;
Basically, I replaced Minecraft's current ChunkLoader implementation with a new one based on Tokyo Cabinet. Rather than saving each chunk in a separate file, MineCabinet stores everything in a single Tokyo Cabinet database, which reduces the number of files for a 60MB world from 17,000 to 1. It also boosts performance by roughly a factor of 4, according to my basic profiling results. here are a few runs from JVisualVM for vanilla Minecraft, McRegion, and MineCabinet. There are two sets of results, one for creating a new world and running around for a few minutes and then saving and exiting the world, and another for reloading that same world.&lt;br /&gt;
&lt;br /&gt;
First, the profiling for initial world creation:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-tTEOYpZyPPE/TVWSfXD-rCI/AAAAAAAAABs/Ap3PeB7_avE/s1600/mc-std-init.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="201" width="400" src="http://3.bp.blogspot.com/-tTEOYpZyPPE/TVWSfXD-rCI/AAAAAAAAABs/Ap3PeB7_avE/s400/mc-std-init.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;center&gt;Vanilla Minecraft - initializing new world. 1030 calls to &lt;code&gt;oj.a(dn, ib)&lt;/code&gt; (aka &lt;code&gt;saveChunk&lt;/code&gt;) in 4522 ms or 4.4 ms/call&lt;/center&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-wQyyl4bHcFQ/TVWSp7ck37I/AAAAAAAAAB0/HvucmIb7h3k/s1600/mc-region-init.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="201" width="400" src="http://3.bp.blogspot.com/-wQyyl4bHcFQ/TVWSp7ck37I/AAAAAAAAAB0/HvucmIb7h3k/s400/mc-region-init.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;center&gt;McRegion - initializing new world. 1076 calls to &lt;code&gt;oj.a(dn, ib)&lt;/code&gt; in 4060 ms or 3.8 ms/call&lt;/center&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-AxUrpXQxvVw/TVWSx8sEtDI/AAAAAAAAAB8/63UNdrtJJBY/s1600/mc-tc-init.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="201" width="400" src="http://3.bp.blogspot.com/-AxUrpXQxvVw/TVWSx8sEtDI/AAAAAAAAAB8/63UNdrtJJBY/s400/mc-tc-init.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;center&gt;MineCabinet - Initializing new world. 996 calls to &lt;code&gt;saveChunk&lt;/code&gt; in 728 ms or 0.73 ms/call&lt;/center&gt;&lt;br /&gt;
&lt;br /&gt;
And for loading that world back from disk:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-IS6XNcBzKO4/TVWUl1QCReI/AAAAAAAAACE/4I8TpDrABLc/s1600/mc-std-reload.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="201" width="400" src="http://1.bp.blogspot.com/-IS6XNcBzKO4/TVWUl1QCReI/AAAAAAAAACE/4I8TpDrABLc/s400/mc-std-reload.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;center&gt;Vanilla Minecraft - loading existing world. 570 calls to &lt;code&gt;oj.a(dn, ib)&lt;/code&gt; in 2605 ms or 4.5 ms/call&lt;br /&gt;
&lt;br /&gt;
566 calls to &lt;code&gt;oj.a(dn, int, int)&lt;/code&gt; (aka &lt;code&gt;loadChunk&lt;/code&gt;) in 868 ms or 1.5 ms/call&lt;/center&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-_iFSwEya1rE/TVWUqBraLEI/AAAAAAAAACM/0X-WWjP1WRE/s1600/mc-region-reload.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="201" width="400" src="http://2.bp.blogspot.com/-_iFSwEya1rE/TVWUqBraLEI/AAAAAAAAACM/0X-WWjP1WRE/s400/mc-region-reload.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;center&gt;McRegion - loading existing world. 590 calls to &lt;code&gt;oj.a(dn, ib)&lt;/code&gt; in 2424 ms or 4.1 ms/call&lt;br /&gt;
&lt;br /&gt;
581 calls to &lt;code&gt;oj.a(dn, int, int)&lt;/code&gt; in 528 ms or 0.91 ms/call&lt;/center&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-TlrtCDPte50/TVWUum4SOjI/AAAAAAAAACU/N0l-ZmCFHwE/s1600/mc-tc-reload.png" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="201" width="400" src="http://4.bp.blogspot.com/-TlrtCDPte50/TVWUum4SOjI/AAAAAAAAACU/N0l-ZmCFHwE/s400/mc-tc-reload.png" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;center&gt;MineCabinet - loading existing world. 562 calls to &lt;code&gt;saveChunk()&lt;/code&gt; in 259 ms or 0.46 ms/call&lt;br /&gt;
&lt;br /&gt;
556 calls to &lt;code&gt;loadChunk()&lt;/code&gt;  in 643 ms or 1.2 ms/call&lt;/center&gt;&lt;br /&gt;
&lt;br /&gt;
So as you can see, a very large speedup. Additionally, Tokyo Cabinet has a number of tuning parameters which could affect performance, including switching from using a B+ tree-based database to a hashtable-based database. The hashtable apparently has higher space overhead, but can be more efficient in some circumstances. I didn't really investigate the impact of various tuning parameters on performance, so there is some potential for even more speedups.&lt;br /&gt;
&lt;br /&gt;
One thing to note, though, is that MineCabinet spends a large amount in &lt;code&gt;saveExtraData()&lt;/code&gt;. This is because I put a call to &lt;code&gt;db.sync()&lt;/code&gt; in there (it was a noop before). It gets called when a world is unloaded, so it seemed like a good time to sync. Although this is a large amount of time, it is only done when switching worlds, so five seconds here isn't as noticeable as a lot of little pauses throughout the game. A more intelligent mod could force a sync (in a dedicated thread) periodically, say after a (configurable?) number of in-game ticks.&lt;br /&gt;
&lt;br /&gt;
Another nice thing about using Tokyo Cabinet is that it obviates the need for managing the "session.lock" file in each world directory. In vanilla Minecraft, this file is checked (twice) for each chunk save to make sure that the directory isn't being written by another Minecraft process. This adds more (though not much) overhead to each chunk save, and can be avoided entirely with Tokyo Cabinet. When opening a database, TC takes a file lock on the file it's opening, so any other process (reader or writer) is blocked from opening that same file. Since a database is opened for the entire session of a world, no other process can modify or read the database while it is in use.&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;Current limitations&lt;/h2&gt;&lt;br /&gt;
All is not perfect, however. Currently, I only provide a native library for 32-bit Linux, since that is the only build environment I have access to. Building Tokyo Cabinet (and the Java bindings) for Mac OSX shouldn't be hard, and it &lt;a href="https://github.com/lancepantz/tokyocabinet"&gt;looks like&lt;/a&gt; someone already has a build made.&lt;br /&gt;
&lt;br /&gt;
Windows is harder, since Tokyo Cabinet does not officially support it. It may be possible to build with MinGW, though I've never used it. Tokyo Cabinet doesn't have many dependencies (zlib, bzip2, and pthreads), so it may be possible to get it to build and run on Windows. I'll have to see.&lt;br /&gt;
&lt;br /&gt;
Another possibility is to use the newer and improved-er &lt;a href="http://fallabs.com/kyotocabinet"&gt;Kyoto Cabinet&lt;/a&gt;, the successor to Tokyo Cabinet which includes (among other things) official binary packages for Windows. The downside is that unlike Tokyo Cabinet, Kyoto Cabinet is licensed under the GPLv3, making it ineligible for use in Minecraft without a commercial license. Mojang may decide that it's worth it to go for the commercial license, but I didn't want to assume that, plus, I wanted to remain closer to the side of legal distribution (Minecraft mods are always a gray area).&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;Closing remarks&lt;/h2&gt;&lt;br /&gt;
My ultimate hope is that MineCabinet (or something similar using an efficient DB) is included in the main Minecraft client, since I think using an embedded DB would provide a number of advantages over even a well-done custom format (such as McRegion). One of the biggest benefits is simply letting someone else deal with the tricky problem of managing persistence and concurrent access. My opinion is that if you can make your problem someone else's problem, go for it, especially when they specialize in solving that problem. Also, databases like Tokyo/Kyoto Cabinet have effective methods for dealing with both intra- and inter-process concurrent access, which is a notoriously difficult problem to get right.&lt;br /&gt;
&lt;br /&gt;
There's plenty more I could say, but this post is long enough as it is. Please feel free to give feedback and suggestions, especially in the form of code ;)!&lt;br /&gt;
&lt;br /&gt;
P.S. A big thank you to Scaevolus, author of &lt;a href="http://www.minecraftforum.net/viewtopic.php?f=25&amp;t=120160"&gt;McRegion&lt;/a&gt; and Minecraft modding expert. Without his help, I never would have been able to navigate the Minecraft sources and make the modifications to put the whole thing together.&lt;img src="http://feeds.feedburner.com/~r/haxney/~4/9LGKrw6Nrg0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.haxney.org/feeds/572806442087266336/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.haxney.org/2011/02/minecabinet-database-backed-chunk.html#comment-form" title="8 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/7770370347473031286/posts/default/572806442087266336?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/7770370347473031286/posts/default/572806442087266336?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/haxney/~3/9LGKrw6Nrg0/minecabinet-database-backed-chunk.html" title="MineCabinet - a database-backed chunk manager for Minecraft" /><author><name>Daniel Hackney</name><uri>https://plus.google.com/114139496531318962673</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="32" height="32" src="//lh4.googleusercontent.com/-wADb4DtR17g/AAAAAAAAAAI/AAAAAAAAAoM/q9V58qhyP4w/s512-c/photo.jpg" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/-tTEOYpZyPPE/TVWSfXD-rCI/AAAAAAAAABs/Ap3PeB7_avE/s72-c/mc-std-init.png" height="72" width="72" /><thr:total>8</thr:total><feedburner:origLink>http://www.haxney.org/2011/02/minecabinet-database-backed-chunk.html</feedburner:origLink></entry></feed>
