<?xml version="1.0" encoding="UTF-8"?>
<feed xml:lang="en-US" xmlns="http://www.w3.org/2005/Atom">
  <title>Infloop - Home</title>
  <id>tag:blog.infloop.com,2008:mephisto/</id>
  <generator version="0.7.3" uri="http://mephistoblog.com">Mephisto Noh-Varr</generator>
  <link href="http://blog.infloop.com/feed/atom.xml" rel="self" type="application/atom+xml"/>
  <link href="http://blog.infloop.com/" rel="alternate" type="text/html"/>
  <updated>2008-06-15T00:32:10Z</updated>
  <entry xml:base="http://blog.infloop.com/">
    <author>
      <name>ahobson</name>
    </author>
    <id>tag:blog.infloop.com,2008-06-15:382</id>
    <published>2008-06-15T00:31:00Z</published>
    <updated>2008-06-15T00:32:10Z</updated>
    <category term="bbc us"/>
    <link href="http://blog.infloop.com/2008/6/15/united-states-of-advertising" rel="alternate" type="text/html"/>
    <title>United States of Advertising</title>
<content type="html">
            &lt;p&gt;I love reading the BBC to get a sense of how the rest of the world is getting the news, but in particular I enjoy learning how the US is perceived on the other side of the pond.&lt;/p&gt;

&lt;p&gt;&lt;a href='http://news.bbc.co.uk/2/hi/programmes/from_our_own_correspondent/7453357.stm'&gt;The United States of Advertising&lt;/a&gt; is a spot on commentary about how the US allows advertising for prescription drugs:&lt;/p&gt;

&lt;blockquote&gt;
    &lt;p&gt;The best part of the adverts tends to come towards the end when the law requires the pharmaceutical company to list the possible side effects of the various products.&lt;/p&gt;
    
    &lt;p&gt;Sometimes these are spelled out in a warm tone implying this is all a bit of a formality imposed by our fuss-budget of a government.&lt;/p&gt;
    
    &lt;p&gt;On other occasions they are rattled out at speeds normally only reached by horse racing commentators in the closing stages of a big race.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;...&lt;/p&gt;

&lt;blockquote&gt;
    &lt;p&gt;They are a daily reminder of the many ways in which America - superficially so similar to Western Europe - is really profoundly different.&lt;/p&gt;
    
    &lt;p&gt;Those adverts with their sure sense of how to play on our doubts and insecurities are a symptom of the restless energy of American capitalism and of the belief that it can apply to issues of health and happiness just as readily as it can apply to polish or pet food.&lt;/p&gt;
&lt;/blockquote&gt;
          </content>  </entry>
  <entry xml:base="http://blog.infloop.com/">
    <author>
      <name>ahobson</name>
    </author>
    <id>tag:blog.infloop.com,2008-06-14:381</id>
    <published>2008-06-14T01:04:00Z</published>
    <updated>2008-06-14T01:04:35Z</updated>
    <category term="soccer euro2008"/>
    <link href="http://blog.infloop.com/2008/6/14/wise-soccer" rel="alternate" type="text/html"/>
    <title>Wise Soccer</title>
<content type="html">
            &lt;p&gt;I had my wisdom teeth out today, and the silver lining was getting to watch &lt;a href='http://edition.cnn.com/2008/SPORT/football/06/13/euros.italy/index.html'&gt;Romania battle Italy
&lt;/a&gt; and &lt;a href='http://edition.cnn.com/2008/SPORT/football/06/13/euros.netherlands/?iref=mpstoryview'&gt;A Clockwork Orange overwhelm France&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Seems like two of the best games of the tournament, and I got to watch them both.  Italy had a ton of chances, but just couldn't convert.  Give Romania credit: they played inspired ball.&lt;/p&gt;

&lt;p&gt;Here's hoping the Dutch can continue their incredible play.  It was beautiful to watch.&lt;/p&gt;

&lt;p&gt;Best line was from (I believe) Adrian Healey who said after the 3rd Dutch Goal:&lt;/p&gt;

&lt;blockquote&gt;
    &lt;p&gt;It's a Dutch oven, and the French are toast.&lt;/p&gt;
&lt;/blockquote&gt;
          </content>  </entry>
  <entry xml:base="http://blog.infloop.com/">
    <author>
      <name>ahobson</name>
    </author>
    <id>tag:blog.infloop.com,2008-05-28:380</id>
    <published>2008-05-28T00:29:00Z</published>
    <updated>2008-05-28T00:32:04Z</updated>
    <category term="feynman"/>
    <link href="http://blog.infloop.com/2008/5/28/feynman-inspiration" rel="alternate" type="text/html"/>
    <title>Feynman Inspiration</title>
<content type="html">
            &lt;p&gt;This article about &lt;a href='http://www.longnow.org/views/essays/articles/ArtFeynman.php'&gt;Richard Feynman working on the early Connection Machines&lt;/a&gt; is just dynamite.&lt;/p&gt;

&lt;blockquote&gt;
    &lt;p&gt;By the end of that summer of 1983, Richard had completed his analysis of the behavior of the router,  and much to our surprise and amusement, he presented his answer in the form of a set of partial differential equations. To a physicist this may seem natural, but to a computer designer, treating a set of boolean circuits as a continuous, differentiable system is a bit strange. Feynman's router equations 
    were in terms of variables representing continuous quantities such as &quot;the average number of 1 bits 
    in a message address.&quot; I was much more accustomed to seeing analysis in terms of inductive proof and case analysis than taking the derivative of &quot;the number of 1's&quot; with respect to time. Our discrete analysis said we needed seven buffers per chip; Feynman's equations suggested that we only needed five. We decided to play it safe and ignore Feynman.&lt;/p&gt;
    
    &lt;p&gt;The decision to ignore Feynman's analysis was made in September, but by next spring we were up against a wall. The chips that we had designed were slightly too big to manufacture and the only way to solve the problem was to cut the number of buffers per chip back to five. Since Feynman's equations claimed we could do this safely, his unconventional methods of analysis started looking better and better to us. We decided to go ahead and make the chips with the smaller number of buffers.&lt;/p&gt;
    
    &lt;p&gt;Fortunately, he was right. When we put together the chips the machine worked. The first program run on the machine in April of 1985 was Conway's game of Life.&lt;/p&gt;
&lt;/blockquote&gt;
          </content>  </entry>
  <entry xml:base="http://blog.infloop.com/">
    <author>
      <name>ahobson</name>
    </author>
    <id>tag:blog.infloop.com,2008-05-14:379</id>
    <published>2008-05-14T01:34:00Z</published>
    <updated>2008-05-14T01:36:03Z</updated>
    <category term="osx"/>
    <link href="http://blog.infloop.com/2008/5/14/late-to-the-leopard-party" rel="alternate" type="text/html"/>
    <title>Late to the Leopard Party</title>
<content type="html">
            &lt;p&gt;I finally upgraded to Leopard at the office.  No real problems yet, but I was surprised how many of the tools I use only have beta version for Leopard.&lt;/p&gt;

&lt;p&gt;First off is &lt;a href='http://www.sente.ch/software/GPGMail/English.lproj/GPGMail.html'&gt;GPGMail&lt;/a&gt;.  This works nicely, but since I use &lt;a href='http://www.macports.org/'&gt;MacPorts&lt;/a&gt;, I had to do the same hack on Leopard that I had to do on Tiger: binary edit the bundle to change the page to the gpg binary (&lt;code&gt;/opt/local/bin/gpg&lt;/code&gt; instead of &lt;code&gt;/usr/local/bin/gpg&lt;/code&gt;).  It's 2008, so feel free to stop hard coding binary paths.&lt;/p&gt;

&lt;p&gt;I used &lt;a href='http://www.suavetech.com/0xed/0xed.html'&gt;0xed&lt;/a&gt;, which works quite nicely.  The file to edit is&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Library/Mail/Bundles/GPGMail.mailbundle/Contents/Frameworks/MacGPGME.framework/Versions/1.1.4/MacGPGME
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Then I needed &lt;a href='http://www.indev.ca/MailActOn.html'&gt;Mail Act On&lt;/a&gt;, which is also &lt;a href='http://www.indev.ca/MailActOnAndLeopard.html'&gt;beta for Leopard&lt;/a&gt;, but this was an easy install with no post install customization needed.&lt;/p&gt;

&lt;p&gt;On Tiger, I use &lt;a href='http://iterm.sourceforge.net/'&gt;iTerm&lt;/a&gt; because eventually I just couldn't live without tabs.  I read about people that say &quot;Just use screen&quot;, but I use tabs &lt;em&gt;and&lt;/em&gt; &lt;a href='http://www.gnu.org/software/screen/'&gt;screen&lt;/a&gt;.  I usually have four windows, each with at least 4 tabs, and screen inside the tabs.  I used to have six windows, but my eyes aren't what they used to be, so I had to increase the font size.&lt;/p&gt;

&lt;p&gt;Leopard's Terminal.app has tabs, which work pretty nicely, except &lt;strong&gt;YOU CAN'T CHANGE THE TAB TITLE&lt;/strong&gt;.  &lt;em&gt;boggle&lt;/em&gt;.  Fortunately, &lt;a href='http://www.culater.net/software/SIMBL/SIMBL.php'&gt;SIMBL&lt;/a&gt; plus a &lt;a href='http://ericanderson.us/2008/03/02/terminalapp-tab-namer-v01-alpha/'&gt;tab namer bundle&lt;/a&gt; and all is well.&lt;/p&gt;

&lt;p&gt;I use &lt;a href='http://docs.blacktree.com/quicksilver/what_is_quicksilver'&gt;Quicksilver&lt;/a&gt; constantly, and it seems to work pretty well on Leopard.  The one problem I've found is that the &lt;code&gt;LockScreen&lt;/code&gt; included in the &lt;code&gt;Extra Scripts&lt;/code&gt; plugin doesn't work on Leopard.  While trying to troubleshoot the problem, I discovered that ktrace is no longer around.  Fortunately, &lt;a href='http://developer.apple.com/documentation/Darwin/Reference/ManPages/man1/dtruss.1m.html'&gt;dtruss&lt;/a&gt; is provided, which utilizes the awesome power of &lt;a href='http://www.sun.com/bigadmin/content/dtrace/'&gt;dtrace&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Fortunately, it's easy to write your own AppleScript to replace the &lt;code&gt;LockScreen&lt;/code&gt; from Quicksilver.  I even added the capability to pause iTunes and lock the screen at the same time.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;try
    tell application &quot;iTunes&quot; to pause
    tell application id &quot;com.apple.ScreenSaver.Engine&quot; to launch
end try
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Save the script to&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Library/Application Support/Quicksilver/PlugIns/Extra Scripts.qsplugin/Contents/Resources/ExtraScripts/Processes
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Finally, let me add my voice to the legions complaining about the &lt;a href='http://discussions.apple.com/thread.jspa?threadID=1201297&amp;amp;amp;start=0&amp;amp;amp;tstart=60'&gt;craptacular ical downgrade&lt;/a&gt; where apple removed the detail drawer in Leopard.  It takes me 4 clicks to add an alarm to an appointment when I used to do it in one.  I don't care how they add it back, but I want some way of seeing appointment details with a single click.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://blog.infloop.com/">
    <author>
      <name>ahobson</name>
    </author>
    <id>tag:blog.infloop.com,2008-04-15:378</id>
    <published>2008-04-15T02:25:00Z</published>
    <updated>2008-04-15T02:25:59Z</updated>
    <category term="politics"/>
    <link href="http://blog.infloop.com/2008/4/15/f-ck-bush-in-the-neck" rel="alternate" type="text/html"/>
    <title>F*ck Bush in the neck</title>
<content type="html">
            &lt;p&gt;Bruce Fein in Slate on &lt;a href='http://www.slate.com/id/2187811'&gt;How to fix the presidency&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
    &lt;p&gt;President George W. Bush's successor should renounce his monarchy. It betters the instruction of King George III, which provoked the Declaration of Independence. Among other things, the 44th president of the United States should do the following promptly upon taking office: Transfer the impending trials of six &quot;high-value&quot; al-Qaida detainees before Spanish Inquisition-like military commissions to civilian courts; repudiate President Bush's kidnappings, secret imprisonments, and maltreatments of suspected al-Qaida supporters abroad on his say-so alone—a page from Hobbes' state of nature; denounce signing statements that declare the president's intent to disregard provisions of bills he has signed into law because he disputes their constitutionality; and end the snobbish custom of former government Brahmins preening in their honorifics after leaving office. The Founding Fathers prohibited titles of nobility to encourage a nonhierarchical culture that honors equality before the law.&lt;/p&gt;
&lt;/blockquote&gt;
          </content>  </entry>
  <entry xml:base="http://blog.infloop.com/">
    <author>
      <name>ahobson</name>
    </author>
    <id>tag:blog.infloop.com,2008-03-27:377</id>
    <published>2008-03-27T12:18:00Z</published>
    <updated>2008-03-27T12:18:52Z</updated>
    <category term="rails ambling"/>
    <link href="http://blog.infloop.com/2008/3/27/amcharts-rails-plugin" rel="alternate" type="text/html"/>
    <title>Amcharts Rails Plugin</title>
<content type="html">
            &lt;p&gt;My first rubyforge project is called &lt;a href='http://ambling.rubyforge.org'&gt;Ambling&lt;/a&gt;: a rails plugin that makes it easy to generate XML for the excellent &lt;a href='http://www.amcharts.com'&gt;Amcharts&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Instead of having to use Builder to generate the XML, you can do something like this in your controller to generate the data XML:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt; def pie_data
   chart = Ambling::Data::Pie.new
   FavoriteColor.count(:color, :group =&amp;gt; :color).each do |data|
     chart.slices &amp;lt;&amp;lt; Ambling::Data::Slice.new(data.last, :title =&amp;gt; data.first,
                                             :url =&amp;gt; favorite_colors_path(:color =&amp;gt; data.first))
   end
   render :xml =&amp;gt; chart.to_xml
 end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And then in your view, embed the flash and customize the settings:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;%=
ambling_chart(:pie,  :data_file =&amp;gt; url_for(:action =&amp;gt; 'pie_data'),
                        :id =&amp;gt; 'pie_data', :width =&amp;gt; 290, :height =&amp;gt; 200,
                        :chart_settings =&amp;gt; Ambling::Pie::Settings.new({
                          :pie =&amp;gt; {
                            :x =&amp;gt; 110,
                            :y =&amp;gt; 110,
                            :radius =&amp;gt; 80,
                            :colors =&amp;gt; '#B40000,#F7941D,#0265AC',
                            :outline_color =&amp;gt; '#000000',
                            :outline_alpha =&amp;gt; 50,
                          },
                          :animation =&amp;gt; {
                            :pull_out_on_click =&amp;gt; false,
                          },
                          :data_labels =&amp;gt; {
                            :show =&amp;gt; cdata_section(&quot;&amp;lt;b&amp;gt;{value}&amp;lt;/b&amp;gt;&quot;), :radius =&amp;gt; -30,
                          },
                          :legend =&amp;gt; {
                            :enabled =&amp;gt; true, :x =&amp;gt; 195, :y =&amp;gt; 20, :width =&amp;gt; 100, :text_color =&amp;gt; '#000',
                            :max_columns =&amp;gt; 1, :spacing =&amp;gt; 2, :text_size =&amp;gt; 10,
                            :key =&amp;gt; {:size =&amp;gt; 10}
                          },
                          :labels =&amp;gt; {
                            :label =&amp;gt;
                              {:x =&amp;gt; 40, :y =&amp;gt; 5, :text =&amp;gt; cdata_section(&quot;&amp;lt;b&amp;gt;Favorite Colors&amp;lt;/b&amp;gt;&quot;),
                                :text_size =&amp;gt; 16, :text_color =&amp;gt; '#0265AC'},
                          }
                        }).to_xml) do
                    content_tag('p', &quot;To see this page properly, you need to upgrade your Flash Player&quot;)
end
%&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Changing a hash on the fly in the view is much easier for me than changing XML, even using builder.&lt;/p&gt;

&lt;p&gt;Thanks to the &lt;a href='http://ziya.liquidrail.com/'&gt;Ziya&lt;/a&gt; rails plugin for inspiration.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://blog.infloop.com/">
    <author>
      <name>ahobson</name>
    </author>
    <id>tag:blog.infloop.com,2008-02-29:376</id>
    <published>2008-02-29T15:02:00Z</published>
    <updated>2008-02-29T15:02:04Z</updated>
    <category term="environment politics"/>
    <link href="http://blog.infloop.com/2008/2/29/out-of-touch-with-out-of-touch" rel="alternate" type="text/html"/>
    <title>Out of touch with out of touch</title>
<content type="html">
            &lt;p&gt;Old News!  The LA Times has an article about how &lt;a href='http://www.latimes.com/news/printedition/front/la-na-gas29feb29,1,2210127.story?coll=la-headlines-frontpage'&gt;Bush is out of touch with reality&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
    &lt;p&gt;&quot;Wait, what did you just say? You're predicting $4-a-gallon gasoline?&quot; Bush responded to a reporter who said some analysts expect prices to soon climb that high. &quot;That's interesting. I hadn't heard that. . . . I know it's high now.&quot;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But the quote below that from the (wo)man on the street that's even funnier:&lt;/p&gt;

&lt;blockquote&gt;
    &lt;p&gt;&quot;Bush is out of touch with a lot of things we are facing today,&quot; said 33-year-old Marisa Cajbon, who was filling her Toyota Sequoia SUV with the expensive fuel. &quot;I have to buy gas. I need to work. I have two kids. I think it's unfortunate. I think it's a crime.&quot;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Hmm.  What &lt;a href='http://news.bbc.co.uk/1/hi/sci/tech/2642773.stm'&gt;things&lt;/a&gt; are we &lt;a href='http://www.pewclimate.org/hurricanes.cfm#severe'&gt;facing today&lt;/a&gt; while you drive your Toyota Sequoia SUV, getting what the EPA claims is 13mpg in the city?&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://blog.infloop.com/">
    <author>
      <name>ahobson</name>
    </author>
    <id>tag:blog.infloop.com,2008-02-25:374</id>
    <published>2008-02-25T03:30:00Z</published>
    <updated>2008-02-25T03:32:48Z</updated>
    <category term="rss shrook netnewswire"/>
    <link href="http://blog.infloop.com/2008/2/25/switching-to-netnewswire" rel="alternate" type="text/html"/>
    <title>Switching to NetNewsWire</title>
<content type="html">
            &lt;p&gt;I have been a &lt;a href='http://www.utsire.com/shrook/'&gt;Shrook&lt;/a&gt; user for over two years now (back when it wasn't free).  I liked its three pane display and it has support for per feed preferences such as show the page itself instead of the contents of the feed.  For feeds that only have excerpts and/or summaries, that makes the browsing experience so much nicer.  Plus, it had feed synchronization to a central server, which was great for me at the time because I had two Macs.  Unfortunately, it's a bit of a pig.  It takes a long time to start up and even longer to exit.&lt;/p&gt;

&lt;p&gt;When I saw that &lt;a href='http://www.newsgator.com/Individuals/NetNewsWire/'&gt;NetNewsWire&lt;/a&gt; was now free, I thought I should give it a try.  Holy Smokes!  It's soooo much faster.  The three pane display is nice enough; I think Shrook's is slightly nicer.  But it doesn't have a per feed preference for fetching the page instead of the feed content.&lt;/p&gt;

&lt;p&gt;I couldn't believe that, so I did some googling.  Fortunately for me, I tried NNW at just the right time because just days before I started using NNW, &lt;a href='http://www.ollicle.com/2008/feb/07/netnewswire_style_hack.html'&gt;Oliver Boermans&lt;/a&gt; contributed a style that uses javascript to show the current page.  Unfortunately, it does it for all feeds.&lt;/p&gt;

&lt;p&gt;I was reading the comments and I found someone had the brilliant idea of making it conditional depending on which page is being loaded.  The commenter did it from the title of the page, which seemed less than ideal to me.  They also iterated through an array of sites instead of using javascript's native ability to have strings as array subscripts.&lt;/p&gt;

&lt;p&gt;So here's my version that extracts the hostname from the URL and displays the page if that host is one of the hardcoded ones.  I'm not javascript expert, but I was surprised that I couldn't find a built in function that parses URLs; maybe my google-fu is weak.  I had to use a regexp.&lt;/p&gt;

&lt;p&gt;This is not nearly as nice as Shrook's per feed preferences, but with this hack, I'm afraid I don't miss Shrook any more.  The performance difference is just too good to give up.  I modified the Default 3.1 style to include the javascript hack; if you prefer a different style, just add similar javascript to your preferred style.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;div id=&quot;_pageContainer&quot;&amp;gt;
&amp;lt;div id=&quot;_newsItemTitle&quot;&amp;gt;[[newsitem_title]]&amp;lt;/div&amp;gt;
&amp;lt;script type=&quot;text/javascript&quot;&amp;gt;
  var previewArray = new Array();
  previewArray[&quot;reddit.com&quot;] = true;
  previewArray[&quot;permalink.gmane.org&quot;] = true;
  previewArray[&quot;atlanta.craigslist.org&quot;] = true;
  previewArray[&quot;isc.sans.org&quot;] = true;
  previewArray[&quot;krugman.blogs.nytimes.com&quot;] = true;
  previewArray[&quot;freakonomics.blogs.nytimes.com&quot;] = true;

  href = document.getElementById('_newsItemTitle').firstChild.getAttribute('href');
  var e=/http:\/\/([^:\/\s]+)([^?\s]+)/;
  if (href.match(e)) {
    host = RegExp.$1;
    if (previewArray[host]) {
      location.replace(href);
    }
  }
&amp;lt;/script&amp;gt;
&amp;lt;div id=&quot;_newsItemContent&quot;&amp;gt;
&amp;lt;div id=&quot;_newsItemDateline&quot;&amp;gt;[[newsitem_dateline]]&amp;lt;/div&amp;gt;
&amp;lt;div id=&quot;_newsItemDescription&quot;&amp;gt;
    [[newsitem_description]]
&amp;lt;/div&amp;gt;
&amp;lt;div id=&quot;_newsItemExtraLinks&quot;&amp;gt;[[newsitem_extralinks]]&amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
          </content>  </entry>
  <entry xml:base="http://blog.infloop.com/">
    <author>
      <name>ahobson</name>
    </author>
    <id>tag:blog.infloop.com,2007-12-21:373</id>
    <published>2007-12-21T02:56:00Z</published>
    <updated>2007-12-21T02:57:05Z</updated>
    <category term="sql"/>
    <link href="http://blog.infloop.com/2007/12/21/our-happy-union" rel="alternate" type="text/html"/>
    <title>Our happy UNION</title>
<content type="html">
            &lt;p&gt;Before I started my current job, I had played with SQL a bit, but had never done anything remotely advanced.  Now, I'm sort of the defacto DBA, and so I've had to learn a great deal.  One of the things I'm using more and more are UNIONs.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;NOTE: The examples here are written using PostgreSQL.  Your mileage may vary with other databases.&lt;/em&gt;
&lt;em&gt;NOTE: These idioms will be nothing new to the SQL expert.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;Time UNIONs&lt;/h3&gt;

&lt;p&gt;One common use of UNIONs is to combine tables that have data from separate times.  For example, suppose that you summarize your apache access logs by day, and so you have something like&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;CREATE TABLE apache_summary_20071201 (
   ip                  cidr,
   url                 text,
   user_agent     text
);

CREATE TABLE apache_summary_20071202 (
  ip                  cidr,
  url                 text,
  user_agent     text
);
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;em&gt;NOTE: I actually prefer to use &lt;a href='http://ip4r.projects.postgresql.org/'&gt;ip4r&lt;/a&gt;, but the &lt;code&gt;cidr&lt;/code&gt; type is built in.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Then you can create a VIEW to UNION them together.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;CREATE OR REPLACE VIEW apache_summary AS
SELECT '2007-12-01'::date AS ymd, apache_summary_20071201.* FROM apache_summary_20071201
UNION ALL
SELECT '2007-12-02'::date AS ymd, apache_summary_20071202.* FROM apache_summary_20071202;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now you can get all of the data at once.  Plus, if you only need one day's worth of data, the query planner is smart enough to only fetch from the table you need if you supply a constant condition.  Notice the &lt;code&gt;One-Time Filter: false&lt;/code&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;db=&amp;gt; EXPLAIN SELECT * FROM apache_summary WHERE ymd = '2007-12-01';
                                     QUERY PLAN                                          
---------------------------------------------------------------------------------------------
 Append  (cost=0.00..44.80 rows=1240 width=96)
   -&amp;gt;  Subquery Scan &quot;*SELECT* 1&quot;  (cost=0.00..22.40 rows=620 width=96)
         -&amp;gt;  Seq Scan on apache_summary_20071201  (cost=0.00..16.20 rows=620 width=96)
   -&amp;gt;  Subquery Scan &quot;*SELECT* 2&quot;  (cost=0.00..22.40 rows=620 width=96)
         -&amp;gt;  Result  (cost=0.00..16.20 rows=620 width=96)
               One-Time Filter: false
               -&amp;gt;  Seq Scan on apache_summary_20071202  (cost=0.00..16.20 rows=620 width=96)
(7 rows)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The advantage to this approach versus &lt;a href='http://www.postgresql.org/docs/8.2/static/ddl-partitioning.html'&gt;partitioning tables&lt;/a&gt; is that you don't have to store the date with each entry.  Since every entry in the table has the same value, a VIEW works out nicely.  The downside is that you can't just add another subquery to the VIEW, so you have to know what is there in order to recreate the view with an additional table.  Partitioning makes that much easier.&lt;/p&gt;

&lt;h3&gt;LIMIT UNIONs&lt;/h3&gt;

&lt;p&gt;Sometimes when doing reports from a database, you want to get a representative sample for each item you are interested in.  For example, imagine that you had a query to return the 10 most popular URLs from your &lt;code&gt;apache_summary&lt;/code&gt; VIEW (an exercise left to the reader).  Then suppose that you wanted to see the 3 most popular User Agents &lt;em&gt;for each URL&lt;/em&gt;.  The simple way would be to issue 10 queries, each looking something like&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;SELECT user_agent, count(*) AS ucount
FROM apache_summary
WHERE ymd = '2007-12-1'
AND url = 'something'
GROUP BY user_agent
ORDER BY ucount DESC
LIMIT 3;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In a background report, that's probably ok, but if this is a web page, the latency of doing 10 queries might really slow things down.  Enter our friend, the UNION.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(
SELECT url, user_agent, count(*) AS ucount
FROM apache_summary
WHERE ymd = '2007-12-1'
AND url = 'something'
GROUP BY user_agent
ORDER BY ucount DESC
LIMIT 3
) UNION ALL (
SELECT url, user_agent, count(*) AS ucount
FROM apache_summary
WHERE ymd = '2007-12-1'
AND url = 'something_else'
GROUP BY user_agent
ORDER BY ucount DESC
LIMIT 3
) UNION ALL (
...
);
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now we can issue a single query to get all of the results, which will really help page load times.&lt;/p&gt;

&lt;h3&gt;Polymorphic Association UNIONs&lt;/h3&gt;

&lt;p&gt;Suppose you are using Ruby on Rails and you want to use &lt;a href='http://wiki.rubyonrails.org/rails/pages/UnderstandingPolymorphicAssociations'&gt;Polymorphic Associations&lt;/a&gt;, but because you are database weenie, you don't want to give up your foreign key constraints.&lt;/p&gt;

&lt;p&gt;Let's use the example from the link above.  We have Addresses, that are shared between Users and Orders.  Normally, we'd do something like&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;CREATE TABLE users (
  id                        SERIAL PRIMARY KEY,
  name                   text
);

CREATE TABLE orders (
  id                        SERIAL PRIMARY KEY,
  order_number      text
);

CREATE TABLE addresses (
  id                        SERIAL PRIMARY KEY,
  city                      text,
  country                text,
  addressable_id      int,
  addressable_type  text
);
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;em&gt;NOTE: Actually, I'd include UNIQUE constraints, use singular table names and include the table name in the primary key (e.g. &lt;code&gt;user_id&lt;/code&gt;), but for simplicity, I'll do it like DHH.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Unfortunately, if something goes wrong (maybe with the DBA doing a fat finger), we can delete a row from &lt;code&gt;users&lt;/code&gt; that still has a reference in &lt;code&gt;addresses&lt;/code&gt; since the database can't enforce foreign key constraints.  That might make things blow up.&lt;/p&gt;

&lt;p&gt;So now, let's try this with a UNION.  We'll leave &lt;code&gt;users&lt;/code&gt; and &lt;code&gt;orders&lt;/code&gt; well enough alone.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;CREATE TABLE user_addresses (
  id                        SERIAL PRIMARY KEY,
  city                      text,
  country                text,
  user_id                int REFERENCES users(id)
);

CREATE TABLE order_addresses (
  id                        SERIAL PRIMARY KEY,
  city                      text,
  country                text,
  order_id              int REFERENCES orders(id)
);

CREATE VIEW addresses AS
SELECT id || ':user' AS id, city, country, 'User' AS addressable_type, user_id AS addressable_id
FROM user_addresses
UNION ALL
SELECT id || ':order' AS id, city, country, 'Order' AS addressable_type, order_id AS addressable_id
FROM order_addresses;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I should point out a couple of things.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;This will only work for read only access.  You'd need to add a trigger
   that would redirect INSERTs and UPDATEs to the appropriate table.  Left as an exercise for the
   reader.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;id&lt;/code&gt; field in the VIEW is not an integer.  In my experience, Rails handles that just fine for
   read only access, but chokes when adding a row.  You'd have to define a custom primary key.
   Left as an exercise for the reader.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I've used this last one to good effect because we have some data loading that occurs outside of rails, but I need to display the data on our web page.  We get to keep foreign key constraints, and I get to use the power of rails.  Double Win!&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://blog.infloop.com/">
    <author>
      <name>ahobson</name>
    </author>
    <id>tag:blog.infloop.com,2007-12-09:372</id>
    <published>2007-12-09T03:32:00Z</published>
    <updated>2007-12-09T03:32:32Z</updated>
    <category term="programming"/>
    <link href="http://blog.infloop.com/2007/12/9/doctors-and-programmers" rel="alternate" type="text/html"/>
    <title>Doctors and Programmers</title>
<content type="html">
            &lt;p&gt;More from the article on &lt;a href='http://www.newyorker.com/reporting/2007/12/10/071210fa_fact_gawande'&gt;checklists in medicine&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
    &lt;p&gt;Tom Wolfe’s “The Right Stuff” tells the story of our first astronauts, and charts the demise of the maverick, Chuck Yeager test-pilot culture of the nineteen-fifties. It was a culture defined by how unbelievably dangerous the job was. Test pilots strapped themselves into machines of barely controlled power and complexity, and a quarter of them were killed on the job. The pilots had to have focus, daring, wits, and an ability to improvise—the right stuff. But as knowledge of how to control the risks of flying accumulated—as checklists and flight simulators became more prevalent and sophisticated—the danger diminished, values of safety and conscientiousness prevailed, and the rock-star status of the test pilots was gone.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I wonder if the same transformation from rock-star status will happen to developers.  I think it should, but I don't know how long it will be before the industry is mature enough to support such a thing.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://blog.infloop.com/">
    <author>
      <name>ahobson</name>
    </author>
    <id>tag:blog.infloop.com,2007-12-08:371</id>
    <published>2007-12-08T03:15:00Z</published>
    <updated>2007-12-08T03:16:22Z</updated>
    <category term="medical miracle"/>
    <link href="http://blog.infloop.com/2007/12/8/the-heck" rel="alternate" type="text/html"/>
    <title>&amp;%*#! the Heck!</title>
<content type="html">
            &lt;p&gt;The New Yorker has an article on how the &lt;a href='http://www.newyorker.com/reporting/2007/12/10/071210fa_fact_gawande'&gt;medical profession is starting to use checklists&lt;/a&gt; when performing complicated procedures so that important steps aren't missed.  Tip of the hat to &lt;a href='http://www.mindhacks.com/'&gt;Mind Hacks&lt;/a&gt; for the link.&lt;/p&gt;

&lt;p&gt;I find it fascinating that this is a new development, because as far as I know, step by step lists are best practice when performing complicated computer procedures.  As I learned from a former Finnish co-worker, writing all the steps out before hand along with what to do in case of problems is critical to a smooth deployment.&lt;/p&gt;

&lt;p&gt;What prompted the title, though, is a story in the article.  I'll quote the same part that Mind Hacks did:&lt;/p&gt;

&lt;blockquote&gt;
    &lt;p&gt;Consider a case report in The Annals of Thoracic Surgery of a three-year-old girl who fell into an icy fishpond in a small Austrian town in the Alps. She was lost beneath the surface for thirty minutes before her parents found her on the pond bottom and pulled her up. Following instructions from an emergency physician on the phone, they began cardiopulmonary resuscitation. A rescue team arrived eight minutes later. The girl had a body temperature of sixty-six degrees, and no pulse. Her pupils were dilated and did not react to light, indicating that her brain was no longer working.&lt;/p&gt;
    
    &lt;p&gt;But the emergency technicians continued CPR anyway. A helicopter took her to a nearby hospital, where she was wheeled directly to an operating room. A surgical team put her on a heart-lung bypass machine. Between the transport time and the time it took to plug the inflow and outflow lines into the femoral vessels of her right leg, she had been lifeless for an hour and a half. By the two-hour mark, however, her body temperature had risen almost ten degrees, and her heart began to beat. It was her first organ to come back.&lt;/p&gt;
    
    &lt;p&gt;After six hours, her core temperature reached 98.6 degrees. The team tried to put her on a breathing machine, but the pond water had damaged her lungs too severely for oxygen to reach her blood. So they switched her to an artificial-lung system known as ECMO—extracorporeal membrane oxygenation. The surgeons opened her chest down the middle with a power saw and sewed lines to and from the ECMO unit into her aorta and her beating heart. The team moved the girl into intensive care, with her chest still open and covered with plastic foil. A day later, her lungs had recovered sufficiently for the team to switch her from ECMO to a mechanical ventilator and close her chest. Over the next two days, all her organs recovered except her brain. A CT scan showed global brain swelling, which is a sign of diffuse damage, but no actual dead zones. So the team drilled a hole into the girl’s skull, threaded in a probe to monitor her cerebral pressure, and kept that pressure tightly controlled by constantly adjusting her fluids and medications. For more than a week, she lay comatose. Then, slowly, she came back to life.&lt;/p&gt;
    
    &lt;p&gt;First, her pupils started to react to light. Next, she began to breathe on her own. And, one day, she simply awoke. Two weeks after her accident, she went home. Her right leg and left arm were partially paralyzed. Her speech was thick and slurry. But by age five, after extensive outpatient therapy, she had recovered her faculties completely. She was like any little girl again.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That's $#&amp;amp;%! amazing.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://blog.infloop.com/">
    <author>
      <name>ahobson</name>
    </author>
    <id>tag:blog.infloop.com,2007-12-02:368</id>
    <published>2007-12-02T22:30:00Z</published>
    <updated>2007-12-02T22:30:11Z</updated>
    <category term="mobile phone"/>
    <link href="http://blog.infloop.com/2007/12/2/phone-shopping" rel="alternate" type="text/html"/>
    <title>Phone Shopping</title>
<content type="html">
            &lt;p&gt;I'm in the market for a new mobile phone, and I'm trying to decide what to buy.  I have a &lt;a href='http://www.sonyericsson.com/cws/products/mobilephones/overview/p910i'&gt;Sony Ericsson P910i&lt;/a&gt; right now.  It's been a good phone, but it's getting long in the tooth.&lt;/p&gt;

&lt;p&gt;I'd like a new mobile that supports WiFi and something faster than GPRS.  I prefer something with a keyboard.  I don't need to check my email constantly, but I would like to be able to do so from time to time.  My daughter loves the drawing application on the P910i, so ideally my new phone would also have that capability.&lt;/p&gt;

&lt;p&gt;The contenders?  In my mind, it's between &lt;a href='http://www.apple.com/iphone/'&gt;Apple's iPhone&lt;/a&gt;, &lt;a href='http://www.nseries.com/products/n95/#l=products,n95'&gt;Nokia's N95&lt;/a&gt;, and the latest update to my P910, &lt;a href='http://developer.sonyericsson.com/site/global/products/phonegallery/p990/p_p990.jsp'&gt;Sony Ericsson's P990&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I know I left out the Treo.  I was a Palm user from the beginning (I think I still have an original Palm Pilot with the logo from before they were bought by 3com).  Before the P910, I had a &lt;a href='http://www.mobiledia.com/phones/samsung/sph-i300.html'&gt;Samsung SPH i300&lt;/a&gt;, and while it was awesome at the time, Palm hasn't innovated much in the past 5 years.  I think the Treo is a clumsy phone with a PDA grafted on.  Sorry, but I'm not going back.&lt;/p&gt;

&lt;p&gt;The &lt;a href='http://www.engadgetmobile.com/2007/05/09/sony-ericsson-p1-gets-reviewed/'&gt;Sony Ericsson P1&lt;/a&gt; is a non starter because of its lack of EDGE support.&lt;/p&gt;

&lt;p&gt;As a mac guy, the iPhone is really compelling.  I really appreciate a great UI, and the iPhone is going to provide that in spades; &lt;a href='http://www.russellbeattie.com/blog/some-nokia-n95-and-s60-thoughts'&gt;much cleaner than the N95&lt;/a&gt;, even though the N95 is more advanced in almost every way.  The N95's advantage with GPS and Google Maps may not be as big a deal with the &lt;a href='http://www.google.com/intl/en/press/annc/20071128_maps_mobile_my_location.html'&gt;new Google Maps that uses cell towers to estimate location.&lt;/a&gt;.  Unfortunately, the iPhone doesn't support &lt;a href='http://cre.ations.net/blog/post/tether-your-iphone'&gt;tethering without a jailbreak and a SOCKS proxy&lt;/a&gt;, and I doubt the SDK will change that.  I don't need to connect via the laptop daily, but for the occasional use, it would be hard to give that up.&lt;/p&gt;

&lt;p&gt;This &lt;a href='http://gigaom.com/2007/04/07/nokia-n95-review/'&gt;N95 review&lt;/a&gt; shows just how powerful a phone it is.  But Audrey wouldn't have a drawing application.&lt;/p&gt;

&lt;p&gt;I may just wait.  With the &lt;a href='http://www.ehomeupgrade.com/entry/4373/third_party_applications'&gt;iPhone SDK coming in February&lt;/a&gt; and a &lt;a href='http://www.pcworld.com/article/id,140130-c,iphone/article.html'&gt;3G iPhone coming sometime in 2008&lt;/a&gt;, now looks like a bad time to buy.&lt;/p&gt;

&lt;p&gt;Honestly, the most interesting thing to wait for is the new &lt;a href='http://www.allaboutsymbian.com/news/item/6089_S60_Touch_Interface_Launched.php'&gt;S60 Touch Interface&lt;/a&gt;.  Unfortunately, who knows how long that will be?  Since Nokia hasn't announced a release date, it's probably going to be in the second half of 2008.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;sigh&lt;/em&gt;&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://blog.infloop.com/">
    <author>
      <name>ahobson</name>
    </author>
    <id>tag:blog.infloop.com,2007-12-02:370</id>
    <published>2007-12-02T21:31:00Z</published>
    <updated>2007-12-02T21:31:22Z</updated>
    <category term="kidnapping torture"/>
    <link href="http://blog.infloop.com/2007/12/2/why-do-i-live-here-again" rel="alternate" type="text/html"/>
    <title>Why do I live here, again?</title>
<content type="html">
            &lt;p&gt;&lt;a href='http://www.newyorker.com/archive/2005/02/14/050214fa_fact6'&gt;Kidnapping&lt;/a&gt;, more &lt;a href='http://www.timesonline.co.uk/tol/news/world/us_and_americas/article2982640.ece'&gt;Kidnapping&lt;/a&gt;, and &lt;a href='http://www.salon.com/opinion/feature/2007/11/09/nance/'&gt;Torture&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Maybe &lt;a href='http://blog.wired.com/sterling/2007/01/cory_doctorow_r.html'&gt;Cory&lt;/a&gt; is right.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://blog.infloop.com/">
    <author>
      <name>ahobson</name>
    </author>
    <id>tag:blog.infloop.com,2007-12-02:369</id>
    <published>2007-12-02T03:08:00Z</published>
    <updated>2007-12-02T03:08:41Z</updated>
    <category term="intelligence"/>
    <link href="http://blog.infloop.com/2007/12/2/smarten-up" rel="alternate" type="text/html"/>
    <title>Smarten Up</title>
<content type="html">
            &lt;p&gt;I'm not sure I like some of the things that James Flynn says, but I find his analysis of our &lt;a href='http://www.moreintelligentlife.com/node/654'&gt;evolving intelligence&lt;/a&gt; pretty compelling.  As a parent, I recognized myself:&lt;/p&gt;

&lt;blockquote&gt;
    &lt;p&gt;And when he looks at his two-year-old grandson, he sees social priorities shifting still further. &quot;His parents have enlisted in the great crusade of intellectual stimulation. If he identifies something they immediately pounce on it. A parent 30 years ago who was looking at a book with their child, if the child said, ‘that's a cow'; they would say, ‘you're right, it's a cow.' Today's parent will add, ‘And what noise does a cow make? How many legs does a cow have?' And away they go.&quot;&lt;/p&gt;
    
    &lt;p&gt;I tell him that this story makes me think of my own 18-month-old son, who, when I took him to his room the night before our conversation, had turned the light switch on and off, again and again, until finally, to his disgust, I had pulled him away to put him in his cot. &quot;Exactly! Merely being surrounded by mechanical contrivances prepares you to have a different mindset. They are artificial causal networks. That in itself helps to free the mind.&quot;&lt;/p&gt;
&lt;/blockquote&gt;
          </content>  </entry>
  <entry xml:base="http://blog.infloop.com/">
    <author>
      <name>ahobson</name>
    </author>
    <id>tag:blog.infloop.com,2007-10-22:367</id>
    <published>2007-10-22T01:37:00Z</published>
    <updated>2007-10-22T01:37:30Z</updated>
    <category term="politics"/>
    <link href="http://blog.infloop.com/2007/10/22/compare-and-contrast" rel="alternate" type="text/html"/>
    <title>Compare and Contrast</title>
<content type="html">
            &lt;p&gt;Bill Maher interviews &lt;a href='http://youtube.com/watch?v=LQYyPooETcI'&gt;Gary Kasparov, who is running against Putin&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Matthew Diaz, naval lawyer at Guantánamo, is &lt;a href='http://www.nytimes.com/2007/10/21/magazine/21Diaz-t.html?_r=1&amp;amp;amp;pagewanted=1&amp;amp;amp;ref=washington&amp;amp;amp;oref=slogin'&gt;convicted and sentenced for releasing the names of the prisoners&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Kasparov is marvelous: sharp, eloquent and slyly funny.  If you had told me in 1988 that a country would imprison someone for releasing the names of prisoners because the ruling powers were ignoring the rule of law, I certainly would have guessed the USSR before guessing the USA.&lt;/p&gt;

&lt;p&gt;And who would have guessed that the opposition candidate not afraid to speak the truth would be in Russia?&lt;/p&gt;
          </content>  </entry>
</feed>
