<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-145332831106508186</id><updated>2012-01-26T12:41:42.807-05:00</updated><category term='bug report'/><category term='np'/><category term='calendar'/><category term='installation'/><category term='news'/><category term='notify-osd'/><category term='stuff'/><category term='web apps'/><category term='shopping'/><category term='syntax'/><category term='upgrade'/><category term='phone'/><category term='chrome'/><category term='sprint'/><category term='firefox'/><category term='sshfs'/><category term='buzz'/><category term='location'/><category term='job'/><category term='css'/><category term='cellphones'/><category term='git'/><category term='latitude'/><category term='gcalcli'/><category term='geekery'/><category term='software engineering'/><category term='rss'/><category term='family'/><category term='beos'/><category term='email'/><category term='unicode'/><category term='pop culture'/><category term='frustration'/><category term='pic'/><category term='removing pessimizations'/><category term='solaris'/><category term='review'/><category term='graphical programming'/><category term='crontab'/><category term='work'/><category term='rant'/><category term='weather'/><category term='facebook'/><category term='boilerweb'/><category term='TV'/><category term='jabber'/><category term='dancer'/><category term='java'/><category term='rock'/><category term='oddmuse'/><category term='consumerism'/><category term='wifi'/><category term='x11'/><category term='httpd'/><category term='security'/><category term='automobiles'/><category term='information'/><category term='instinct'/><category term='philosophy'/><category term='bash'/><category term='computers'/><category term='gui'/><category term='networking'/><category term='home automation'/><category term='every day carry'/><category term='complaint'/><category term='puppet'/><category term='mvc'/><category term='routeshout'/><category term='emulation'/><category term='android'/><category term='desktop'/><category term='o&apos;reilly'/><category term='festival'/><category term='delicious'/><category term='html'/><category term='sikuli'/><category term='book review'/><category term='puzzles'/><category term='dropbox'/><category term='command-line'/><category term='sucking'/><category term='net neutrality'/><category term='fun'/><category term='version control'/><category term='testing'/><category term='ubuntu'/><category term='various and sundry'/><category term='blogging'/><category term='json'/><category term='subversion'/><category term='google'/><category term='ruby'/><category term='simplicity'/><category term='mail'/><category term='technology'/><category term='yahoo pipes'/><category term='effective perl'/><category term='ipap'/><category term='javascript'/><category term='fuse'/><category term='debugging'/><category term='perl'/><category term='passwords'/><category term='lucid'/><category term='skype'/><category term='github'/><category term='mindless link propagation'/><category term='browsers'/><category term='star wars'/><category term='gnome'/><category term='live CDs'/><category term='python'/><category term='shell'/><category term='ironman'/><category term='graphing'/><category term='free terry'/><category term='windows'/><category term='catalyst'/><category term='oauth'/><category term='linuxfest'/><category term='code'/><category term='kvm'/><category term='thunderbird'/><category term='disfunction'/><category term='markup'/><category term='hardware'/><category term='linux'/><category term='arduino'/><category term='evo'/><category term='usb'/><category term='ajax'/><category term='ckeditor'/><category term='programming'/><category term='r'/><category term='games'/><category term='modules'/><category term='coding horror'/><category term='editors'/><category term='bookmarks'/><category term='defining terms'/><category term='larry wall'/><category term='office suites'/><category term='television'/><category term='pop'/><category term='gps'/><category term='jquery'/><category term='higher order perl'/><category term='cool'/><category term='bluetooth'/><category term='gizmo'/><category term='blackberry'/><category term='absolutely awesome perl modules'/><category term='sql'/><category term='hacks'/><category term='imap'/><category term='telephony'/><category term='unix'/><category term='twitter'/><category term='netbook'/><category term='history'/><category term='new gear day'/><category term='we live in the future'/><category term='opensolaris'/><category term='fail'/><category term='social media'/><category term='slashdot'/><category term='fail software'/><category term='beautiful code'/><category term='gmail'/><category term='system administration'/><title type='text'>/var/log/rant</title><subtitle type='html'>Logging my complaints through time</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default?start-index=101&amp;max-results=100'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>349</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-4587001320347483360</id><published>2012-01-18T14:41:00.000-05:00</published><updated>2012-01-18T14:41:40.825-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='dancer'/><category scheme='http://www.blogger.com/atom/ns#' term='mvc'/><category scheme='http://www.blogger.com/atom/ns#' term='perl'/><title type='text'>More Gripes and Misunderstandings about Dancer</title><content type='html'>&lt;div&gt;It has been suggested that I'm not using MVC separation, which is fair, as I don't really see MVC separation. I found the POD for &lt;code&gt;Dancer::Plugin::Database&lt;/code&gt;, and have modified my package to use it. &lt;code&gt;weather&lt;/code&gt; is the old one, &lt;code&gt;weather2&lt;/code&gt; is the new one using the plugin.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;pre class="python" name="code"&gt;package TestApp ;&lt;br /&gt;use Dancer ':syntax' ;&lt;br /&gt;use Dancer::Plugin::Database ;&lt;br /&gt;use lib '/home/jacoby/lib' ;&lt;br /&gt;use MyDB 'db_connect' ;&lt;br /&gt;use DateTime ;&lt;br /&gt;use Data::Dumper ;&lt;br /&gt;&lt;br /&gt;our $VERSION = '0.1' ;&lt;br /&gt;&lt;br /&gt;get '/' =&amp;gt; sub {&lt;br /&gt;    template 'index' ;&lt;br /&gt;    } ;&lt;/pre&gt;&lt;pre class="python" name="code"&gt;get '/weather' =&amp;gt; sub {&lt;br /&gt;    my $dbh = db_connect() ;&lt;br /&gt;    my $sql = &amp;lt;&amp;lt;SQL;&lt;br /&gt;    # Last Eight Hours&lt;br /&gt;    SELECT  time , AVG( temp_f )&lt;br /&gt;    FROM weather WHERE zip = "47909"&lt;br /&gt;    AND HOUR( TIMEDIFF( SYSDATE() , time ) ) &amp;lt; 9&lt;br /&gt;    GROUP BY HOUR(time)&lt;br /&gt;    ORDER BY time&lt;br /&gt;SQL&lt;br /&gt;    my $hr = $dbh-&amp;gt;selectall_arrayref( $sql ) or croak $dbh-&amp;gt;errstr ;&lt;br /&gt;    my @hr ;&lt;br /&gt;    for my $point ( @$hr ) {&lt;br /&gt;        my ( $time, $temp ) = @$point ;&lt;br /&gt;        my @time = split /\D+/ ,  $time ;&lt;br /&gt;        my $dt = DateTime-&amp;gt;new(&lt;br /&gt;            year  =&amp;gt; $time[0] ,&lt;br /&gt;            month =&amp;gt; $time[1] ,&lt;br /&gt;            day   =&amp;gt; $time[2] ,&lt;br /&gt;            hour =&amp;gt; $time[3] ,&lt;br /&gt;            minute =&amp;gt; $time[4] ,&lt;br /&gt;            second =&amp;gt; $time[5] ,&lt;br /&gt;            ) ;&lt;br /&gt;        my $data ;&lt;br /&gt;        $data-&amp;gt;{ time } = $dt-&amp;gt;format_cldr( 'h:mm a' ) ;&lt;br /&gt;        $data-&amp;gt;{ temp } = sprintf '%.1f', $temp ;&lt;br /&gt;        next if $data-&amp;gt;{ time } !~ /00/ ;&lt;br /&gt;        push @hr, $data ;&lt;br /&gt;        }&lt;br /&gt;    my $string = 'Temperature in West Lafayette for the last 8 hours' ;&lt;br /&gt;    my $hr_ptr = \@hr ;&lt;br /&gt;    template 'weather' , {&lt;br /&gt;        string =&amp;gt; $string ,&lt;br /&gt;        weather =&amp;gt; $hr_ptr&lt;br /&gt;        } ;&lt;br /&gt;    } ;&lt;br /&gt;&lt;br /&gt;get '/weather2' =&amp;gt; sub {&lt;br /&gt;    my $string = 'Temperature in West Lafayette for the last 8 hours' ;&lt;br /&gt;    my $sth = database-&amp;gt;prepare(&lt;br /&gt;        'SELECT  time , AVG( temp_f ) temp&lt;br /&gt;        FROM weather WHERE zip = "47909"&lt;br /&gt;        AND HOUR( TIMEDIFF( SYSDATE() , time ) ) &amp;lt; 9&lt;br /&gt;        GROUP BY HOUR(time)&lt;br /&gt;        ORDER BY time '&lt;br /&gt;        ) ;&lt;br /&gt;    $sth-&amp;gt;execute( ) ;&lt;br /&gt;    template 'weather' , {&lt;br /&gt;        string =&amp;gt; $string ,&lt;br /&gt;        xxx =&amp;gt; $sth-&amp;gt;fetchall_arrayref( ) ,&lt;br /&gt;        } ;&lt;br /&gt;    } ;&lt;br /&gt;&lt;br /&gt;true ;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;I have been pointed to&amp;nbsp;&lt;a href="http://search.cpan.org/~xsawyerx/Dancer-1.3091/lib/Dancer/Tutorial.pod"&gt;http://search.cpan.org/~xsawyerx/Dancer-1.3091/lib/Dancer/Tutorial.pod&lt;/a&gt;, and, beyond my wanting to be more specific in the munging of the data, &lt;code&gt;weather&lt;/code&gt; is very similar to "Our First Route Handler". (How I store some data is not necessarily how I want to display some data.)&lt;br /&gt;&lt;br /&gt;weather2 uses&amp;nbsp;&lt;a href="http://search.cpan.org/~bigpresh/Dancer-Plugin-Database-1.60/lib/Dancer/Plugin/Database.pm"&gt;http://search.cpan.org/~bigpresh/Dancer-Plugin-Database-1.60/lib/Dancer/Plugin/Database.pm&lt;/a&gt;&amp;nbsp;and you can see that there's much less code in there. The stuff I put into &amp;nbsp;MyDB exists in Dancer::Plugin::Database, and I probably could mess with the data before sending it on, instead of hooking up &lt;code&gt;$sth-&amp;gt;fetchall_arrayref()&lt;/code&gt; to the output.&lt;br /&gt;&lt;br /&gt;The big thing I see here, which I could do something about with weather but probably not with the plugin-using weather2, is the SQL code being here. I would much rather shove that SQL off into a library somewhere, which I've done elsewhere, than have it at this point. But maybe, that's an aspect of me not really getting the MVC thing yet.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-4587001320347483360?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/4587001320347483360/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=4587001320347483360' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/4587001320347483360'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/4587001320347483360'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2012/01/more-gripes-and-misunderstandings-about.html' title='More Gripes and Misunderstandings about Dancer'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-4047426177442208995</id><published>2012-01-18T11:17:00.001-05:00</published><updated>2012-01-18T11:17:48.468-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='dancer'/><category scheme='http://www.blogger.com/atom/ns#' term='mvc'/><category scheme='http://www.blogger.com/atom/ns#' term='perl'/><title type='text'>I Can't Help Feeling Stupid Standing 'Round</title><content type='html'>&lt;div&gt;We're jumping from straight Perl and CGI.pm for web applications to an MVC, a jump we've been wanting to do for years. I've tried Catalyst a couple times, and both times, I spend most of my learning curve thinking "If I wrote this up without an MVC, I'd be done and on to the next thing by now", and in general, I get told much the same thing by my bosses, in the form of "move on &amp;nbsp;to this other, non-MVC-related task".&lt;br /&gt;&lt;br /&gt;But that was Catalyst, which seemingly brings along half of CPAN with it. This time, I'm trying &lt;a href="http://perldancer.org/"&gt;Dancer&lt;/a&gt;&amp;nbsp;with Template Toolkit, and I'm getting some progress. Here's a chunk of code I have working.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;pre class="Perl" name="code"&gt;package TestApp ;&lt;br /&gt;use Dancer ':syntax' ;&lt;br /&gt;use lib '/home/jacoby/lib' ;&lt;br /&gt;use MyDB 'db_connect' ;&lt;br /&gt;use DateTime ;&lt;br /&gt;&lt;br /&gt;our $VERSION = '0.1' ;&lt;br /&gt;&lt;br /&gt;get '/' =&amp;gt; sub {&lt;br /&gt;    template 'index' ;&lt;br /&gt;    } ;&lt;br /&gt;&lt;br /&gt;get '/weather' =&amp;gt; sub {&lt;br /&gt;    my $dbh = db_connect() ;&lt;br /&gt;    my $sql = &amp;lt;&amp;lt;SQL;&lt;br /&gt;    # Last Eight Hours&lt;br /&gt;    SELECT  time , AVG( temp_f )&lt;br /&gt;    FROM weather WHERE zip = "47909"&lt;br /&gt;    AND HOUR( TIMEDIFF( SYSDATE() , time ) ) &amp;lt; 9&lt;br /&gt;    GROUP BY HOUR(time)&lt;br /&gt;    ORDER BY time&lt;br /&gt;SQL&lt;br /&gt;    my $hr = $dbh-&amp;gt;selectall_arrayref( $sql ) or croak $dbh-&amp;gt;errstr ;&lt;br /&gt;    my @hr ;&lt;br /&gt;    for my $point ( @$hr ) {&lt;br /&gt;        my ( $time, $temp ) = @$point ;&lt;br /&gt;        my @time = split /\D+/ ,  $time ;&lt;br /&gt;        my $dt = DateTime-&amp;gt;new(&lt;br /&gt;            year  =&amp;gt; $time[0] ,&lt;br /&gt;            month =&amp;gt; $time[1] ,&lt;br /&gt;            day   =&amp;gt; $time[2] ,&lt;br /&gt;            hour =&amp;gt; $time[3] ,&lt;br /&gt;            minute =&amp;gt; $time[4] ,&lt;br /&gt;            second =&amp;gt; $time[5] ,&lt;br /&gt;            ) ;&lt;br /&gt;        my $data ;&lt;br /&gt;        $data-&amp;gt;{ time } = $dt-&amp;gt;format_cldr( 'h:mm a' ) ;&lt;br /&gt;        $data-&amp;gt;{ temp } = sprintf '%.1f', $temp ;&lt;br /&gt;        next if $data-&amp;gt;{ time } !~ /00/ ;&lt;br /&gt;        push @hr, $data ;&lt;br /&gt;        }&lt;br /&gt;    my $vars = {&lt;br /&gt;        string =&amp;gt; 'Temperature in West Lafayette for the last 8 hours' ,&lt;br /&gt;        weather =&amp;gt; \@hr ,&lt;br /&gt;        } ;&lt;br /&gt;&lt;br /&gt;    template 'weather' , { var =&amp;gt; $vars } ;&lt;br /&gt;    } ;&lt;br /&gt;&lt;br /&gt;true ;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div&gt;A few notes here: MyDB.pm is a module I use to get a DBI object without putting the DB connection info into the code, making it safer for me to dump it in public like this. I've been collecting weather data for the West Lafayette area so I have a significant set to use when I want to play around with SQL and R.&lt;br /&gt;&lt;br /&gt;Normally, when I pass things around, I pass, for example, a hash of hashes, then sort on the keys of the hash. Here, I'm making an array of hashes, so it's pre-sorted. I'm liking that. Still wrapping my head around how to put data where Template Toolkit can get to it. I like having my HTML as HTML, with occasional &amp;lt;code&amp;gt;[% FOREACH object IN array %] [% object.value %] [% END %] &amp;lt;/code&amp;gt; sorts of thing added. I used to have lots of &amp;lt;code&amp;gt; print qq{&amp;lt;div&amp;gt; $div_contents &amp;lt;/div&amp;gt;} ;&amp;lt;/code&amp;gt; in my code, before I got here, where the coding standard is &amp;lt;code&amp;gt; print $cgi-&amp;gt;div( $div_contents ) ; &amp;lt;/code&amp;gt;, which is fine and all, but I always was very proud of my HTML and it feels good to be getting back into writing it in the midst of the coming of HTML5 and all.&lt;br /&gt;&lt;br /&gt;But I'm curious if I did this the correct way of putting together the data, or if there's an easier better way that isn't apparent from the Dancer::Cookbook POD. It seems like I should be expecting a greater leap than this seems to give. What am I missing, if anything?&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-4047426177442208995?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/4047426177442208995/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=4047426177442208995' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/4047426177442208995'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/4047426177442208995'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2012/01/i-cant-help-feeling-stupid-standing.html' title='I Can&apos;t Help Feeling Stupid Standing &apos;Round'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-1780807576146097317</id><published>2012-01-14T01:20:00.000-05:00</published><updated>2012-01-14T01:20:40.083-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='television'/><category scheme='http://www.blogger.com/atom/ns#' term='ubuntu'/><title type='text'>Ubuntu on the Big Screen</title><content type='html'>&lt;div style="text-align: center;"&gt;&lt;iframe allowfullscreen="" frameborder="0" height="312" mozallowfullscreen="" src="http://revision3.com/html5player-v11479?external=true&amp;amp;width=480&amp;amp;height=270" webkitallowfullscreen="" width="480"&gt;&lt;/iframe&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;iframe allowfullscreen="" frameborder="0" height="274" src="http://www.youtube.com/embed/jq_WaOLjdyQ" width="480"&gt;&lt;/iframe&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;So, Google TV, Apple TV, Roku, Boxee, and now &lt;a href="http://www.ubuntu.com/tv"&gt;Ubuntu TV&lt;/a&gt;. I think there's going to be problems making it a standard install because there's no standard setup on TVs. A big hamstring is the lack of Blu-Ray support in Linux (true last time I checked, maybe not now) but I can easily see a point soon where that doesn't matter anymore.&lt;br /&gt;&lt;br /&gt;So, the set-top is the new desktop? And is this reason to go to Linux Mint or even straight Debian on machines you want to run at work?&amp;nbsp;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-1780807576146097317?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/1780807576146097317/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=1780807576146097317' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/1780807576146097317'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/1780807576146097317'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2012/01/ubuntu-on-big-screen.html' title='Ubuntu on the Big Screen'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://img.youtube.com/vi/jq_WaOLjdyQ/default.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-2112956392871854555</id><published>2012-01-11T11:06:00.000-05:00</published><updated>2012-01-11T11:06:07.038-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cool'/><category scheme='http://www.blogger.com/atom/ns#' term='home automation'/><category scheme='http://www.blogger.com/atom/ns#' term='hardware'/><title type='text'>Belkin Offers Wireless Home Automation</title><content type='html'>&lt;div style="text-align: center;"&gt;&lt;iframe allowfullscreen="" frameborder="0" height="274" src="http://www.youtube.com/embed/MOCaD_mtu9I" width="480"&gt;&lt;/iframe&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;Home Automation is cool. This has been the opinion of this blog since the beginning. I have tested some X10 stuff before, and have found data-over-power-line to be unreliable. This is why the wireless setup that was mentioned in Google I/O last year (but not in any way delivered, as far as I can tell ) draws so much interest from me, and why I feel the need to show this video here. Wireless is &lt;i&gt;so&lt;/i&gt;&amp;nbsp;the way to go with this stuff. I wonder if you can put together little command-line apps to turn things on and off, which you can then set up via crontab on your Linux box to turn the lights on or start the coffee machine at 7am or so.&lt;br /&gt;&lt;br /&gt;I also like the motion sensor. In rooms where you're not going to want to darken while you're in them (bedroom, living room for movie night) and rooms where you're not likely going to be blocked from the motion sensor during your time there (bathroom, kitchen), lights on a motion sensor make all the sense in the world to me. I used to have one in my den and I loved it.&lt;br /&gt;&lt;br /&gt;Belkin's normally the "Hey! Cheap cable! Cool!" company for me, but I'd be more than happy to give this one a shot.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-2112956392871854555?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/2112956392871854555/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=2112956392871854555' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/2112956392871854555'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/2112956392871854555'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2012/01/belkin-offers-wireless-home-automation.html' title='Belkin Offers Wireless Home Automation'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://img.youtube.com/vi/MOCaD_mtu9I/default.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-1293950108217793290</id><published>2012-01-11T10:40:00.002-05:00</published><updated>2012-01-11T10:40:46.832-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rant'/><category scheme='http://www.blogger.com/atom/ns#' term='shopping'/><title type='text'>"Did the HTTP Headers tell you about Comcast?"</title><content type='html'>There's some buzz about an article in Forbes called &lt;a href="http://www.forbes.com/sites/larrydownes/2012/01/02/why-best-buy-is-going-out-of-business-gradually/"&gt;"Why Best Buy is Going out of Business ... Gradually"&lt;/a&gt; (and the &lt;a href="http://www.forbes.com/sites/larrydownes/2012/01/09/the-people-vs-best-buy-round-two/1/"&gt;followup&lt;/a&gt;) about how specific decisions (such as training their workforce to talk to people about buying other stuff, not knowing what's in the store) is hurting their customer relations. Long article, go read.&lt;br /&gt;&lt;br /&gt;Part of it is telling the story of a trip to Best Buy, looking for &lt;i&gt;How To Train Your Dragon&lt;/i&gt; in 3D, when a sales person with no knowledge of Blu-Ray placement came up and tried to push him onto another cable system. I've come to expect that when I walk into Best Buy. It doesn't deter me from shopping at Best Buy yet, the way that the old-school, "ask for a page of personal information for a $2 cash purchase" kept me from shopping at Radio Shack for over 15 years, but it is annoying.&lt;br /&gt;&lt;br /&gt;I went to Menards yesterday. I had three things I was looking for: stuff I saw on Make or Lifehacker or something where you dip the handles of your tools to get a comfortable and insulated grip (called &lt;a href="http://www.plastidip.com/"&gt;Plasti Dip&lt;/a&gt; and to be found in the the same aisle as the Leathermen), cheap masking tape and Dremel tools I could use to recess the bottom of my son's Pinewood Derby car so the weights don't drag on the track. What I &lt;i&gt;did not want&lt;/i&gt; is a young woman to try to sell me on Comcast. In my apartment complex, I have the choice between DishTV and cable-cutting, anyway, so I'm not the market anyway. &lt;br /&gt;&lt;br /&gt;First guy I talked to didn't know about Plasti Dip, so he called a co-worker who directed me right to it. I don't count that as a customer service fail at all. What I do count as a fail is the free-range Comcast girl interrupting my tool-hunting experience, for two reasons. First, when men shop, they are expected to know what they want and where it is, or at least use the game-seeking sections of his brain to scope out the environment and find it. It's a hunt. There are people there whose job it is to maintain the game preserve and point out where to find the beast. The shopper respects the worker by interrupting him only after looking for himself first, and the worker respects the shopper by being available to ask questions but not forcing an interaction before the hunt has finished. That is the male way of shopping, and the Comcast girl breaks that.&lt;br /&gt;&lt;br /&gt;Second, cable TV connects to home electronics via a coaxial connection in the back of the unit. It's more than a natural fit, it's an engineered fit. &lt;i&gt;You're looking at big HD TVs? You'll want something to watch on it, and man, I have just the thing.&lt;/i&gt;&amp;nbsp;Cable TV is as much a fit for hardware stores as Legos or tampons: not much.&lt;br /&gt;&lt;br /&gt;I first heard of something like this in college: at the bar, a cute girl in a tight Jagermeister T-shirt comes up and asks if you've ever tried Jager, which you try because, hey, cute girl. Maybe there's even a Jager Face contest and she has a Polaroid camera (OK, think back to 1991 on this one, OK?) Suddenly, everyone you know drinks Jager shots and beer. I guess I don't mind it in the bar, in part because I don't do that anymore, but I increasingly mind it in the stores. I hope this is a dying trend.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-1293950108217793290?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/1293950108217793290/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=1293950108217793290' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/1293950108217793290'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/1293950108217793290'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2012/01/did-http-headers-tell-you-about-comcast.html' title='&quot;Did the HTTP Headers tell you about Comcast?&quot;'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-6898554216093551083</id><published>2012-01-06T12:30:00.002-05:00</published><updated>2012-01-06T12:30:55.910-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='philosophy'/><category scheme='http://www.blogger.com/atom/ns#' term='unix'/><category scheme='http://www.blogger.com/atom/ns#' term='history'/><category scheme='http://www.blogger.com/atom/ns#' term='shell'/><title type='text'>My Song of Love for Unix</title><content type='html'>&lt;div&gt;&lt;iframe allowfullscreen="" frameborder="0" height="360" src="http://www.youtube.com/embed/VaDsgcPyC0Y" width="480"&gt;&lt;/iframe&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;My first computer was a DOS-running TRS-80 in the 1980s. In 1988, when I was heading off to college, my parents got me a Tandy PC with an 8088 processor and a green monochrome monitor that took a composite video cable. I still have it but I don't use it. The only modification I did on it was to add a modem (2400 baud, I think, but maybe 1200 baud) and I mostly used it to connect to BBSes and mostly to the campus' big machine, MUSIC (Multi-User System for Interactive Computing). I know I touched some GNU tools for DOS at the time, and I heard about UNIX systems and felt an awe about them that I don't think it's possible to express these days, when you can download Linux for free and all of Apple's computers run BSD, but I never got close to a real UNIX system back then.&lt;br /&gt;&lt;br /&gt;In fact, the first I really touched a Unix system was when I went to school again, to get my Computer Science degree. I learned C as a subset of C++ on SunOS systems, and I have to say that I was somewhat underwhelmed with Unix. X looked positively crufty compared to Windows 95, much less MacOS, even in 1996. What I didn't get, what it took me a while to get, is that the windows don't really matter. Once you get into the Unix mindset, CDE is KDE is Gnome is Windows is MacOS. The way windowing doesn't matter, and what does matter is the command line.&lt;br /&gt;&lt;br /&gt;And why is that? Windows has CMD and now Powershell, and Macs could be coerced to give you a prompt even back then, even if few people used them. What makes Unix systems different? In a word, pipes.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;Pipes?&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;So, you have an MP3 of a song, somewhere in your music collection. For example, "Never Ending Love" by Delaney and Bonnie. You don't know where it is and you want to copy it to your phone. So, first you have to go through your music collection.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;find Music/. &lt;/code&gt;&lt;br /&gt;&lt;br /&gt;That gives you a big list of all your music. tl;dr&lt;br /&gt;&lt;br /&gt;&lt;code&gt;find Music/. | grep -i delaney &lt;/code&gt;&lt;br /&gt;&lt;br /&gt;OK, so, that gives you the whole album, plus "Delaney's Dream" by Seth Austin, too.&lt;br /&gt;&lt;br /&gt;&lt;code&gt; find Music/. | grep -i delaney | grep -i "never ending" &lt;/code&gt;&lt;br /&gt;&lt;br /&gt;And, if your music collection is mine, that cuts it down to two. And a great many other problems can be broken down in similar ways.&lt;br /&gt;&lt;br /&gt;It gets deeper, but in essence, the command line, the basic way you connect with a machine, is a programming language in and of itself. You write small things that filter the information, learn the flags to control the output of the tools, and only display it when it is down to what you need to see. To the extent it is possible to script a windowing system, it is a cast-iron &lt;i&gt;PITA&lt;/i&gt;. When you want to script things in the command line, it is baked in at a fundamental level.&lt;br /&gt;&lt;br /&gt;So, if someone suggests you learn Unix, yeah, it's great to run Ubuntu and get the Unity shell (the current term for window manager, I guess), but you'll either be using things that are ported to all the platforms (Chrome, Firefox, Komodo Edit, in my case), things that are equivalent to things on other platforms (Nautilus vs Windows Explorer, for example) or things that are hoped to be equivalent to things on other platforms but just aren't (GIMP vs Photoshop). &lt;a href="http://xkcd.com/934/"&gt;This makes Mac vs PC vs Linux largely a matter of taste&lt;/a&gt;, but the command line, or shell, is the thing that makes Unix different, that makes it powerful, which makes it powerful and user-friendly to those who it excepts as users.&lt;br /&gt;&lt;br /&gt;Yes, I have just largely restated Neal Stephenson's &lt;a href="http://www.cryptonomicon.com/beginning.html"&gt;"In the Beginning was the Command Line"&lt;/a&gt;. I still enjoyed the trip, and hope you did too.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-6898554216093551083?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/6898554216093551083/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=6898554216093551083' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/6898554216093551083'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/6898554216093551083'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2012/01/my-song-of-love-for-unix.html' title='My Song of Love for Unix'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://img.youtube.com/vi/VaDsgcPyC0Y/default.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-1019386060380321080</id><published>2012-01-01T15:39:00.001-05:00</published><updated>2012-01-01T15:39:19.570-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rant'/><category scheme='http://www.blogger.com/atom/ns#' term='information'/><title type='text'>Information Diet Commentary, or Sniping At An Idea I Have Some Sympathy For</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-Xzp_5NCIx-8/TwDD61w_uQI/AAAAAAAACuE/cqZlggOysHg/s1600/harmony-200-remote-emea-glamour-images.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" height="320" src="http://1.bp.blogspot.com/-Xzp_5NCIx-8/TwDD61w_uQI/AAAAAAAACuE/cqZlggOysHg/s320/harmony-200-remote-emea-glamour-images.png" width="291" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;I hit an idea on my Google+ feed about &lt;i&gt;Information Diet&lt;/i&gt;. &lt;a href="https://plus.google.com/u/0/107033731246200681024/posts/fd5DAQ4bY3p"&gt;This has been presented as a summation of the concept&lt;/a&gt;:&lt;/div&gt;&lt;blockquote&gt;#1 Productivity Tip: Spend 10% of your time consuming and 90% of your time producing. Make more stuff. Watch less. Read less. Do.&lt;/blockquote&gt;&lt;div&gt;Really, this is hard to argue with, but hard to follow, as Tim O'Reilly said.&lt;br /&gt;&lt;br /&gt;So, I go around looking at more. While I think the author of &lt;i&gt;Information Diet&lt;/i&gt; and I probably wildly disagree on key points of ideology, I would guess that I could find lots of points of commonality. I'll have to do some reading to decide that.&lt;br /&gt;&lt;br /&gt;But I found something else that &lt;a href="http://scienceblogs.com/sciencepunk/2011/11/the_information_diet_-_do_brai.php"&gt;I strongly and intensely disagree with&lt;/a&gt;.&amp;nbsp;&lt;/div&gt;&lt;blockquote&gt;&lt;b&gt;#2 Decentralise your media consumption &lt;/b&gt;This is a bit of a heretical idea too - technology is geared towards central entertainment systems for our homes. But you know what? They are hateful, terrible devices. Ten years ago, if I'd wanted to listen to music, my flow chart would have looked like this:&lt;br /&gt;&lt;div&gt;&lt;code&gt;SWITCH ON STEREO &amp;gt; INSERT CD &amp;gt; PRESS PLAY&lt;/code&gt;&lt;/div&gt;Now it looks something like this&lt;br /&gt;&lt;div&gt;&lt;code&gt;SWITCH ON PC &amp;gt; WAIT TO BOOT &amp;gt; LOG IN &amp;gt; MORE BOOTING &amp;gt; UPDATES START ROLLING &amp;gt; CLICK ON ITUNES &amp;gt; WAIT SEVERAL MINUTES WHILE IT BOOTS &amp;gt; GET BORED, OPEN EMAIL/BROWSER &amp;gt; ITUNES UPDATE REQUIRED &amp;gt; START DOWNLOAD &amp;gt; START CLICKING ON FEEDS &amp;gt; ITUNES UPDATE DOWNLOADED &amp;gt; INSTALLING &amp;gt; RESTARTING ITUNES, MORE WAITING &amp;gt; ITUNES OPEN &amp;gt; ! WINDOWS UPDATE FINISHED, MANDATORY REBOOT...&lt;/code&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;Funny, in 2001 and before, my process for listening to music, more often than not, was: &lt;/div&gt;&lt;div&gt;&lt;code&gt; OPEN WINAMP &amp;gt; CHOOSE A SONG  &amp;gt; PRESS PLAY &lt;/code&gt;&lt;/div&gt;I was and still am a computer guy at that time, and because I was coding and otherwise working on the PC, my stuff is by and large already updated to current versions. If the "now" case from Sciencepunk is &lt;i&gt;every single time&lt;/i&gt;, iTunes must &lt;b&gt;suck&lt;/b&gt;. But yeah, for the last 10 years, my CDs would get ripped and filed almost immediately, and I would listen to the original media rarely.Let me contrast it with my listening to a CD in 2001:&lt;br /&gt;&lt;div&gt;&lt;code&gt; EITHER GO TO MY WALL OF CDS (HOME) OR MY SMALL MOBILE COLLECTION &amp;gt; LOOK FOR CD &amp;gt; LOOK AGAIN BECAUSE WITH THAT MANY CDS, YOU NEVER FIND IT ON FIRST ATTEMPT &amp;gt; IF FOUND, INSERT CD AND PRESS PLAY, ELSE FAIL &lt;/code&gt;&lt;/div&gt;And things like Google Music and Spotify make this much much easier. And never ends in fail.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-1019386060380321080?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/1019386060380321080/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=1019386060380321080' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/1019386060380321080'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/1019386060380321080'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2012/01/information-diet-commentary-or-sniping.html' title='Information Diet Commentary, or Sniping At An Idea I Have Some Sympathy For'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-Xzp_5NCIx-8/TwDD61w_uQI/AAAAAAAACuE/cqZlggOysHg/s72-c/harmony-200-remote-emea-glamour-images.png' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-1351713524519835833</id><published>2011-12-16T23:21:00.001-05:00</published><updated>2011-12-16T23:45:40.501-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>In Praise of Night-Hacking, or at least in hopes to understand</title><content type='html'>&lt;table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; margin-left: 1em; text-align: right;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-rlc7kUdR2ag/TuwWeL5l9bI/AAAAAAAACk8/jTSaymxVxUI/s1600/256310347_7135d8219b_b.jpg" imageanchor="1" style="clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="320" src="http://4.bp.blogspot.com/-rlc7kUdR2ag/TuwWeL5l9bI/AAAAAAAACk8/jTSaymxVxUI/s320/256310347_7135d8219b_b.jpg" width="240" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Photo credit:&amp;nbsp;&lt;a href="http://www.flickr.com/photos/pantulis/256310347/"&gt;pantulis&lt;/a&gt;&amp;nbsp;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;div&gt;I code every day. It's what I do, and I'm thankful. But there is a problem with coding from 9am to 5pm.&lt;br /&gt;&lt;br /&gt;Other people.&lt;br /&gt;&lt;br /&gt;Yeah, you're coding for their benefit, and it is well and good and helpful (and secretly, an ego boost at times when you otherwise feel humbled by the tasks in front of you) to serve as tech support for other people, even when and sometimes especially when &lt;a href="http://www.youtube.com/watch?v=5eCdIe0wdvU"&gt;the task seems otherwise mundane to you&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;But, when you have all that state in your head, the last thing you want to do is fix someone else's thing. It has had me nearly to tears before. When there's nobody else around, you don't have to worry about the house of cards you have in your head. That's when you can relax and get into it, man. You know, like a coding machine?&lt;br /&gt;&lt;br /&gt;But that's not it. Or at least not all of it.&lt;br /&gt;&lt;br /&gt;At least what &lt;a href="http://swizec.com/blog/"&gt;a geek with a hat&lt;/a&gt;&amp;nbsp;has to say. &lt;a href="http://swizec.com/blog/why-programmers-work-at-night/swizec/3198"&gt;In&amp;nbsp;essence&lt;/a&gt;, when you're tired, parts of your brain shut down, and those can be the &lt;a href="http://www.youtube.com/watch?v=bBWrMQVsuak"&gt;"squirrel!"&lt;/a&gt;&amp;nbsp;aspects that get in the way of the deep concentration you need to build, understand and modify the house of data cards in your head. And, with your focus and the lights of the computer screen, you can keep going until you drop off, and when you do, it's the deep, relaxing sleep that exhaustion brings, not the light, brittle sleep sometimes broken by insomnia you get when you're sleeping because it's time. (I once heard a professor opine that humans were really built for 25-hour days. I do believe that some.)&lt;br /&gt;&lt;br /&gt;A big problem is, of course, that if your life doesn't live on hacker's hours, parts of your life fall away when &lt;i&gt;you&lt;/i&gt; start living on hackers hours. Something to sleep on, so to speak.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-1351713524519835833?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/1351713524519835833/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=1351713524519835833' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/1351713524519835833'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/1351713524519835833'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2011/12/in-praise-of-night-hacking-or-at-least.html' title='In Praise of Night-Hacking, or at least in hopes to understand'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-rlc7kUdR2ag/TuwWeL5l9bI/AAAAAAAACk8/jTSaymxVxUI/s72-c/256310347_7135d8219b_b.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-1210663111192832853</id><published>2011-12-15T09:55:00.003-05:00</published><updated>2011-12-15T09:55:52.105-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='debugging'/><category scheme='http://www.blogger.com/atom/ns#' term='perl'/><title type='text'>Can You Identify The Bug?</title><content type='html'>&lt;pre class="perl" name="code"&gt;#!/usr/bin/perl&lt;br /&gt;# 2g_run_reversal.pl&lt;br /&gt;&lt;br /&gt;use 5.010 ;&lt;br /&gt;use strict ;&lt;br /&gt;use warnings ;&lt;br /&gt;use Carp ;&lt;br /&gt;use Data::Dumper ;&lt;br /&gt;use Getopt::Long ;&lt;br /&gt;use Pod::Usage ;&lt;br /&gt;&lt;br /&gt;use lib '/home/ltl/lib' ;&lt;br /&gt;use SecGenTools::Run 'get_run_data' ;&lt;br /&gt;use SecGenTools::Accession 'get_accession_data' ;&lt;br /&gt;use SecGenTools::Request 'get_request_data' ;&lt;br /&gt;&lt;br /&gt;my $config      = config() ;&lt;br /&gt;my $run_stub    = get_run_data( $config-&amp;gt;{ run_id } ) ;&lt;br /&gt;my $run         = $run_stub-&amp;gt;{ $config-&amp;gt;{ run_id } } ;&lt;br /&gt;my $run_samples = get_run_sample( $config-&amp;gt;{ run_id } ) ;&lt;br /&gt;my %conversion =&lt;br /&gt;    map { $_, $run-&amp;gt;{ max_regions } + 1 - $_ } 1 .. $run-&amp;gt;{ max_regions } ;&lt;br /&gt;&lt;br /&gt;for my $region ( 1 .. $run-&amp;gt;{ max_regions } ) {&lt;br /&gt;   my $conversion = $conversion{ $region } ;&lt;br /&gt;   for my $sample_id ( sort keys %$run_samples ) {&lt;br /&gt;       my $sample = $run_samples-&amp;gt;{ $sample_id } ;&lt;br /&gt;       next if $sample-&amp;gt;{ region } != $region ;&lt;br /&gt;       $sample-&amp;gt;{ region } = $conversion ;&lt;br /&gt;       update_run_sample( $sample ) ;&lt;br /&gt;       say join "\n\t" , $sample_id ,&lt;br /&gt;           $sample-&amp;gt;{ accession_id } ,&lt;br /&gt;           $region ,&lt;br /&gt;           $conversion ,&lt;br /&gt;           ;&lt;br /&gt;       }&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;exit 1 ;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This is the core of the code. &lt;code&gt;config()&lt;/code&gt; puts all the configuration options into a hash and returns it. &lt;code&gt;get_run_data()&lt;/code&gt;, &lt;code&gt;get_request_data()&lt;/code&gt;, and&lt;code&gt;get_accession_data()&lt;/code&gt;, are wrappers around database calls.&lt;br /&gt;&lt;br /&gt;An &lt;i&gt;accession &lt;/i&gt;is an individual sample to be analyzed. A &lt;i&gt;request &lt;/i&gt;is one or more accessions. A &lt;i&gt;run &lt;/i&gt;is one or more requests, assigning the accessions to one of the &lt;i&gt;regions&lt;/i&gt;. And, because this is a mapping between a data structure and a physical object, it is possible for the user to start at the wrong end. This program is supposed to take all the requests and reverse the regions. That is, for an 8-region run, all the accessions in region 1 should be in region 8 and vice versa.&lt;br /&gt;&lt;br /&gt;This code puts everything in regions 1-4. It took me a morning to figure out why, although part of that was restoring the database to the way it was before.&lt;br /&gt;&lt;br /&gt;It took me a while to get it, so stop here if you're still looking.&lt;br /&gt;&lt;br /&gt;In a word, persistence.&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;$sample&lt;/code&gt; is a reference to the data in &lt;code&gt;$run_samples&lt;/code&gt;. In my mind, &lt;code&gt;my $sample = $run_samples-&amp;gt;{ $sample_id } &lt;/code&gt; made a local copy, but it didn't. That meant that, when the code hits region 5, it works on the accessions just moved over from region 4, too, and so on.&lt;br /&gt;&lt;br /&gt;And, in working around that, I decided that looping on region was useless except to massage the retentive control freak in me, and once I convinced myself of that, things got better. So, like the Monster at the End of the Book, the bug is me.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-1210663111192832853?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/1210663111192832853/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=1210663111192832853' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/1210663111192832853'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/1210663111192832853'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2011/12/can-you-identify-bug.html' title='Can You Identify The Bug?'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-8647245192443677297</id><published>2011-12-07T00:15:00.001-05:00</published><updated>2011-12-07T07:42:40.494-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='various and sundry'/><title type='text'>Lots of Small Rants</title><content type='html'>I got three things on Black Friday, and the first one shouldn't even count. It's the e-book version of &lt;a href="http://shop.oreilly.com/product/0636920010364.do"&gt;Programming Android&lt;/a&gt;&amp;nbsp;from O'Reilly. Time was, when I had a technical question, O'Reilly books were the first place I'd look, but now, my first checks are Google and StackOverflow, so this is a bit of a nostalgia move, but &amp;nbsp; &amp;nbsp;there's enough of a blank spot in my mind to justify it. Now, just to spend some time and generate something.&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-ACHq86MzJxw/Tt7MH4iPuqI/AAAAAAAACa8/O2kcwxymkY8/s1600/IMAG0649.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" height="320" src="http://3.bp.blogspot.com/-ACHq86MzJxw/Tt7MH4iPuqI/AAAAAAAACa8/O2kcwxymkY8/s320/IMAG0649.jpg" width="191" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;The other two are cheap pieces of USB hardware from Newegg. The first is a USB Wifi dongle (shown right), or, as it reads, "802.11b b/g/n Wireless Adatper". I have to say, I like it better so far than the Netgear that has been going back and forth between a few Windows boxes I have. Plus, I like the form. It's nice and small.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The other is also an inexpensive piece of Rosewill kit, a USB dongle connecting to a remote to Windows Media Center. Right now, it's nonsensically connected to the laptop I'm writing this on, but I could easily see myself liking this. I have a wireless Logitech keyboard with gone-AWOL mouse and don't do much with whatever PC I have in the bedroom for lack of pointer, and while I have been using Boxee for bedroom media PC duties, I could see myself accepting Windows Media Center due to this one. Problem is, the PC I needed the USB dongle for is the the same one I needed the remote for, and because it's been repurposed from HTPC to desktop, as long as I need the WiFi dongle, I do not need the remote and vice versa.&lt;br /&gt;&lt;br /&gt;I've been doing more with git, as previously mentioned today, and I think have hit the distinction for bare repositories. This has been kicking to most of the day, and it's a bit of duh I just had to work through to get this into my head. I've been making non-bare repositories and wanting them to behave like bare repositories, then tearing my hair out. I'll have to work out aliases or scripts for this stuff.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-8647245192443677297?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/8647245192443677297/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=8647245192443677297' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/8647245192443677297'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/8647245192443677297'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2011/12/lots-of-small-rants.html' title='Lots of Small Rants'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-ACHq86MzJxw/Tt7MH4iPuqI/AAAAAAAACa8/O2kcwxymkY8/s72-c/IMAG0649.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-8497029307401266494</id><published>2011-12-06T11:34:00.001-05:00</published><updated>2011-12-06T12:35:46.032-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='book review'/><category scheme='http://www.blogger.com/atom/ns#' term='version control'/><category scheme='http://www.blogger.com/atom/ns#' term='git'/><title type='text'>Book Review - Version Control by Example, or "Thank you, @eric_sink"</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-lzPePnVCHz8/Tt5ArEiYUxI/AAAAAAAACaw/DFY43jl8bmw/s1600/IMAG0648.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="400" src="http://3.bp.blogspot.com/-lzPePnVCHz8/Tt5ArEiYUxI/AAAAAAAACaw/DFY43jl8bmw/s400/IMAG0648.jpg" width="238" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;For too long, I've worked in environments without version control. There's been backups, either real or virtual, and for the web part there's the Google cache (which saved by butt once as the webmaster for my LUG) but version control has always been something that I know I &lt;i&gt;should&lt;/i&gt;&amp;nbsp;be doing, but we've never done. (The one exception was doing temp work at the car parts company. There, we used code reviews and Synergy. Not the good &lt;a href="http://synergy-foss.org/"&gt;Synergy&lt;/a&gt;, which gives you the ability use one keyboard and mouse across several computers in software, but the bad one, the ancient, slow and ponderous &lt;a href="http://en.wikipedia.org/wiki/Telelogic_Synergy"&gt;configuration management system&lt;/a&gt;, which is similar enough to version control that I cannot express the distinction.&lt;br /&gt;&lt;br /&gt;So, here's something where I know I should be doing it, but I don't really know how to do it. I've heard enough about Git and have signed up with &lt;a href="https://github.com/"&gt;Github&lt;/a&gt;, which put it before Subversion and CVS and the rest of the choices. But, unfortunately, I hadn't heard enough about Git to really know what the heck I should be doing with it.&lt;br /&gt;&lt;br /&gt;Then I saw a post by my internet friend &lt;a href="http://www.funnelfiasco.com/"&gt;Funnel Fiasco&lt;/a&gt;&amp;nbsp;about &lt;a href="http://www.ericsink.com/vcbe/index.html"&gt;Version Control by Example&lt;/a&gt; by &lt;a href="http://www.ericsink.com/"&gt;Eric Sink&lt;/a&gt;, saying how good it was. And, as it turns out, Eric is much more about teaching people about how to not do stupid things than he is about sales, so you can download digital copies, &lt;a href="http://www.ericsink.com/vcbe/html/index.html"&gt;browse through online&lt;/a&gt;, and &lt;a href="http://www.ericsink.com/entries/vcbe_print_edition_free.html"&gt;he'll even send you a copy free&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I've had it in my bag for several months without cracking it open, which was stupid of me. Right now, I'm in a decent place at work, with little sitting with a tight deadline, so I have time to go through the book and start &amp;nbsp;actually learning from it, and &lt;i&gt;wow!&lt;/i&gt; I'm getting it! It makes sense. The core of the book is the same examples expressed in Subversion, Mercurial, Veracity and Git, so it serves as a Rosetta Stone, too, so if you know one, you have a step toward using the others if that's what your workplace or project uses.&lt;br /&gt;&lt;br /&gt;Thank you, &lt;a href="http://twitter.com/#!/eric_sink"&gt;Eric Sink!&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-8497029307401266494?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/8497029307401266494/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=8497029307401266494' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/8497029307401266494'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/8497029307401266494'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2011/12/book-review-version-control-by-example.html' title='Book Review - Version Control by Example, or &quot;Thank you, @eric_sink&quot;'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-lzPePnVCHz8/Tt5ArEiYUxI/AAAAAAAACaw/DFY43jl8bmw/s72-c/IMAG0648.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-2879056671104207691</id><published>2011-12-05T13:13:00.001-05:00</published><updated>2011-12-05T13:14:07.164-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='git'/><category scheme='http://www.blogger.com/atom/ns#' term='github'/><category scheme='http://www.blogger.com/atom/ns#' term='code'/><title type='text'>Speaking of git</title><content type='html'>mount.pl, my script for automating the mounting and unmounting of remote file systems via sshfs, &lt;a href="https://github.com/jacoby/mount.pl"&gt;is now on github&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-2879056671104207691?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/2879056671104207691/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=2879056671104207691' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/2879056671104207691'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/2879056671104207691'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2011/12/speaking-of-git.html' title='Speaking of git'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-2763616431987357577</id><published>2011-12-05T11:20:00.001-05:00</published><updated>2011-12-05T13:11:40.148-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='version control'/><title type='text'>Questions about Git</title><content type='html'>I'm reading Eric Sink's &lt;i&gt;Version Control By Example&lt;/i&gt;, starting to hit the examples, and I'm finding that to be a bit of a problem.&lt;br /&gt;&lt;br /&gt;Eric's example is one dev in Birmingham, UK and one in Birmingham, AL, writing C code and committing to a server in Cleveland. Right now, the dev team for my office are two coders separated by all of five feet, writing Perl code for one of two servers, one being the web server. I'm easing in to git, as you might guess by the reading material, and like most working environments I've been in, our version control system has been "copy a backup before you muck with the file", which I know is dumb and useless (especially in the lab, where we rely on RAID for data protection and thus don't really have backups). I'm kinda taking the lead on this, having been burned enough to want to protect myself, but I don't really know much of it.&lt;br /&gt;&lt;br /&gt;I've been using git so far to keep track of changes locally, just doing git init and git commit within the local file system. Is this enough? Or do we really, truly need a server?&lt;br /&gt;&lt;br /&gt;And the code sits in &lt;code&gt;/home/user/web/cgi-bin/foo/bar/blee/quuz.cgi&lt;/code&gt; or &lt;code&gt;/home/user/bin/hoge.pl&lt;/code&gt;, I'm wondering: should I have those be the directories to run git in? Or should I do the work in &lt;code&gt;/home/varlogrant/dev/hoge.pl/&lt;/code&gt; and copy hoge.pl over to /home/usr/bin when I'm happy with it and it has been committed?&lt;br /&gt;&lt;br /&gt;I have a bigger question on how to take a large selection of interconnected Perl modules and make them 1) test driven in the real, chromatic-approved way, 2) working with git in a useful way, and 3) usable from &lt;code&gt;~/lib&lt;/code&gt; on several dissimilar systems. I have a cheap hack on #3, but if I break apart and reassemble the modules, I can probably do it cleaner and smarter.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-2763616431987357577?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/2763616431987357577/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=2763616431987357577' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/2763616431987357577'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/2763616431987357577'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2011/12/questions-about-git.html' title='Questions about Git'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-5401843798345169305</id><published>2011-12-02T11:54:00.001-05:00</published><updated>2011-12-06T11:33:30.144-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='bash'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>'cat' considered not useless</title><content type='html'>Consider this:&lt;br /&gt;&lt;pre class="perl" name="code"&gt;cat /path/to/my/file.log |&lt;br /&gt;grep filter |&lt;br /&gt;sed 'something, I don't really use sed a lot' |&lt;br /&gt;grep filter_again |&lt;br /&gt;lp&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Many would write this off as "useless use of cat". I don't think so. I mean, functionally, sure. But it isn't all functional.&lt;br /&gt;&lt;pre class="perl" name="code"&gt;cat /path/to/my/file.log | # read data from file&lt;br /&gt;grep filter |              # run a filter on file contents&lt;br /&gt;sed 'something, I don't really use sed a lot' | #change file contents&lt;br /&gt;grep filter_again |        # run another filter on contents&lt;br /&gt;lp                         # send to printer&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Compare to this:&lt;br /&gt;&lt;pre class="perl" name="code"&gt;grep filter cat |          # read data from file AND run a filter on file contents&lt;br /&gt;sed 'something, I don't really use sed a lot' | #change file contents&lt;br /&gt;grep filter_again |        # run another filter on contents&lt;br /&gt;lp                         # send to printer&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;You have now overloaded grep and if you want to remove it, you now have more editing than reading a line.&lt;br /&gt;&lt;br /&gt;Friend of the blog Patrick says that this use of cat is just as useless as comments. I tend to agree.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-5401843798345169305?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/5401843798345169305/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=5401843798345169305' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/5401843798345169305'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/5401843798345169305'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2011/12/cat-considered-not-useless.html' title='&apos;cat&apos; considered not useless'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-8909456060574964814</id><published>2011-12-01T13:33:00.001-05:00</published><updated>2011-12-01T13:43:16.872-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cellphones'/><category scheme='http://www.blogger.com/atom/ns#' term='security'/><title type='text'>You Do Not Own Your Phone</title><content type='html'>&lt;iframe width="480" height="360" src="http://www.youtube.com/embed/T17XQI_AYNo" frameborder="0" allowfullscreen&gt;&lt;/iframe&gt;That is, unless you root it. Thank you Trevor Eckhart, and no thank you Carrier IQ.And &lt;a href="http://www.forbes.com/sites/andygreenberg/2011/11/30/phone-rootkit-carrier-iq-may-have-violated-wiretap-law-in-millions-of-cases/"&gt;Forbes reports that this could mean millions of violations of wiretap law.&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-8909456060574964814?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/8909456060574964814/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=8909456060574964814' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/8909456060574964814'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/8909456060574964814'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2011/12/you-do-not-own-your-phone.html' title='You Do Not Own Your Phone'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://img.youtube.com/vi/T17XQI_AYNo/default.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-3151704169691546790</id><published>2011-11-28T09:46:00.001-05:00</published><updated>2011-11-28T11:36:44.277-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='system administration'/><category scheme='http://www.blogger.com/atom/ns#' term='fuse'/><category scheme='http://www.blogger.com/atom/ns#' term='hacks'/><category scheme='http://www.blogger.com/atom/ns#' term='sshfs'/><category scheme='http://www.blogger.com/atom/ns#' term='frustration'/><title type='text'>Improving my SSHFS script</title><content type='html'>I can name more than a dozen machines whose file systems I would want to mount from work. I don't mount those file systems all the time, but I do often enough that I have a Perl script I use to manage my SSHFS mounting and unmounting of them.&lt;br /&gt;&lt;br /&gt;Here's a problem. This weekend, the servers for work were taken down for scheduled maintenance. That's fine, but it does mean that I had to remount a bunch of them this AM, and when the script went through the already-mounted filesystems, it would ask for a password and say "this is already mounted". What I probably want is some way of knowing quickly whether there's something mounted and then doing that check before I do the mount.&lt;br /&gt;&lt;br /&gt;And this is what initially draws my attention: mount points are directories. And directories can contain files. It is a known trick for hackers to unmount shares, hide files in the mount point, and remount, where sysadmins won't notice it. It strikes me that I can touch a file like .unmounted into each mount point, and then look for that file on each remounting, and skip it if I can't -f that file.&lt;br /&gt;&lt;br /&gt;But really, this has to be a solved problem somehow, so there might be a better way. Pointers?&lt;br /&gt;&lt;br /&gt;&lt;b&gt;ETA:&lt;/b&gt;&amp;nbsp;The code, a few revisions back, is part of &lt;a href="http://varlogrant.blogspot.com/2008/12/useful-test.html"&gt;a previous post&lt;/a&gt;. A twitter response is leading me to start the process of finally using my github account and setting it up there. Will add again when I get to there.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-3151704169691546790?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/3151704169691546790/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=3151704169691546790' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/3151704169691546790'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/3151704169691546790'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2011/11/improving-my-sshfs-script.html' title='Improving my SSHFS script'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-1159176797930336699</id><published>2011-11-16T13:02:00.001-05:00</published><updated>2011-11-16T14:06:10.725-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='np'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='perl'/><title type='text'>I've Been Doin' Some Hard-Travelin', I Thought You Knowed</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://maps.google.com/maps/api/staticmap?path=color:0xff0000ff|weight:1|33.448456,-112.073845|47.042419,-122.893074|44.931110,-123.029160|38.555607,-121.468925|39.160950,-119.753876|40.754700,-111.892624|43.613739,-116.237648|46.595806,-112.027031|48.813343,-100.779007|44.367966,-100.336380|41.145550,-104.802040|39.739166,-104.984169|35.667233,-105.964577|30.266666,-97.750000|35.482307,-97.534996|39.040001,-95.690002|40.809868,-96.675346|41.590939,-93.620865|44.950001,-93.094002|43.074722,-89.384445|42.733501,-84.546700|39.962246,-83.000648|38.349499,-81.633293|38.197273,-84.863113|36.165001,-86.783997|39.790943,-86.147682|39.783249,-89.650375|38.572952,-92.189285|34.736008,-92.331123|32.320000,-90.207001|30.458090,-91.140228|32.361538,-86.279121|30.451799,-84.272774|33.759998,-84.389999|34.000000,-81.035004|35.771000,-78.638000|37.540001,-77.459999|38.972946,-76.501160|39.161922,-75.526756|40.269791,-76.875610|40.221741,-74.756142|42.659828,-73.781342|44.266392,-72.571938|41.766998,-72.677002|41.823551,-71.422134|42.235199,-71.027496|43.220093,-71.549126|44.323536,-69.765259&amp;amp;size=500x400&amp;amp;sensor=false" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://maps.google.com/maps/api/staticmap?path=color:0xff0000ff|weight:1|33.448456,-112.073845|47.042419,-122.893074|44.931110,-123.029160|38.555607,-121.468925|39.160950,-119.753876|40.754700,-111.892624|43.613739,-116.237648|46.595806,-112.027031|48.813343,-100.779007|44.367966,-100.336380|41.145550,-104.802040|39.739166,-104.984169|35.667233,-105.964577|30.266666,-97.750000|35.482307,-97.534996|39.040001,-95.690002|40.809868,-96.675346|41.590939,-93.620865|44.950001,-93.094002|43.074722,-89.384445|42.733501,-84.546700|39.962246,-83.000648|38.349499,-81.633293|38.197273,-84.863113|36.165001,-86.783997|39.790943,-86.147682|39.783249,-89.650375|38.572952,-92.189285|34.736008,-92.331123|32.320000,-90.207001|30.458090,-91.140228|32.361538,-86.279121|30.451799,-84.272774|33.759998,-84.389999|34.000000,-81.035004|35.771000,-78.638000|37.540001,-77.459999|38.972946,-76.501160|39.161922,-75.526756|40.269791,-76.875610|40.221741,-74.756142|42.659828,-73.781342|44.266392,-72.571938|41.766998,-72.677002|41.823551,-71.422134|42.235199,-71.027496|43.220093,-71.549126|44.323536,-69.765259&amp;amp;size=500x400&amp;amp;sensor=false" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;Back to the &lt;a href="http://varlogrant.blogspot.com/2011/11/traveling-salesman-without-farmers.html"&gt;Traveling Salesman&lt;/a&gt;.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;What I had before was 11298 miles, using the shortest available path to an unconnected state capital, and it had problems, problems where the path already chosen forced a great amount of backtracking. &lt;i&gt;Knots&lt;/i&gt;, my friend Mark calls them. The knots are the thing that looked really wrong to me.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;So, I added another step.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;I modified&amp;nbsp;&lt;code&gt;choose_shortest_path()&lt;/code&gt; so that it returned an array with the path. I then do some substitutions. Take two capitals, switch their order, and if that gets us shorter, go with that. Not randomly. Iteratively. First those next to each other, then those separated by one, then by two, up to 5. Then again. Five times.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;This gets me to 10886 miles. So far. I'm doing it again, five times going from one to forty, just to see if we can get better than that, because the Washington-to-Arizona knot looks wrong to me, but that's a gut feeling, not a proven issue. That is a near-1100-mile leap, but using it seems to save me 412 miles, so it must work.&amp;nbsp;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;A CS professor once described NP-Complete problems as a license to hack, because there isn't an established best solution, you can play with it. This is a bit what I'm doing here. Certainly, this won't help you pack you knapsack, but if it helps you visit all the capitals that much faster, I'm happy.&lt;/div&gt;&lt;br /&gt;&lt;pre class="perl" name="code"&gt;#!/usr/bin/perl&lt;br /&gt;&lt;br /&gt;# naive shortest-path determination - A little better&lt;br /&gt;&lt;br /&gt;use 5.010 ;&lt;br /&gt;use strict ;&lt;br /&gt;use warnings ;&lt;br /&gt;use Data::Dumper ;&lt;br /&gt;use DBI ;&lt;br /&gt;&lt;br /&gt;use lib '/home/jacoby/lib' ;&lt;br /&gt;use MyDB 'db_connect' ;&lt;br /&gt;&lt;br /&gt;my $states    = get_states() ;&lt;br /&gt;my $combos    = get_combos() ;&lt;br /&gt;my $distances = get_distances() ;&lt;br /&gt;my %shortest ;&lt;br /&gt;&lt;br /&gt;#for my $start ( 1..48 ) {&lt;br /&gt;#    my $state = $states-&gt;{ $start }-&gt;{ state } ;&lt;br /&gt;#    my @path = choose_shortest_path( $start ) ;&lt;br /&gt;#    my $dist = find_distance( @path ) ;&lt;br /&gt;#    say join "\t", (sprintf '%02.2f' , $dist), $start, $state ;&lt;br /&gt;#    }&lt;br /&gt;#exit ;&lt;br /&gt;&lt;br /&gt;my @path = choose_shortest_path( 23 ) ;&lt;br /&gt;my $distance = find_distance( @path ) ;&lt;br /&gt;say $distance ;&lt;br /&gt;say as_google_url( separate_by_pipes( @path ) ) ;&lt;br /&gt;say '' ;&lt;br /&gt;&lt;br /&gt;my $path = \@path ;&lt;br /&gt;for my $pass ( 1 .. 5 ) {&lt;br /&gt;    for my $offset ( 1 .. 40 ) {&lt;br /&gt;        my $start = 0 ;&lt;br /&gt;        $path = massage_path( $start, $offset, $path ) ;&lt;br /&gt;        my $distance = find_distance( @$path ) ;&lt;br /&gt;        say join "\t", $pass , $offset, scalar @$path , $distance ;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;say as_google_url( separate_by_pipes( @$path ) ) ;&lt;br /&gt;say separate_by_pipes( @$path ) ;&lt;br /&gt;&lt;br /&gt;exit ;&lt;br /&gt;&lt;br /&gt;######## ######## ######## ######## ######## ######## ######## ########&lt;br /&gt;sub choose_shortest_path {&lt;br /&gt;    my @path = @_ ;&lt;br /&gt;    return @path if scalar @path == 48 ;&lt;br /&gt;    my $s_id    = shift @path ;&lt;br /&gt;    my $state   = $states-&gt;{ $s_id }-&gt;{ state } ;&lt;br /&gt;    my @choices = sort { #sort by distance&lt;br /&gt;        $distances-&gt;{ $a }-&gt;{ distance } &lt;=&gt; $distances-&gt;{ $b }-&gt;{ distance }&lt;br /&gt;        }&lt;br /&gt;        grep { # haven't been chosen yet&lt;br /&gt;                is_not_in_array( $combos-&gt;{ $_ }-&gt;{ state_id_1 }, \@path )&lt;br /&gt;            and is_not_in_array( $combos-&gt;{ $_ }-&gt;{ state_id_2 }, \@path )&lt;br /&gt;            }&lt;br /&gt;        grep { # must have the state current state&lt;br /&gt;               $combos-&gt;{ $_ }-&gt;{ state_id_1 } == $s_id&lt;br /&gt;            or $combos-&gt;{ $_ }-&gt;{ state_id_2 } == $s_id&lt;br /&gt;            } keys %$combos ;&lt;br /&gt;    my $c     = shift @choices ; #shortest&lt;br /&gt;    my $c_obj = $combos-&gt;{ $c } ;&lt;br /&gt;    my ( $o ) = grep { $_ != $s_id } $c_obj-&gt;{ state_id_1 },&lt;br /&gt;        $c_obj-&gt;{ state_id_2 } ;&lt;br /&gt;    my $o_state = $states-&gt;{ $o }-&gt;{ state } ;&lt;br /&gt;    my $d = $distances-&gt;{ $c }-&gt;{ distance } || 'x' ;&lt;br /&gt;    return choose_shortest_path( $o, $s_id, @path ) ;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;######## ######## ######## ######## ######## ######## ######## ########&lt;br /&gt;sub massage_path {&lt;br /&gt;    my ( $a, $offset, $path ) = @_ ;&lt;br /&gt;    my $b = $a + $offset ;&lt;br /&gt;    my $alt ;&lt;br /&gt;    @$alt = @$path ;&lt;br /&gt;    if ( $b &gt;= 48 ) { return $path ; }&lt;br /&gt;    $alt-&gt;[ $a ] = $path-&gt;[ $b ] ;&lt;br /&gt;    $alt-&gt;[ $b ] = $path-&gt;[ $a ] ;&lt;br /&gt;    my $d1 = find_distance( @$path ) ;&lt;br /&gt;    my $d2 = find_distance( @$alt ) ;&lt;br /&gt;    $path = $alt if $d2 &lt; $d1 ;&lt;br /&gt;    return massage_path( $a + 1, $offset, $path ) ;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;######## ######## ######## ######## ######## ######## ######## ########&lt;br /&gt;sub find_distance {&lt;br /&gt;    my @path     = @_ ;&lt;br /&gt;    my $distance = 0 ;&lt;br /&gt;    for my $i ( 1 .. 47 ) {&lt;br /&gt;        my ( $s1, $s2 ) = sort { $a &lt;=&gt; $b } $path[ $i ], $path[ $i - 1 ] ;&lt;br /&gt;        my ( $combo ) = grep {&lt;br /&gt;                   $combos-&gt;{ $_ }-&gt;{ state_id_1 } == $s1&lt;br /&gt;                &amp;&amp; $combos-&gt;{ $_ }-&gt;{ state_id_2 } == $s2&lt;br /&gt;                }&lt;br /&gt;            sort keys %$combos ;&lt;br /&gt;        $distance += $distances-&gt;{ $combo }-&gt;{ distance } ;&lt;br /&gt;        }&lt;br /&gt;    return sprintf '%0.02f', $distance ;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;######## ######## ######## ######## ######## ######## ######## ########&lt;br /&gt;sub is_not_in_array {&lt;br /&gt;    my ( $num, $path ) = @_ ;&lt;br /&gt;    for my $p ( @$path ) {&lt;br /&gt;        return 0 if $num == $p ;&lt;br /&gt;        }&lt;br /&gt;    return 1 ;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;######## ######## ######## ######## ######## ######## ######## ########&lt;br /&gt;sub get_states {&lt;br /&gt;    my $dbh    = db_connect() ;&lt;br /&gt;    my $sql    = 'SELECT * from state_capitals ORDER BY id' ;&lt;br /&gt;    my $states = $dbh-&gt;selectall_hashref( $sql, 'id' ) or croak $dbh-&gt;errstr ;&lt;br /&gt;    return $states ;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;######## ######## ######## ######## ######## ######## ######## ########&lt;br /&gt;sub get_combos {&lt;br /&gt;    my $dbh    = db_connect() ;&lt;br /&gt;    my $sql    = 'SELECT * from combinations ORDER BY id' ;&lt;br /&gt;    my $combos = $dbh-&gt;selectall_hashref( $sql, 'id' ) or croak $dbh-&gt;errstr ;&lt;br /&gt;    return $combos ;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;######## ######## ######## ######## ######## ######## ######## ########&lt;br /&gt;sub get_distances {&lt;br /&gt;    my $dbh    = db_connect() ;&lt;br /&gt;    my $sql    = 'SELECT * from distances ORDER BY id' ;&lt;br /&gt;    my $combos = $dbh-&gt;selectall_hashref( $sql, 'id' ) or croak $dbh-&gt;errstr ;&lt;br /&gt;    return $combos ;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;######## ######## ######## ######## ######## ######## ######## ########&lt;br /&gt;sub separate_by_pipes {&lt;br /&gt;    return join '|', @_ ;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;######## ######## ######## ######## ######## ######## ######## ########&lt;br /&gt;sub as_mark_list {&lt;br /&gt;    my ( $path ) = @_ ;&lt;br /&gt;    return join '', map { $states-&gt;{ $_ }-&gt;{ st } }&lt;br /&gt;        split m{\|}mx, $path ;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;######## ######## ######## ######## ######## ######## ######## ########&lt;br /&gt;sub as_google_url {&lt;br /&gt;    my ( $path ) = @_ ;&lt;br /&gt;    my $url1 =&lt;br /&gt;        'http://maps.google.com/maps/api/staticmap?path=color:0xff0000ff|weight:1|'&lt;br /&gt;        ;&lt;br /&gt;    my $url2 = '&amp;size=500x400&amp;sensor=false' ;&lt;br /&gt;    my $body = join '|', map {&lt;br /&gt;        join ',', $states-&gt;{ $_ }-&gt;{ latitude },&lt;br /&gt;            $states-&gt;{ $_ }-&gt;{ longitude }&lt;br /&gt;            }&lt;br /&gt;        split m{\|}mx, $path ;&lt;br /&gt;    return join '', $url1, $body, $url2 ;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;######## ######## ######## ######## ######## ######## ######## ########&lt;br /&gt;sub key_from_value {&lt;br /&gt;    my ( $v ) = @_ ;&lt;br /&gt;    my %rev = reverse %shortest ;&lt;br /&gt;    return $rev{ $v } ;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-1159176797930336699?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/1159176797930336699/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=1159176797930336699' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/1159176797930336699'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/1159176797930336699'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2011/11/ive-been-doin-some-hard-travelin-i.html' title='I&apos;ve Been Doin&apos; Some Hard-Travelin&apos;, I Thought You Knowed'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-7485788503482228567</id><published>2011-11-10T09:40:00.001-05:00</published><updated>2011-11-10T09:54:28.207-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='debugging'/><title type='text'>Beyond Firebug to NYTProf</title><content type='html'>&lt;a href="http://varlogrant.blogspot.com/2011/11/just-ran-firebug.html"&gt;Clearly, the problem is in the core application&lt;/a&gt;, not the CSS and JS surrounding it. And Firebug only covers the outside of the application.&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So I got NYTProf going. A little search gave me the knowledge that calling a page at &lt;code&gt;http://example.com/myprog.cgi?foo=bar&lt;/code&gt; is the same as calling it with &lt;code&gt;perl myprog.cgi 'foo=bar'&lt;/code&gt;, which is so good to know, especially since the addition of the NYTProf step is &lt;code&gt;perl -d:NYTProf myprog.cgi 'foo=bar'&lt;/code&gt; .&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So, I was able to shave off a second by caching. I could have HOP'd it and just used Memoize, but I like having all the details of a program visible so I don't get bit by something I can't see.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;pre class="perl" name="code"&gt;{&lt;br /&gt;    # all lines of code with  %url_cache are new&lt;br /&gt;    # URLs have been changed to protect the innocent.&lt;br /&gt;    my %url_cache ;&lt;br /&gt;    sub get_service_page {&lt;br /&gt;        my ( $pi ) = @_ ;&lt;br /&gt;        if ( $url_cache{ $pi } ) {&lt;br /&gt;            return $url_cache{ $pi } ;&lt;br /&gt;            }&lt;br /&gt;        my $readfile = pi_Readfile() ;&lt;br /&gt;        my $url = 'http://www.example.edu/~user/projects/XXXXX/' ;&lt;br /&gt;        my $alt =&lt;br /&gt;            'http://www.example.edu/~user/something_else.cgi'&lt;br /&gt;            ;&lt;br /&gt;        my $attr   = 'SGNAME_PUTATIVE' ;&lt;br /&gt;        my $sgname = $readfile-&amp;gt;{ $pi }-&amp;gt;{ $attr } ;&lt;br /&gt;&lt;br /&gt;        if ( ! defined $sgname || '' eq $sgname ) {&lt;br /&gt;            $url_cache{ $pi } = $alt ;&lt;br /&gt;            return $alt ;&lt;br /&gt;            }&lt;br /&gt;        $url =~ s/XXXXX/$sgname/ ;&lt;br /&gt;        $url_cache{ $pi } = $url ;&lt;br /&gt;        return $url ;&lt;br /&gt;        }&lt;br /&gt;    }&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;So, simply by holding onto that little piece of information instead of checking against the same &lt;code&gt;pi_Readfile()&lt;/code&gt; each time, I was able to go from 2-3 seconds to 1.2 seconds. And, now that I'm seeing it, I could hold onto the data structure I get from&amp;nbsp;&amp;nbsp;&lt;code&gt;pi_Readfile()&lt;/code&gt;&amp;nbsp;the same way I hold onto the cache, and could probably tighten up even more.&lt;br /&gt;&lt;br /&gt;I don't know why it didn't occur to me to do that in the first place....&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-7485788503482228567?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/7485788503482228567/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=7485788503482228567' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/7485788503482228567'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/7485788503482228567'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2011/11/beyond-firebug-to-nytprof.html' title='Beyond Firebug to NYTProf'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-8432971493072192834</id><published>2011-11-09T10:19:00.000-05:00</published><updated>2011-11-09T10:19:02.619-05:00</updated><title type='text'>Just Ran Firebug</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-_F5c6gvOwHY/TrqZvce9_1I/AAAAAAAACJU/uD7PoygPg3g/s1600/firebug.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="198" src="http://3.bp.blogspot.com/-_F5c6gvOwHY/TrqZvce9_1I/AAAAAAAACJU/uD7PoygPg3g/s640/firebug.png" width="640" /&gt;&lt;/a&gt;&lt;/div&gt;Pretty clear where the lag is, isn't it?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-8432971493072192834?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/8432971493072192834/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=8432971493072192834' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/8432971493072192834'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/8432971493072192834'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2011/11/just-ran-firebug.html' title='Just Ran Firebug'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-_F5c6gvOwHY/TrqZvce9_1I/AAAAAAAACJU/uD7PoygPg3g/s72-c/firebug.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-823355405432879406</id><published>2011-11-07T13:38:00.001-05:00</published><updated>2011-11-07T13:40:27.695-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='np'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='perl'/><title type='text'>Even More Traveling, Even Less Sales</title><content type='html'>Here's some table descriptions from MySQL, from which you should be able to reverse engineer the table creation. &lt;b&gt;State Capitals&lt;/b&gt;&lt;pre&gt;&lt;br /&gt;+-----------+-------------+------+-----+---------+----------------+&lt;br /&gt;| Field     | Type        | Null | Key | Default | Extra          |&lt;br /&gt;+-----------+-------------+------+-----+---------+----------------+&lt;br /&gt;| id        | int(10)     | NO   | PRI | NULL    | auto_increment |&lt;br /&gt;| state     | varchar(25) | YES  |     | NULL    |                |&lt;br /&gt;| st        | varchar(2)  | YES  |     | NULL    |                |&lt;br /&gt;| city      | varchar(25) | YES  |     | NULL    |                |&lt;br /&gt;| latitude  | float(12,6) | YES  |     | NULL    |                |&lt;br /&gt;| longitude | float(12,6) | YES  |     | NULL    |                |&lt;br /&gt;+-----------+-------------+------+-----+---------+----------------+&lt;br /&gt;&lt;/pre&gt;&lt;b&gt;Combinations&lt;/b&gt; - Connecting each one to each other&lt;pre&gt;&lt;br /&gt;+------------+---------+------+-----+---------+----------------+&lt;br /&gt;| Field      | Type    | Null | Key | Default | Extra          |&lt;br /&gt;+------------+---------+------+-----+---------+----------------+&lt;br /&gt;| id         | int(10) | NO   | PRI | NULL    | auto_increment |&lt;br /&gt;| state_id_1 | int(10) | YES  |     | NULL    |                |&lt;br /&gt;| state_id_2 | int(10) | YES  |     | NULL    |                |&lt;br /&gt;+------------+---------+------+-----+---------+----------------+&lt;br /&gt;&lt;/pre&gt;&lt;b&gt;Distances&lt;/b&gt;&lt;pre&gt;&lt;br /&gt;+----------+-------------+------+-----+---------+----------------+&lt;br /&gt;| Field    | Type        | Null | Key | Default | Extra          |&lt;br /&gt;+----------+-------------+------+-----+---------+----------------+&lt;br /&gt;| id       | int(10)     | NO   | PRI | NULL    | auto_increment |&lt;br /&gt;| distance | float(12,6) | YES  |     | NULL    |                |&lt;br /&gt;+----------+-------------+------+-----+---------+----------------+&lt;br /&gt;&lt;/pre&gt;I'll say again, I think I made a mistake by not including distance in the combination table. I didn't write perl code to put the state capital information into the database. I copied it from a source and recrafted it into SQL by hand.&lt;pre class="sql" name="code"&gt;&lt;br /&gt;INSERT INTO state_capitals ( id , state , st , city ) VALUES ( 01 , "Delaware" , "DE" , "Dover" ) ;&lt;br /&gt;INSERT INTO state_capitals ( id , state , st , city ) VALUES ( 02 , "Pennsylvania" , "PA" , "Harrisburg" ) ;&lt;br /&gt;INSERT INTO state_capitals ( id , state , st , city ) VALUES ( 03 , "New Jersey, NJ" , "Trenton" ) ;&lt;br /&gt;INSERT INTO state_capitals ( id , state , st , city ) VALUES ( 04 , "Georgia" , "GA" , "Atlanta" ) ;&lt;br /&gt;INSERT INTO state_capitals ( id , state , st , city ) VALUES ( 05 , "Connecticut" , "CT" , "Hartford" ) ;&lt;br /&gt;INSERT INTO state_capitals ( id , state , st , city ) VALUES ( 06 , "Massachusetts" , "MA" , "Boston" ) ;&lt;br /&gt;INSERT INTO state_capitals ( id , state , st , city ) VALUES ( 07 , "Maryland" , "MD" , "Annapolis" ) ;&lt;br /&gt;INSERT INTO state_capitals ( id , state , st , city ) VALUES ( 08 , "South Carolina" , "SC" , "Columbia" ) ;&lt;br /&gt;INSERT INTO state_capitals ( id , state , st , city ) VALUES ( 09 , "New Hampshire" , "NH" , "Concord" ) ;&lt;br /&gt;INSERT INTO state_capitals ( id , state , st , city ) VALUES ( 10 , "Virginia" , "VA" , "Richmond" ) ;&lt;br /&gt;INSERT INTO state_capitals ( id , state , st , city ) VALUES ( 11 , "New York" , "NY" , "Albany" ) ;&lt;br /&gt;INSERT INTO state_capitals ( id , state , st , city ) VALUES ( 12 , "North Carolina" , "NC" , "Raleigh" ) ;&lt;br /&gt;INSERT INTO state_capitals ( id , state , st , city ) VALUES ( 13 , "Rhode Island" , "RI" , "Providence" ) ;&lt;br /&gt;INSERT INTO state_capitals ( id , state , st , city ) VALUES ( 14 , "Vermont" , "VT" , "Montpelier" ) ;&lt;br /&gt;INSERT INTO state_capitals ( id , state , st , city ) VALUES ( 15 , "Kentucky" , "KY" , "Frankfort" ) ;&lt;br /&gt;INSERT INTO state_capitals ( id , state , st , city ) VALUES ( 16 , "Tennessee" , "TN" , "Nashville" ) ;&lt;br /&gt;INSERT INTO state_capitals ( id , state , st , city ) VALUES ( 17 , "Ohio" , "OH" , "Columbus" ) ;&lt;br /&gt;INSERT INTO state_capitals ( id , state , st , city ) VALUES ( 18 , "Louisiana" , "LA" , "Baton Rouge" ) ;&lt;br /&gt;INSERT INTO state_capitals ( id , state , st , city ) VALUES ( 19 , "Indiana" , "IN" , "Indianapolis" ) ;&lt;br /&gt;INSERT INTO state_capitals ( id , state , st , city ) VALUES ( 20 , "Mississippi" , "MS" , "Jackson" ) ;&lt;br /&gt;INSERT INTO state_capitals ( id , state , st , city ) VALUES ( 21 , "Illinois" , "IL" , "Springfield" ) ;&lt;br /&gt;INSERT INTO state_capitals ( id , state , st , city ) VALUES ( 22 , "Alabama" , "AL" , "Montgomery" ) ;&lt;br /&gt;INSERT INTO state_capitals ( id , state , st , city ) VALUES ( 23 , "Maine" , "ME" , "Augusta" ) ;&lt;br /&gt;INSERT INTO state_capitals ( id , state , st , city ) VALUES ( 24 , "Missouri" , "MO" , "Jefferson City" ) ;&lt;br /&gt;INSERT INTO state_capitals ( id , state , st , city ) VALUES ( 25 , "Arkansas" , "AR" , "Little Rock" ) ;&lt;br /&gt;INSERT INTO state_capitals ( id , state , st , city ) VALUES ( 26 , "Michigan" , "MI" , "Lansing" ) ;&lt;br /&gt;INSERT INTO state_capitals ( id , state , st , city ) VALUES ( 27 , "Florida" , "FL" , "Tallahassee" ) ;&lt;br /&gt;INSERT INTO state_capitals ( id , state , st , city ) VALUES ( 28 , "Texas" , "TX" , "Austin" ) ;&lt;br /&gt;INSERT INTO state_capitals ( id , state , st , city ) VALUES ( 29 , "Iowa" , "IA" , "Des Moines" ) ;&lt;br /&gt;INSERT INTO state_capitals ( id , state , st , city ) VALUES ( 30 , "Wisconsin" , "WI" , "Madison" ) ;&lt;br /&gt;INSERT INTO state_capitals ( id , state , st , city ) VALUES ( 31 , "California" , "CA" , "Sacramento" ) ;&lt;br /&gt;INSERT INTO state_capitals ( id , state , st , city ) VALUES ( 32 , "Minnesota" , "MN" , "Saint Paul" ) ;&lt;br /&gt;INSERT INTO state_capitals ( id , state , st , city ) VALUES ( 33 , "Oregon" , "OR" , "Salem" ) ;&lt;br /&gt;INSERT INTO state_capitals ( id , state , st , city ) VALUES ( 34 , "Kansas" , "KS" , "Topeka" ) ;&lt;br /&gt;INSERT INTO state_capitals ( id , state , st , city ) VALUES ( 35 , "West Virginia" , "WV" , "Charleston" ) ;&lt;br /&gt;INSERT INTO state_capitals ( id , state , st , city ) VALUES ( 36 , "Nevada" , "NV" , "Carson City" ) ;&lt;br /&gt;INSERT INTO state_capitals ( id , state , st , city ) VALUES ( 37 , "Nebraska" , "NE" , "Lincoln" ) ;&lt;br /&gt;INSERT INTO state_capitals ( id , state , st , city ) VALUES ( 38 , "Colorado" , "CO" , "Denver" ) ;&lt;br /&gt;INSERT INTO state_capitals ( id , state , st , city ) VALUES ( 39 , "North Dakota" , "ND" , "Bismarck" ) ;&lt;br /&gt;INSERT INTO state_capitals ( id , state , st , city ) VALUES ( 40 , "South Dakota" , "SD" , "Pierre" ) ;&lt;br /&gt;INSERT INTO state_capitals ( id , state , st , city ) VALUES ( 41 , "Montana" , "MT" , "Helena" ) ;&lt;br /&gt;INSERT INTO state_capitals ( id , state , st , city ) VALUES ( 42 , "Washington" , "WA" , "Olympia" ) ;&lt;br /&gt;INSERT INTO state_capitals ( id , state , st , city ) VALUES ( 43 , "Idaho" , "ID" , "Boise" ) ;&lt;br /&gt;INSERT INTO state_capitals ( id , state , st , city ) VALUES ( 44 , "Wyoming" , "WY" , "Cheyenne" ) ;&lt;br /&gt;INSERT INTO state_capitals ( id , state , st , city ) VALUES ( 45 , "Utah" , "UT" , "Salt Lake City" ) ;&lt;br /&gt;INSERT INTO state_capitals ( id , state , st , city ) VALUES ( 46 , "Oklahoma" , "OK" , "Oklahoma City" ) ;&lt;br /&gt;INSERT INTO state_capitals ( id , state , st , city ) VALUES ( 47 , "New Mexico" , "NM" , "Santa Fe" ) ;&lt;br /&gt;INSERT INTO state_capitals ( id , state , st , city ) VALUES ( 48 , "Arizona" , "AZ" , "Phoenix" ) ;&lt;br /&gt;INSERT INTO state_capitals ( id , state , st , city ) VALUES ( 49 , "Alaska" , "AK" , "Juneau" ) ;&lt;br /&gt;INSERT INTO state_capitals ( id , state , st , city ) VALUES ( 50 , "Hawaii" , "HI" , "Honolulu" ) ;&lt;br /&gt;&lt;/pre&gt;The latitudes and longitudes were also hand-crafted.&lt;pre class="sql" name="code"&gt;&lt;br /&gt;UPDATE state_capitals SET latitude="32.361538", longitude="-86.279118" where state = "Alabama" ;&lt;br /&gt;UPDATE state_capitals SET latitude="58.301935", longitude="-134.419740" where state = "Alaska" ;&lt;br /&gt;UPDATE state_capitals SET latitude="33.448457", longitude="-112.073844" where state = "Arizona" ;&lt;br /&gt;UPDATE state_capitals SET latitude="34.736009", longitude="-92.331122" where state = "Arkansas" ;&lt;br /&gt;UPDATE state_capitals SET latitude="38.555605", longitude="-121.468926" where state = "California" ;&lt;br /&gt;UPDATE state_capitals SET latitude="39.7391667", longitude="-104.984167" where state = "Colorado" ;&lt;br /&gt;UPDATE state_capitals SET latitude="41.767", longitude="-72.677" where state = "Connecticut" ;&lt;br /&gt;UPDATE state_capitals SET latitude="39.161921", longitude="-75.526755" where state = "Delaware" ;&lt;br /&gt;UPDATE state_capitals SET latitude="30.4518", longitude="-84.27277" where state = "Florida" ;&lt;br /&gt;UPDATE state_capitals SET latitude="33.76", longitude="-84.39" where state = "Georgia" ;&lt;br /&gt;UPDATE state_capitals SET latitude="21.30895", longitude="-157.826182" where state = "Hawaii" ;&lt;br /&gt;UPDATE state_capitals SET latitude="43.613739", longitude="-116.237651" where state = "Idaho" ;&lt;br /&gt;UPDATE state_capitals SET latitude="39.783250", longitude="-89.650373" where state = "Illinois" ;&lt;br /&gt;UPDATE state_capitals SET latitude="39.790942", longitude="-86.147685" where state = "Indiana" ;&lt;br /&gt;UPDATE state_capitals SET latitude="41.590939", longitude="-93.620866" where state = "Iowa" ;&lt;br /&gt;UPDATE state_capitals SET latitude="39.04", longitude="-95.69" where state = "Kansas" ;&lt;br /&gt;UPDATE state_capitals SET latitude="38.197274", longitude="-84.86311" where state = "Kentucky" ;&lt;br /&gt;UPDATE state_capitals SET latitude="30.45809", longitude="-91.140229" where state = "Louisiana" ;&lt;br /&gt;UPDATE state_capitals SET latitude="44.323535", longitude="-69.765261" where state = "Maine" ;&lt;br /&gt;UPDATE state_capitals SET latitude="38.972945", longitude="-76.501157" where state = "Maryland" ;&lt;br /&gt;UPDATE state_capitals SET latitude="42.2352", longitude="-71.0275" where state = "Massachusetts" ;&lt;br /&gt;UPDATE state_capitals SET latitude="42.7335", longitude="-84.5467" where state = "Michigan" ;&lt;br /&gt;UPDATE state_capitals SET latitude="44.95", longitude="-93.094" where state = "Minnesota" ;&lt;br /&gt;UPDATE state_capitals SET latitude="32.320", longitude="-90.207" where state = "Mississippi" ;&lt;br /&gt;UPDATE state_capitals SET latitude="38.572954", longitude="-92.189283" where state = "Missouri" ;&lt;br /&gt;UPDATE state_capitals SET latitude="46.595805", longitude="-112.027031" where state = "Montana" ;&lt;br /&gt;UPDATE state_capitals SET latitude="40.809868", longitude="-96.675345" where state = "Nebraska" ;&lt;br /&gt;UPDATE state_capitals SET latitude="39.160949", longitude="-119.753877" where state = "Nevada" ;&lt;br /&gt;UPDATE state_capitals SET latitude="43.220093", longitude="-71.549127" where state = "New Hampshire" ;&lt;br /&gt;UPDATE state_capitals SET latitude="40.221741", longitude="-74.756138" where state = "New Jersey" ;&lt;br /&gt;UPDATE state_capitals SET latitude="35.667231", longitude="-105.964575" where state = "New Mexico" ;&lt;br /&gt;UPDATE state_capitals SET latitude="42.659829", longitude="-73.781339" where state = "New York" ;&lt;br /&gt;UPDATE state_capitals SET latitude="35.771", longitude="-78.638" where state = "North Carolina" ;&lt;br /&gt;UPDATE state_capitals SET latitude="48.813343", longitude="-100.779004" where state = "North Dakota" ;&lt;br /&gt;UPDATE state_capitals SET latitude="39.962245", longitude="-83.000647" where state = "Ohio" ;&lt;br /&gt;UPDATE state_capitals SET latitude="35.482309", longitude="-97.534994" where state = "Oklahoma" ;&lt;br /&gt;UPDATE state_capitals SET latitude="44.931109", longitude="-123.029159" where state = "Oregon" ;&lt;br /&gt;UPDATE state_capitals SET latitude="40.269789", longitude="-76.875613" where state = "Pennsylvania" ;&lt;br /&gt;UPDATE state_capitals SET latitude="41.82355", longitude="-71.422132" where state = "Rhode Island" ;&lt;br /&gt;UPDATE state_capitals SET latitude="34.000", longitude="-81.035" where state = "South Carolina" ;&lt;br /&gt;UPDATE state_capitals SET latitude="44.367966", longitude="-100.336378" where state = "South Dakota" ;&lt;br /&gt;UPDATE state_capitals SET latitude="36.165", longitude="-86.784" where state = "Tennessee" ;&lt;br /&gt;UPDATE state_capitals SET latitude="30.266667", longitude="-97.75" where state = "Texas" ;&lt;br /&gt;UPDATE state_capitals SET latitude="40.7547", longitude="-111.892622" where state = "Utah" ;&lt;br /&gt;UPDATE state_capitals SET latitude="44.26639", longitude="-72.57194" where state = "Vermont" ;&lt;br /&gt;UPDATE state_capitals SET latitude="37.54", longitude="-77.46" where state = "Virginia" ;&lt;br /&gt;UPDATE state_capitals SET latitude="47.042418", longitude="-122.893077" where state = "Washington" ;&lt;br /&gt;UPDATE state_capitals SET latitude="38.349497", longitude="-81.633294" where state = "West Virginia" ;&lt;br /&gt;UPDATE state_capitals SET latitude="43.074722", longitude="-89.384444" where state = "Wisconsin" ;&lt;br /&gt;UPDATE state_capitals SET latitude="41.145548", longitude="-104.802042" where state = "Wyoming" ;&lt;br /&gt;&lt;/pre&gt;The distances themselves were generated mathematically, with the help of Google and Wikipedia to find the how-to.&lt;pre class="perl" name="code"&gt;&lt;br /&gt;#!/usr/bin/perl&lt;br /&gt;&lt;br /&gt;use 5.010 ;&lt;br /&gt;use strict ;&lt;br /&gt;use warnings ;&lt;br /&gt;use Data::Dumper ;&lt;br /&gt;use DBI ;&lt;br /&gt;&lt;br /&gt;use lib '/home/jacoby/lib' ;&lt;br /&gt;use MyDB 'db_connect' ;&lt;br /&gt;&lt;br /&gt;use subs qw{ get_combos get_states set_distance } ;&lt;br /&gt;&lt;br /&gt;my $pi = atan2( 1, 1 ) * 4 ;&lt;br /&gt;my $states = get_states() ;&lt;br /&gt;my $combos = get_combos() ;&lt;br /&gt;&lt;br /&gt;for my $combo ( (sort { $a&lt;=&gt;$b } keys %$combos ) ) {&lt;br /&gt;    my $c_obj = $combos-&gt;{$combo} ;&lt;br /&gt;    my ( $state_1 , $state_2 ) =  sort { $a &lt;=&gt; $b } $c_obj-&gt;{ state_id_1 } , $c_obj-&gt;{ state_id_2 } ;&lt;br /&gt;    my $obj_s1 = $states-&gt;{ $state_1 } ;&lt;br /&gt;    my $obj_s2 = $states-&gt;{ $state_2 } ;&lt;br /&gt;    my $dist = haversine(&lt;br /&gt;            $obj_s1-&gt;{ latitude } , $obj_s1-&gt;{ longitude } ,&lt;br /&gt;            $obj_s2-&gt;{ latitude } , $obj_s2-&gt;{ longitude } ) ;&lt;br /&gt;    say $combo ;&lt;br /&gt;    say join ' - ' ,&lt;br /&gt;    ( join ', ' , $obj_s1-&gt;{ city } , $obj_s1-&gt;{ state } ) ,&lt;br /&gt;    ( join ', ' , $obj_s2-&gt;{ city } , $obj_s2-&gt;{ state } ) ;&lt;br /&gt;    say join "\t" , '' , $dist . ' miles';&lt;br /&gt;    set_distance( $combo , $dist ) ;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;sub get_states {&lt;br /&gt;    my $dbh = db_connect() ;&lt;br /&gt;    my $sql = 'SELECT * from state_capitals ORDER BY id' ;&lt;br /&gt;    my $states = $dbh-&gt;selectall_hashref( $sql , 'id' ) or croak $dbh-&gt;errstr;&lt;br /&gt;    return $states ;&lt;br /&gt;    }&lt;br /&gt;sub get_combos {&lt;br /&gt;    my $dbh = db_connect() ;&lt;br /&gt;    my $sql = 'SELECT * from combinations ORDER BY id' ;&lt;br /&gt;    my $combos = $dbh-&gt;selectall_hashref( $sql , 'id' ) or croak $dbh-&gt;errstr;&lt;br /&gt;    return $combos ;&lt;br /&gt;    }&lt;br /&gt;sub set_distance {&lt;br /&gt;    my ( $combo , $dist ) = @_ ;&lt;br /&gt;    my $dbh = db_connect() ;&lt;br /&gt;    my $sql = "INSERT INTO distances ( id , distance ) VALUES ( $combo , $dist ) " ;&lt;br /&gt;    say $sql ;&lt;br /&gt;    $dbh-&gt;do( $sql ) or croak $dbh-&gt;errstr;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;sub haversine {&lt;br /&gt;    my ( $lat1, $lon1, $lat2, $lon2 ) = @_ ;&lt;br /&gt;&lt;br /&gt;    my $theta = $lon1 - $lon2 ;&lt;br /&gt;    my $dist =&lt;br /&gt;        sin( deg2rad( $lat1 ) ) *&lt;br /&gt;        sin( deg2rad( $lat2 ) ) +&lt;br /&gt;        cos( deg2rad( $lat1 ) ) *&lt;br /&gt;        cos( deg2rad( $lat2 ) ) *&lt;br /&gt;        cos( deg2rad( $theta ) ) ;&lt;br /&gt;&lt;br /&gt;    $dist = acos( $dist ) ;&lt;br /&gt;    $dist = rad2deg( $dist ) ;&lt;br /&gt;    $dist = $dist * 60 * 1.1515 ;&lt;br /&gt;    return sprintf '%5.2f' , $dist ;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;sub acos {&lt;br /&gt;    my ( $rad ) = @_ ;&lt;br /&gt;    my $ret = atan2( sqrt( 1 - $rad**2 ), $rad ) ;&lt;br /&gt;    return $ret ;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;sub deg2rad {&lt;br /&gt;    my ( $deg ) = @_ ;&lt;br /&gt;    return ( $deg * $pi / 180 ) ;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;sub rad2deg {&lt;br /&gt;    my ( $rad ) = @_ ;&lt;br /&gt;    return ( $rad * 180 / $pi ) ;&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-823355405432879406?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/823355405432879406/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=823355405432879406' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/823355405432879406'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/823355405432879406'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2011/11/even-more-traveling-even-less-sales.html' title='Even More Traveling, Even Less Sales'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-4566734279593399672</id><published>2011-11-07T13:12:00.001-05:00</published><updated>2011-11-07T13:12:24.178-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='np'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='perl'/><title type='text'>More Details on Traveling Salesman</title><content type='html'>I have just received mail from a programmer in France who is interested in learning Perl and &amp;nbsp;asked about some of the constructs in my Traveling Salesman code, specifically asking about MyDB.pm and do_connect. That module and that function are about one thing: getting a DBI object without having to have my login and password and all that within the body of the program, so I can do things like paste it into my blog without worrying. Adapted, it looks like this:&lt;br /&gt;&lt;br /&gt;&lt;pre class="perl" name="code"&gt;package MyDB ;&lt;br /&gt;use strict;&lt;br /&gt;use warnings;&lt;br /&gt;use DBI;&lt;br /&gt;&lt;br /&gt;use Exporter qw(import);&lt;br /&gt;our %EXPORT_TAGS = ('all' =&amp;gt; [ qw(&lt;br /&gt;                                   db_connect&lt;br /&gt;                            ) ],&lt;br /&gt;                    );&lt;br /&gt;our @EXPORT_OK   = ( @{$EXPORT_TAGS{'all'}} );&lt;br /&gt;our $VERSION = 0.0.1;&lt;br /&gt;our %_DB = (&lt;br /&gt;    default =&amp;gt; {&lt;br /&gt;        user       =&amp;gt; 'YouDontGetThis',&lt;br /&gt;        password   =&amp;gt; 'YouDontGetThis',&lt;br /&gt;        host       =&amp;gt; 'YouDontGetThis',&lt;br /&gt;        port       =&amp;gt; '3306',&lt;br /&gt;        database   =&amp;gt; 'YouDontGetThis',&lt;br /&gt;        },&lt;br /&gt;    test =&amp;gt; {&lt;br /&gt;        user       =&amp;gt; 'YouDontGetThis',&lt;br /&gt;        password   =&amp;gt; 'YouDontGetThis',&lt;br /&gt;        host       =&amp;gt; 'YouDontGetThis',&lt;br /&gt;        port       =&amp;gt; '3306',&lt;br /&gt;        database   =&amp;gt; 'YouDontGetThis',&lt;br /&gt;        },&lt;br /&gt;    );&lt;br /&gt;&lt;br /&gt;my $_db_params  = '';       # String of current database parameters.&lt;br /&gt;my $_dbh;                   # Save the handle.&lt;br /&gt;&lt;br /&gt;sub db_connect {&lt;br /&gt;    my ($param_ptr, $attr_ptr) = @_;&lt;br /&gt;&lt;br /&gt;    # If database is already opened then check for a fast return.&lt;br /&gt;&lt;br /&gt;    if (defined $_dbh &amp;amp;&amp;amp;&lt;br /&gt;        (!defined $param_ptr || $param_ptr eq ''))    { return $_dbh }&lt;br /&gt;&lt;br /&gt;    # Check for a different set of parameters to use via a the name (string)&lt;br /&gt;    #   of the parameter (e.g., 'test').&lt;br /&gt;&lt;br /&gt;    my $which_db = 'default';&lt;br /&gt;&lt;br /&gt;    if (defined $param_ptr &amp;amp;&amp;amp; ref($param_ptr) eq '' &amp;amp;&amp;amp; $param_ptr ne '') {&lt;br /&gt;        if (defined $_DB{$param_ptr})   { $which_db = $param_ptr }&lt;br /&gt;        else { return; }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    # Get the base parameters ... copy and flatten from global array&lt;br /&gt;&lt;br /&gt;    my %params = ();&lt;br /&gt;    my %attr   = ();&lt;br /&gt;&lt;br /&gt;    foreach (keys %{$_DB{$which_db}} ) {&lt;br /&gt;        $params{$_} = $_DB{$which_db}{$_};&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;    # Add in extra parameters if given and if the database is not the default.&lt;br /&gt;&lt;br /&gt;    if (defined $param_ptr&lt;br /&gt;        &amp;amp;&amp;amp; ref($param_ptr) eq 'HASH'&lt;br /&gt;        &amp;amp;&amp;amp; (!defined $param_ptr-&amp;gt;{database} ||&lt;br /&gt;             $param_ptr-&amp;gt;{database} ne 'default') ) {&lt;br /&gt;&lt;br /&gt;        foreach (keys %{$_DB{default}})  {&lt;br /&gt;            if (defined $param_ptr-&amp;gt;{$_}) { $params{$_} = $param_ptr-&amp;gt;{$_} }&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;    if (defined $attr_ptr &amp;amp;&amp;amp; ref($attr_ptr) eq 'HASH') {&lt;br /&gt;        foreach (keys %$attr_ptr)  { $attr{$_} = $attr_ptr-&amp;gt;{$_} }&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;    # Now make up an order string of the parameters so that we can compare&lt;br /&gt;    #   them to the old ones.&lt;br /&gt;&lt;br /&gt;    my $new_db_params = '';&lt;br /&gt;    foreach (sort keys %params)  { $new_db_params .= $params{$_} };&lt;br /&gt;&lt;br /&gt;    # Can also do a quick return if params are same as old ones&lt;br /&gt;&lt;br /&gt;    if (defined $_dbh &amp;amp;&amp;amp; $new_db_params eq $_db_params)  {&lt;br /&gt;        return $_dbh;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;    # At this point either the database has never been opened or&lt;br /&gt;    #   new parameters are to be used. Close database and reopen.&lt;br /&gt;&lt;br /&gt;    $_db_params = $new_db_params;&lt;br /&gt;&lt;br /&gt;    if (defined $_dbh) { $_dbh-&amp;gt;disconnect }    # no error check&lt;br /&gt;&lt;br /&gt;    my $source = "dbi:mysql:$params{database}:$params{host}:$params{port}";&lt;br /&gt;&lt;br /&gt;    $_dbh = DBI-&amp;gt;connect($source, $params{user},&lt;br /&gt;                               $params{password}, \%attr);&lt;br /&gt;&lt;br /&gt;    return $_dbh;&lt;br /&gt;&lt;br /&gt;    } # End of db_connect&lt;br /&gt;&lt;br /&gt;1;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&amp;nbsp;For the particulars, I used something, I think WolframAlpha, to get the latitude and longitude of each capital, then looked into some geometry to calculate the distances. Perhaps I should include some database dumps here. for that info.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-4566734279593399672?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/4566734279593399672/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=4566734279593399672' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/4566734279593399672'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/4566734279593399672'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2011/11/more-details-on-traveling-salesman.html' title='More Details on Traveling Salesman'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-242278722917961085</id><published>2011-11-07T12:35:00.002-05:00</published><updated>2011-11-07T12:35:52.141-05:00</updated><title type='text'>How I create my web applications</title><content type='html'>I handle our web stuff from soup to nuts, so here's a little bit of my methodology on how I do that work.&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;I think about what we're supposed to do and what we're supposed to store, and try to express it in SQL, culminating in the creation of a table in our MySQL database.&lt;/li&gt;&lt;li&gt;I write generalized functions for CRUD (creation, reading, updating and deleting) as needed, and create or add to existing Perl modules. I also make testing scripts for these functions to run on the command line.&lt;/li&gt;&lt;li&gt;I write the read functions into a Perl-driven CGI program. I'm old-school enough that each attempt to learn a framework such as Catalyst leaves me frustrated. Full creation of an element is usually handled in this program.&lt;/li&gt;&lt;li&gt;I write a jQuery-based Javascript module to run within the CGI that allows me to collect and add to all the information I need to make modifications.&amp;nbsp;&lt;/li&gt;&lt;li&gt;I write an AJAX backend program in Perl that passes JSON back and forth between the client and server.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;Right now, I'm in that last step. I know there are a few things that I need to start doing. I need to have development, test and production streams going for all this stuff. I need to have much more git going on. And, often there are small tweaks on the CSS throughout this process.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-242278722917961085?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/242278722917961085/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=242278722917961085' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/242278722917961085'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/242278722917961085'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2011/11/how-i-create-my-web-applications.html' title='How I create my web applications'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-1957265613324564448</id><published>2011-11-03T10:47:00.001-04:00</published><updated>2011-11-07T13:14:33.729-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='np'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='perl'/><title type='text'>Traveling Salesman without Farmer's Daughter</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://maps.google.com/maps/api/staticmap?path=color:0xff0000ff|weight:1|33.448456,-112.073845|40.754700,-111.892624|39.160950,-119.753876|38.555607,-121.468925|44.931110,-123.029160|47.042419,-122.893074|43.613739,-116.237648|46.595806,-112.027031|48.813343,-100.779007|44.367966,-100.336380|41.145550,-104.802040|39.739166,-104.984169|35.667233,-105.964577|30.266666,-97.750000|35.482307,-97.534996|39.040001,-95.690002|40.809868,-96.675346|41.590939,-93.620865|44.950001,-93.094002|43.074722,-89.384445|42.733501,-84.546700|36.165001,-86.783997|38.349499,-81.633293|39.962246,-83.000648|38.197273,-84.863113|39.790943,-86.147682|39.783249,-89.650375|38.572952,-92.189285|34.736008,-92.331123|30.458090,-91.140228|32.320000,-90.207001|30.451799,-84.272774|32.361538,-86.279121|33.759998,-84.389999|34.000000,-81.035004|35.771000,-78.638000|37.540001,-77.459999|40.269791,-76.875610|38.972946,-76.501160|39.161922,-75.526756|40.221741,-74.756142|44.266392,-72.571938|42.659828,-73.781342|41.766998,-72.677002|41.823551,-71.422134|42.235199,-71.027496|43.220093,-71.549126|44.323536,-69.765259&amp;amp;size=500x400&amp;amp;sensor=false" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="320" src="http://maps.google.com/maps/api/staticmap?path=color:0xff0000ff|weight:1|33.448456,-112.073845|40.754700,-111.892624|39.160950,-119.753876|38.555607,-121.468925|44.931110,-123.029160|47.042419,-122.893074|43.613739,-116.237648|46.595806,-112.027031|48.813343,-100.779007|44.367966,-100.336380|41.145550,-104.802040|39.739166,-104.984169|35.667233,-105.964577|30.266666,-97.750000|35.482307,-97.534996|39.040001,-95.690002|40.809868,-96.675346|41.590939,-93.620865|44.950001,-93.094002|43.074722,-89.384445|42.733501,-84.546700|36.165001,-86.783997|38.349499,-81.633293|39.962246,-83.000648|38.197273,-84.863113|39.790943,-86.147682|39.783249,-89.650375|38.572952,-92.189285|34.736008,-92.331123|30.458090,-91.140228|32.320000,-90.207001|30.451799,-84.272774|32.361538,-86.279121|33.759998,-84.389999|34.000000,-81.035004|35.771000,-78.638000|37.540001,-77.459999|40.269791,-76.875610|38.972946,-76.501160|39.161922,-75.526756|40.221741,-74.756142|44.266392,-72.571938|42.659828,-73.781342|41.766998,-72.677002|41.823551,-71.422134|42.235199,-71.027496|43.220093,-71.549126|44.323536,-69.765259&amp;amp;size=500x400&amp;amp;sensor=false" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;a href="http://varlogrant.blogspot.com/2011/11/more-details-on-traveling-salesman.html"&gt;Have posted some related details to the problem&lt;/a&gt;, specifically some database access boilerplate.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;The challenge is &lt;i&gt;not&lt;/i&gt;&amp;nbsp;traditional Traveling Salesman, which brings you back to the start. In this case, this is all the state capitals in the continental US, and the challenge is to get through all of them in the shortest distance, but was &lt;i&gt;not&lt;/i&gt;&amp;nbsp;getting back to the start.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;This is my naive solution, which is starting from what I judged to be the furthest east (Maine) and going westward, choosing the shortest capital-to-capital distance. This is easy, and it avoids the biggest pitfall, the one that makes this a named problem.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;Starting at one capital, you have 47 choices. For each of them, there are then 46 choices each, and then 45, and so on. The notation for that is &lt;i&gt;n!&lt;/i&gt;&amp;nbsp;(as opposed to &lt;i&gt;!n&lt;/i&gt; which means &lt;i&gt;not n&lt;/i&gt;) and it is big. &lt;a href="http://www.wolframalpha.com/input/?i=48%21"&gt;1.24x10&lt;sup&gt;61&lt;/sup&gt;.&lt;/a&gt;&amp;nbsp;This means that generating all possible paths would take forever even on big iron. The CS term is &lt;a href="http://en.wikipedia.org/wiki/NP_(complexity)"&gt;nondeterministic polynomial&lt;/a&gt;, or NP. Traveling Salesman is NP-Complete, IIRC. What this means is that, while finding a relatively fast way through this is pretty easy, finding the provably shortest isn't.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;But I'm sure I can do better than this naive solution. The backtracking to get Vermont in makes me think that starting with Vermont and New Hampshire might be the better solution, and the jump from Tennessee to Michigan tells me that simple shortest-path is &lt;i&gt;not&lt;/i&gt; the best solution there. I can generate this fast with simple recursion, getting a simple ordered list, doing the transforms that could tweak this into a faster path is something I don't really know how to do, code-wise.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;Here's my Perl code, including some dyked-out bits covering some other cases. The first thing I can think of is to check every edge and each time two edges cross, switch the order of the second node for each edge. I think that could work, if I could decide how to code it.&amp;nbsp;&lt;/div&gt;&lt;br /&gt;&lt;pre class="perl" name="code"&gt;#!/usr/bin/perl&lt;br /&gt;&lt;br /&gt;# naive shortest-path determination - sucks&lt;br /&gt;&lt;br /&gt;use 5.010 ;&lt;br /&gt;use strict ;&lt;br /&gt;use warnings ;&lt;br /&gt;use Data::Dumper ;&lt;br /&gt;use DBI ;&lt;br /&gt;&lt;br /&gt;use lib '/home/jacoby/lib' ;&lt;br /&gt;use MyDB 'db_connect' ;&lt;br /&gt;&lt;br /&gt;my $states    = get_states() ;&lt;br /&gt;my $combos    = get_combos() ;&lt;br /&gt;my $distances = get_distances() ;&lt;br /&gt;my %shortest ;&lt;br /&gt;&lt;br /&gt;#for my $start ( 1..48 ) {&lt;br /&gt;#    my $state = $states-&amp;gt;{ $start }-&amp;gt;{ state } ;&lt;br /&gt;#    my $dist  = choose_shortest_path( $start ) ;&lt;br /&gt;#    say join "\t", (sprintf '%02.2f' , $dist), $start, $state ;&lt;br /&gt;#    }&lt;br /&gt;#exit ;&lt;br /&gt;&lt;br /&gt;# 23 = maine&lt;br /&gt;&lt;br /&gt;#&lt;br /&gt;##say 'long' ;&lt;br /&gt;##say choose_longest_path( 23 ) ;&lt;br /&gt;##say '' ;&lt;br /&gt;&lt;br /&gt;#say 'short' ;&lt;br /&gt;#choose_shortest_path( 23 ) ;&lt;br /&gt;#say Dumper \%shortest ;&lt;br /&gt;#say '' ;&lt;br /&gt;#&lt;br /&gt;#my ( $s ) = sort { $shortest{ $a } &amp;lt;=&amp;gt; $shortest{ $b } } keys %shortest ;&lt;br /&gt;#&lt;br /&gt;#say as_mark_list( $s ) ;&lt;br /&gt;#say '' ;&lt;br /&gt;#say as_google_url( $s ) ;&lt;br /&gt;#say '' ;&lt;br /&gt;&lt;br /&gt;sub as_mark_list {&lt;br /&gt;    my ( $path ) = @_ ;&lt;br /&gt;    return join '', map { $states-&amp;gt;{ $_ }-&amp;gt;{ st } }&lt;br /&gt;        split m{\|}mx, $path ;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;sub as_google_url {&lt;br /&gt;    my ( $path ) = @_ ;&lt;br /&gt;    my $url1 =&lt;br /&gt;        'http://maps.google.com/maps/api/staticmap?path=color:0xff0000ff|weight:1|'&lt;br /&gt;        ;&lt;br /&gt;    my $url2 = '&amp;amp;size=500x400&amp;amp;sensor=false' ;&lt;br /&gt;    my $body = join '|', map {&lt;br /&gt;        join ',', $states-&amp;gt;{ $_ }-&amp;gt;{ latitude },&lt;br /&gt;            $states-&amp;gt;{ $_ }-&amp;gt;{ longitude }&lt;br /&gt;            }&lt;br /&gt;        split m{\|}mx, $path ;&lt;br /&gt;    return join '', $url1, $body, $url2 ;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;sub key_from_value {&lt;br /&gt;    my %rev = reverse %shortest ;&lt;br /&gt;    my ( $v ) = @_ ;&lt;br /&gt;    return $rev{ $v } ;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;sub choose_shortest_path {&lt;br /&gt;    my @path = @_ ;&lt;br /&gt;    do {&lt;br /&gt;        #say join '|', reverse map {&lt;br /&gt;            #join ',',&lt;br /&gt;        #        $states-&amp;gt;{ $_ }-&amp;gt;{ latitude },&lt;br /&gt;        #        $states-&amp;gt;{ $_ }-&amp;gt;{ longitude }&lt;br /&gt;        #        } @path ;&lt;br /&gt;        #say as_mark_list( join '|', @path ) ;&lt;br /&gt;        #say as_google_url( join '|', @path ) ;&lt;br /&gt;        return 0 ;&lt;br /&gt;        }&lt;br /&gt;        if scalar @path == 48 ;&lt;br /&gt;&lt;br /&gt;    #say join ' ' , scalar @path , '-' , @path ;&lt;br /&gt;    my $s_id    = shift @path ;&lt;br /&gt;    my $state   = $states-&amp;gt;{ $s_id }-&amp;gt;{ state } ;&lt;br /&gt;    my @choices = sort {&lt;br /&gt;        $distances-&amp;gt;{ $a }-&amp;gt;{ distance } &amp;lt;=&amp;gt; $distances-&amp;gt;{ $b }-&amp;gt;{ distance }&lt;br /&gt;        }&lt;br /&gt;        grep {&lt;br /&gt;                is_not_in_array( $combos-&amp;gt;{ $_ }-&amp;gt;{ state_id_1 }, \@path )&lt;br /&gt;            and is_not_in_array( $combos-&amp;gt;{ $_ }-&amp;gt;{ state_id_2 }, \@path )&lt;br /&gt;            }&lt;br /&gt;        grep {&lt;br /&gt;               $combos-&amp;gt;{ $_ }-&amp;gt;{ state_id_1 } == $s_id&lt;br /&gt;            or $combos-&amp;gt;{ $_ }-&amp;gt;{ state_id_2 } == $s_id&lt;br /&gt;            } keys %$combos ;&lt;br /&gt;    my $c     = shift @choices ;&lt;br /&gt;    my $c_obj = $combos-&amp;gt;{ $c } ;&lt;br /&gt;    my ( $o ) = grep { $_ != $s_id } $c_obj-&amp;gt;{ state_id_1 },&lt;br /&gt;        $c_obj-&amp;gt;{ state_id_2 } ;&lt;br /&gt;    my $o_state = $states-&amp;gt;{ $o }-&amp;gt;{ state } ;&lt;br /&gt;    my $d = $distances-&amp;gt;{ $c }-&amp;gt;{ distance } || 'x' ;&lt;br /&gt;&lt;br /&gt;    #say $state ;&lt;br /&gt;&lt;br /&gt;    #say join "\t", '', $d, $c, $s_id, $state, $o, $o_state ;&lt;br /&gt;    #say join "\t", '', join ' ' , @path ;&lt;br /&gt;    #say '' ;&lt;br /&gt;    my $dist = choose_shortest_path( $o, $s_id, @path ) ;&lt;br /&gt;    return $dist + $d ;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;#sub choose_longest_path {&lt;br /&gt;#    my @path = @_ ;&lt;br /&gt;#    do {&lt;br /&gt;#        say join '|', reverse map {&lt;br /&gt;#            join ',',&lt;br /&gt;#                $states-&amp;gt;{ $_ }-&amp;gt;{ latitude },&lt;br /&gt;#                $states-&amp;gt;{ $_ }-&amp;gt;{ longitude }&lt;br /&gt;#                } @path ;&lt;br /&gt;#        say as_mark_list( join '|', @path ) ;&lt;br /&gt;#        say as_google_url( join '|', @path ) ;&lt;br /&gt;#        return 0 ;&lt;br /&gt;#        }&lt;br /&gt;#        if scalar @path == 48 ;&lt;br /&gt;#&lt;br /&gt;#    #say join ' ' , scalar @path , '-' , @path ;&lt;br /&gt;#    my $s_id    = shift @path ;&lt;br /&gt;#    my $state   = $states-&amp;gt;{ $s_id }-&amp;gt;{ state } ;&lt;br /&gt;#    my @choices = sort {&lt;br /&gt;#        $distances-&amp;gt;{ $a }-&amp;gt;{ distance } &amp;lt;=&amp;gt; $distances-&amp;gt;{ $b }-&amp;gt;{ distance }&lt;br /&gt;#        }&lt;br /&gt;#        grep {&lt;br /&gt;#                is_not_in_array( $combos-&amp;gt;{ $_ }-&amp;gt;{ state_id_1 }, \@path )&lt;br /&gt;#            and is_not_in_array( $combos-&amp;gt;{ $_ }-&amp;gt;{ state_id_2 }, \@path )&lt;br /&gt;#            }&lt;br /&gt;#        grep {&lt;br /&gt;#               $combos-&amp;gt;{ $_ }-&amp;gt;{ state_id_1 } == $s_id&lt;br /&gt;#            or $combos-&amp;gt;{ $_ }-&amp;gt;{ state_id_2 } == $s_id&lt;br /&gt;#            } keys %$combos ;&lt;br /&gt;#    my $c     = pop @choices ;&lt;br /&gt;#    my $c_obj = $combos-&amp;gt;{ $c } ;&lt;br /&gt;#    my ( $o ) = grep { $_ != $s_id } $c_obj-&amp;gt;{ state_id_1 },&lt;br /&gt;#        $c_obj-&amp;gt;{ state_id_2 } ;&lt;br /&gt;#    my $o_state = $states-&amp;gt;{ $o }-&amp;gt;{ state } ;&lt;br /&gt;#    my $d = $distances-&amp;gt;{ $c }-&amp;gt;{ distance } || 'x' ;&lt;br /&gt;#&lt;br /&gt;#    #say $state ;&lt;br /&gt;#&lt;br /&gt;#    #say join "\t", '', $d, $c, $s_id, $state, $o, $o_state ;&lt;br /&gt;#    #say join "\t", '', join ' ' , @path ;&lt;br /&gt;#    #say '' ;&lt;br /&gt;#    my $dist = choose_longest_path( $o, $s_id, @path ) ;&lt;br /&gt;#    return $dist + $d ;&lt;br /&gt;#    }&lt;br /&gt;&lt;br /&gt;sub is_not_in_array {&lt;br /&gt;    my ( $num, $path ) = @_ ;&lt;br /&gt;    for my $p ( @$path ) {&lt;br /&gt;        return 0 if $num == $p ;&lt;br /&gt;        }&lt;br /&gt;    return 1 ;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;sub get_states {&lt;br /&gt;    my $dbh    = db_connect() ;&lt;br /&gt;    my $sql    = 'SELECT * from state_capitals ORDER BY id' ;&lt;br /&gt;    my $states = $dbh-&amp;gt;selectall_hashref( $sql, 'id' ) or croak $dbh-&amp;gt;errstr ;&lt;br /&gt;    return $states ;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;sub get_combos {&lt;br /&gt;    my $dbh    = db_connect() ;&lt;br /&gt;    my $sql    = 'SELECT * from combinations ORDER BY id' ;&lt;br /&gt;    my $combos = $dbh-&amp;gt;selectall_hashref( $sql, 'id' ) or croak $dbh-&amp;gt;errstr ;&lt;br /&gt;    return $combos ;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;sub get_distances {&lt;br /&gt;    my $dbh    = db_connect() ;&lt;br /&gt;    my $sql    = 'SELECT * from distances ORDER BY id' ;&lt;br /&gt;    my $combos = $dbh-&amp;gt;selectall_hashref( $sql, 'id' ) or croak $dbh-&amp;gt;errstr ;&lt;br /&gt;    return $combos ;&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-1957265613324564448?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/1957265613324564448/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=1957265613324564448' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/1957265613324564448'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/1957265613324564448'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2011/11/traveling-salesman-without-farmers.html' title='Traveling Salesman without Farmer&apos;s Daughter'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-7986341081054352959</id><published>2011-10-25T15:58:00.000-04:00</published><updated>2011-10-25T15:58:58.988-04:00</updated><title type='text'>Android Dreams</title><content type='html'>&lt;iframe src="http://player.vimeo.com/video/30300114?title=0&amp;amp;byline=0&amp;amp;portrait=0" width="400" height="225" frameborder="0" webkitAllowFullScreen allowFullScreen&gt;&lt;/iframe&gt;&lt;p&gt;&lt;a href="http://vimeo.com/30300114"&gt;android dreams&lt;/a&gt; from &lt;a href="http://vimeo.com/samuelcockedey"&gt;Samuel Cockedey&lt;/a&gt; on &lt;a href="http://vimeo.com"&gt;Vimeo&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-7986341081054352959?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/7986341081054352959/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=7986341081054352959' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/7986341081054352959'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/7986341081054352959'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2011/10/android-dreams.html' title='Android Dreams'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-1425011423558452586</id><published>2011-10-24T13:00:00.001-04:00</published><updated>2011-10-24T13:00:42.505-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='frustration'/><title type='text'>Split Attention</title><content type='html'>If anyone has a solution, please tell me.&lt;br /&gt;&lt;br /&gt;I have some tasks. The one that's almost off my front burner is a conversion job. There's a gob of files that exist in the worst possible XML format, which is there's one entry in the XML, which is a huge compressed BLOB (&lt;i&gt;b&lt;/i&gt;inary &lt;i&gt;l&lt;/i&gt;arge &lt;i&gt;ob&lt;/i&gt;ject) of unknown format. The files have a name that say what kind of job created it and what day, but if you don't know which project went through which day, it gives you no help. We &lt;i&gt;can&lt;/i&gt; export as (a more real) XML, which gives us the sample information we need. Thing is, there are over &lt;i&gt;1500&lt;/i&gt;&amp;nbsp;samples&amp;nbsp;to be converted, which really cannot be a by-hand operation.&lt;br /&gt;&lt;br /&gt;So, I'm working with &lt;a href="http://sikuli.org/"&gt;Sikuli&lt;/a&gt;&amp;nbsp;&lt;a href="http://varlogrant.blogspot.com/search/label/sikuli"&gt;again&lt;/a&gt;, this time on Windows not Ubuntu. I've done the best I can, but this is a program written in Jython (a Java [not my favorite] implementation of Python[not my favorite]) running in Sikuli (taking over the keyboard and mouse) going over Samba to grab the configuration and data&amp;nbsp;files, running in 32-bit Windows 7 on a VirtualBox instance. There's lots and lots of not-necessarily-stable involved here, which means I have to keep checking on it to ensure it keeps running. Which means, while it is going, I can't really throw my mind at any task that really takes my attention, which, basically, means any task I need to do at work, which makes me feel terribly unproductive, even as I know that it's much more productive than if I was doing all that crud by hand.&lt;br /&gt;&lt;br /&gt;So, until I can code up a way that's much more repeatable and stable, or at least until I get well past the 10% completion this project is at about now, I can't really focus elsewhere.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-1425011423558452586?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/1425011423558452586/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=1425011423558452586' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/1425011423558452586'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/1425011423558452586'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2011/10/split-attention.html' title='Split Attention'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-613187663863819460</id><published>2011-10-21T00:48:00.001-04:00</published><updated>2011-10-21T00:48:18.902-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='android'/><category scheme='http://www.blogger.com/atom/ns#' term='networking'/><title type='text'>We Solved It! Return of the PAL Problem</title><content type='html'>&lt;div&gt;Remember what I was saying about the &lt;a href="http://varlogrant.blogspot.com/2011/10/i-dont-like-pal20.html"&gt;campus networking issue&lt;/a&gt; I've been discussing? Long story short: My phone connects to our PEAP and THAWTE protected campus network just fine, but once I am on, the network cannot do anything. But only with Android. Windows is happy with PAL2.0. iOS is happy with PAL2.0, and if I recall the last time I booted the poor, battery-starved old Linux laptop I have in my bookcase at work, desktop Linux is happy with PAL2.0.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;But Android is not. Which is annoying.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I have of course went to the helpdesk, and that's where it gets a bit interesting. There's two groups I've hit: the helpdesk, who have found this problem across different Android versions, across different carriers, different handset manufacturers, without finding any common indicator, and the networking group, who, without more to go on, have entered the &lt;i&gt;go away kid, you bother me&lt;/i&gt; zone, considering it a failure in user configuration.&lt;br /&gt;&lt;br /&gt;I feel I should point out that, for the most part, my co-worker Rick keeps his Android phone all but off when he's in the office. I, on the other hand, tend to hook my phone into my Greater Audio System (Windows and another 1/8" cable [either laptop or phone, depending] run into a y-cable plugged into the audio-in of my Linux box, which I config to go direct to the audio out, because I don't have a mixer, and then into a speaker and to my headphones) so I can get my phone's notification beeps and podcasts along with the other audio I have at work. So I use the network and feel it when it isn't available. So, while I was pushed by usage, for Rick it was a question of curiosity. Which seems to be enough.&lt;br /&gt;&lt;br /&gt;When you think about networking, if you think about networking, you probably think about your IP address akin to a phone number, which kinda works and kinda doesn't. Assume we have an address of 8.8.8.8 (which I don't: that's the IP address of Google's open DNS server, which I kinda like). I can directly connect to any machine on my subnet, which could easily be 8.8.8.7 and 8.8.8.15 or further out, and if I can't find what I want on my local network, the traffic goes out the gateway to the hierarchically higher network. (There can also be down, in addition to up, but that's not important right now.)&lt;br /&gt;&lt;br /&gt;One way to look around the local network is by using MAC addresses and routing tables, but that's too low level for this discussion. We use &lt;a href="http://en.wikipedia.org/wiki/Subnetwork"&gt;subnet masks&lt;/a&gt;. It's a series of 1s and 0s, in that order, which is used to tell if IP address A is in the same subnet as IP address B. A common netmask would look like &lt;code&gt;11111111111111111111111100000000&lt;/code&gt;. Clearly, that's hard for people to deal with, so we would write that as &lt;code&gt;255.255.255.0&lt;/code&gt;. First, each of those four breaks out 8 spaces, which are binary representations of positive integers between 0 and 255. Here's a table of what the allowed numbers are:&lt;/div&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt; &lt;td&gt;00000000 &lt;/td&gt;&lt;td&gt;0 &lt;/td&gt; &lt;/tr&gt;&lt;tr&gt; &lt;td&gt;10000000 &lt;/td&gt;&lt;td&gt;128 &lt;/td&gt; &lt;/tr&gt;&lt;tr&gt; &lt;td&gt;11000000 &lt;/td&gt;&lt;td&gt;192 &lt;/td&gt; &lt;/tr&gt;&lt;tr&gt; &lt;td&gt;11100000 &lt;/td&gt;&lt;td&gt;224 &lt;/td&gt; &lt;/tr&gt;&lt;tr&gt; &lt;td&gt;11110000 &lt;/td&gt;&lt;td&gt;240 &lt;/td&gt; &lt;/tr&gt;&lt;tr&gt; &lt;td&gt;11111000 &lt;/td&gt;&lt;td&gt;248 &lt;/td&gt; &lt;/tr&gt;&lt;tr&gt; &lt;td&gt;11111100 &lt;/td&gt;&lt;td&gt;252 &lt;/td&gt; &lt;/tr&gt;&lt;tr&gt; &lt;td&gt;11111110 &lt;/td&gt;&lt;td&gt;254 &lt;/td&gt; &lt;/tr&gt;&lt;tr&gt; &lt;td&gt;11111111 &lt;/td&gt;&lt;td&gt;255 &lt;/td&gt; &lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;So, if the subnet mask is, 255.255.0.0, that means the mask in binary is &lt;code&gt;11111111&amp;nbsp;11111111&amp;nbsp;00000000&amp;nbsp;00000000&lt;/code&gt;. The digit that share a space with 1 will be the same if the IP address is on the same subnet, and different if it's 0. Google's 8.8.8.8 would be &lt;code&gt;00001000&amp;nbsp;00001000&amp;nbsp;00001000&amp;nbsp;00001000&lt;/code&gt;, the neighbor 8.8.8.9 would be &lt;code&gt;00001000&amp;nbsp;00001000&amp;nbsp;00001000&amp;nbsp;00001001&lt;/code&gt;. Diff's at the end, in the zero space, and thus same subnet. 8.9.8.8 would be &lt;code&gt;00001000&amp;nbsp;00001001&amp;nbsp;00001000&amp;nbsp;00001000&lt;/code&gt;, and that diff would be in the ones, and thus different.&lt;br /&gt;&lt;br /&gt;The subnet mask sent out by DHCP was 255.255.240.0. iOS and Windows are just peachy with that. Rick noticed that the IP addresses were a little higher than he would expect. He suggested that we enter in static IP addresses based upon what we got via DHCP (using a tool like ifconfig to tell you it all) but with 224 as the third octet, and it worked like a charm. Go us!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-613187663863819460?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/613187663863819460/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=613187663863819460' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/613187663863819460'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/613187663863819460'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2011/10/we-solved-it-return-of-pal-problem.html' title='We Solved It! Return of the PAL Problem'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-4568400406177419667</id><published>2011-10-19T16:36:00.001-04:00</published><updated>2011-10-19T16:36:53.464-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='frustration'/><category scheme='http://www.blogger.com/atom/ns#' term='wifi'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>I don't like PAL2.0</title><content type='html'>Purdue has a wireless network, called Purdue Air Link, or PAL2.0. In essence, you log on to the wireless the same way you'd log onto most other university computing equipment.&amp;nbsp;&lt;div&gt;&lt;br /&gt;It works fine on my co-workers' iProducts.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;It works fine on my laptop.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In most places, it works fine for me. And not just "at my home". Other places on campus, other places with PAL2.0.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;But not in my office. In my office, I can connect -- phone says I have connection to network, phone says I have an IP address -- but cannot do anything with them. And the tools I would normally try to use to get a better idea of what's going on, such as ping, nslookup, traceroute and the like, are not on my phone. (Maybe I need to look into those.)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;And, I should say, it affects my co-worker's Android phone, too.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I don't understand an issue that only occurs with Android phones, but it seems I have one. I think I'm getting an IP address, but I can't route.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-4568400406177419667?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/4568400406177419667/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=4568400406177419667' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/4568400406177419667'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/4568400406177419667'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2011/10/i-dont-like-pal20.html' title='I don&apos;t like PAL2.0'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-6070747077525914311</id><published>2011-10-17T10:31:00.000-04:00</published><updated>2011-10-17T10:31:20.126-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='editors'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='frustration'/><title type='text'>Mad Mad Mad at Komodo Edit</title><content type='html'>I program, and for most small jobs, and for most complex find/replace jobs, I prefer vi. I have tried EMACS, but I never really got it. But I've hit a point that, when I'm doing most of my coding, I prefer an editor that behaves a bit more like a word processor. I want a graphical editor. I have tried a few. The one I use these days is &lt;a href="http://www.activestate.com/komodo-edit"&gt;Komodo Edit&lt;/a&gt; from &lt;a href="http://www.activestate.com/"&gt;Activestate&lt;/a&gt;, which I use some on Windows but primarily on Unix.&lt;br /&gt;&lt;br /&gt;I develop and maintain a few web apps for the lab, and that's everything from SQL to Perl libraries to Perl applications to HTML to Javascript. I'm often wanting to make sure that the page I'm writing is working right with the AJAX Javascript code I'm writing for it, which is connecting to the CGI Perl code I'm writing, and that it is working correctly with the modules. Since they're at the far ends of the user experience, the Perl module and the HTML are tabs in one editor window, with the client-side Javascript in an other window and the server side Perl in another. Both my journalism school page layout background and my history with 80x24 terminals has lead me to believe that you don't want to go too wide, so I try to keep my code within 75 to 80 characters per line. My main monitor is 1680x1050, and I can have my code at a readable font size and still have three editor windows in one monitor, leaving my other for terminals (I have four to six open post of the time) and my Windows monitor open to a web browser.&lt;br /&gt;&lt;br /&gt;This means that I CANNOT have three open and not partially-hidden editor windows on one screen. This used to be no problem for Komodo Edit, and is a deal-breaker for me.&lt;br /&gt;&lt;br /&gt;So, what other mature modern graphical text editors for Linux are out there?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-6070747077525914311?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/6070747077525914311/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=6070747077525914311' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/6070747077525914311'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/6070747077525914311'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2011/10/mad-mad-mad-at-komodo-edit.html' title='Mad Mad Mad at Komodo Edit'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-829619199550281084</id><published>2011-10-13T09:54:00.000-04:00</published><updated>2011-10-13T09:55:01.209-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='computers'/><category scheme='http://www.blogger.com/atom/ns#' term='history'/><title type='text'>Who is Dennis Ritchie and Why should I care?</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-eRSQwh_vs2I/Tpbp1rUfIeI/AAAAAAAACAE/kWX58K8Xaog/s1600/Dennis_Ritchie.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" height="320" src="http://2.bp.blogspot.com/-eRSQwh_vs2I/Tpbp1rUfIeI/AAAAAAAACAE/kWX58K8Xaog/s320/Dennis_Ritchie.jpg" width="230" /&gt;&lt;/a&gt;&lt;/div&gt;You can check &lt;a href="http://en.wikipedia.org/wiki/Dennis_Ritchie"&gt;Wikipedia&lt;/a&gt;&amp;nbsp;for the fuller explanation, but here's the summary: He was a researcher at Bell Labs. While he was there, he worked on the Multics system, and as an offshoot, created the C language and the Unix operating system. The C language was not tightly tied to the specific system it came from, which meant that things written in it could reasonably be ported from one set of hardware to another.&lt;br /&gt;&lt;br /&gt;He, Ken Thompson and Brian Kernighan are among the set of people whose creations made modern computation possible. I throw into that list Bob Metcalfe (ethernet) and Douglas Engelbart (windowing systems and the mouse). Others came along after and made things better, smaller, faster, more integrated and more beautiful, which is all very important, but Ritchie is among those who made things possible. He will be missed.&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;b&gt;Dennis MacAlistair Ritchie 1941-2011&lt;/b&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-829619199550281084?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/829619199550281084/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=829619199550281084' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/829619199550281084'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/829619199550281084'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2011/10/you-can-check-wikipedia-fuller.html' title='Who is Dennis Ritchie and Why should I care?'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/-eRSQwh_vs2I/Tpbp1rUfIeI/AAAAAAAACAE/kWX58K8Xaog/s72-c/Dennis_Ritchie.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-1179339131170446840</id><published>2011-10-12T01:50:00.002-04:00</published><updated>2011-10-13T09:55:51.536-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='computers'/><title type='text'>Open Computing, Taken To The Next Level</title><content type='html'>&lt;table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: left; margin-right: 1em; text-align: left;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-1hnwHJg3OQk/TpUojWBMWfI/AAAAAAAAB_w/LPNnfzB3Z2g/s1600/DOMA-PROPCI41.jpg" imageanchor="1" style="clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="400" src="http://4.bp.blogspot.com/-1hnwHJg3OQk/TpUojWBMWfI/AAAAAAAAB_w/LPNnfzB3Z2g/s400/DOMA-PROPCI41.jpg" width="400" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Hat-tip &lt;a href="http://blog.makezine.com/archive/2011/10/tool-review-doma-pro-pci-open-computer-case.html"&gt;MakerBlog&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;This is the &lt;a href="http://www.myopenpc.com/products/doma-pro-pci/"&gt;Doma Pro PCI&lt;/a&gt;, a black acrylic "case" for a computer. I say "case" because, while there are enclosures for the optical and hard drive, it's not really a case because it doesn't close. All your electronic bits are open to the world.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Which is neat, if you're in an environment where keeping your computer open to the elements is acceptable I wouldn't try this with young children.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;But, as always, I do like.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;During college, friend-of-the-blog Patrick had a working computer stuck to his bulletin board. The power supply sat on a nearby shelf, I think, but otherwise, it all hung off the wall.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I'd be curious about RF interference in the surounding area, but this looks like a neat thing.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-1179339131170446840?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/1179339131170446840/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=1179339131170446840' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/1179339131170446840'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/1179339131170446840'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2011/10/open-computing-taken-to-next-level.html' title='Open Computing, Taken To The Next Level'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-1hnwHJg3OQk/TpUojWBMWfI/AAAAAAAAB_w/LPNnfzB3Z2g/s72-c/DOMA-PROPCI41.jpg' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-8099114292704628649</id><published>2011-10-06T09:47:00.002-04:00</published><updated>2011-10-06T09:47:37.576-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='frustration'/><category scheme='http://www.blogger.com/atom/ns#' term='ubuntu'/><title type='text'>Trying to install boom</title><content type='html'>&lt;a href="http://zachholman.com/boom/"&gt;boom&lt;/a&gt; is a key-value store, running on the command line and written in &lt;a href="http://ruby-lang.org/"&gt;ruby&lt;/a&gt;. I don't know whether I need a key-value store for my command line, but I remember when I didn't know if I needed a laptop, bash, Linux, VirtualBox, an RSS&amp;nbsp;aggregator, and so many other things. So, I thought I'd try it. And, I of course decided to try it first on the machine I command line the most, my work machine, which runs Ubuntu 10.04, the long-term support version.&lt;br /&gt;&lt;br /&gt;&lt;pre class="bash" name="code"&gt;jacoby@oz:~$ uname -a&lt;br /&gt;Linux oz 2.6.32-34-generic #77-Ubuntu SMP Tue Sep 13 19:40:53 UTC 2011 i686 GNU/Linux&lt;br /&gt;jacoby@oz:~$ ruby -v&lt;br /&gt;ruby 1.9.1p378 (2010-01-10 revision 26273) [i486-linux]&lt;br /&gt;jacoby@oz:~$ gem -v&lt;br /&gt;1.3.5&lt;br /&gt;jacoby@oz:~$ gem install boom&lt;br /&gt;WARNING:  Installing to ~/.gem since /var/lib/gems/1.9.1 and&lt;br /&gt;	  /var/lib/gems/1.9.1/bin aren't both writable.&lt;br /&gt;WARNING:  You don't have /home/jacoby/.gem/ruby/1.9.1/bin in your PATH,&lt;br /&gt;	  gem executables will not run.&lt;br /&gt;ERROR:  Error installing boom:&lt;br /&gt;	multi_json requires RubyGems version &amp;gt;= 1.3.6&lt;br /&gt;&lt;/pre&gt;&lt;pre class="bash" name="code"&gt;jacoby@oz:~$ gem update --system 1.3.7&lt;br /&gt;ERROR:  While executing gem ... (RuntimeError)&lt;br /&gt;    gem update --system is disabled on Debian. RubyGems can be updated using the official Debian repositories by aptitude or apt-get.&lt;br /&gt;jacoby@oz:~$ &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;I followed this up by downloading and building ruby and trying to do a gem install from that. Into my second day, I decided that spending more of my precious time trying to get it working on Ubuntu was a waste. So I briefly considered reimplementing it in perl, then found ruby for Windows and installed it on my Win7 box. Then I opened a term and did the gem install. And now it works.&lt;br /&gt;&lt;br /&gt;I find this profoundly disappointing.&lt;br /&gt;&lt;br /&gt;I don't think this is the fault of Zach Holman, the creator of boom. I&amp;nbsp;have now tried boom on Windows and kinda like it. I suspect (and might pop open VirtualBox and a bleeding-edge distro to check) that the problem is that Ubuntu or just U10.04 is stuck with an ancient RubyGems the way that RHEL is stuck with ancient Perl. I just know that I don't believe it should've been a problem.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-8099114292704628649?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/8099114292704628649/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=8099114292704628649' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/8099114292704628649'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/8099114292704628649'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2011/10/trying-to-install-boom.html' title='Trying to install boom'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-2063430182572478350</id><published>2011-10-04T13:17:00.003-04:00</published><updated>2011-10-04T13:17:48.952-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='we live in the future'/><title type='text'></title><content type='html'>&lt;a href="http://www.theatlantic.com/technology/archive/2011/10/for-some-strange-reason-i-want-to-talk-to-my-ipad/246130/"&gt;http://www.theatlantic.com/technology/archive/2011/10/for-some-strange-reason-i-want-to-talk-to-my-ipad/246130/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I have headphones at work, which I use for the express purpose of filtering out the sounds of my coworkers, and the sound of them talking to each other is distracting enough. Voice control makes all the sense in a car, but on a tablet?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-2063430182572478350?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/2063430182572478350/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=2063430182572478350' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/2063430182572478350'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/2063430182572478350'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2011/10/httpwww.html' title=''/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-6838458332532575552</id><published>2011-10-04T09:41:00.002-04:00</published><updated>2011-10-04T09:42:00.566-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='frustration'/><title type='text'>Tablesorter Bug</title><content type='html'>We use the jQuery module tablesorter to allow for the dynamic sorting of our tables, and I have just now run into a bug.&lt;br /&gt;&lt;br /&gt;We have 3 second-generation sequencers: the 454, the SOLiD, and the HiScan. We have a second-generation sequence table, which mingles all three. And sorting on sequence agent is broken, because it trys to look at the column numerically when clearly, it needs to treat them all as character strings. Which will monopolize my next few hours.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-6838458332532575552?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/6838458332532575552/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=6838458332532575552' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/6838458332532575552'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/6838458332532575552'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2011/10/tablesorter-bug.html' title='Tablesorter Bug'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-1786755355504385721</id><published>2011-09-29T15:52:00.001-04:00</published><updated>2011-09-29T15:52:45.747-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><title type='text'>Learned some Javascript (and maybe more) (I think)</title><content type='html'>&lt;pre class="javascript" name="code"&gt;var filename = get_filename_or_something() ; # !important&lt;br /&gt;if ( !! filename ) {&lt;br /&gt;    # do code&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;It took me a while, but I &lt;i&gt;think&lt;/i&gt; I get this. If you try this and &lt;code&gt;filename&lt;/code&gt; is undefined, that could be a problem. One bang forces it into the logical realm, and the other bang reverses it, making positives negatives. In perl, we'd just go &lt;code&gt; if ( $filename ) {} &lt;/code&gt;, but we're cool like that.&lt;br /&gt;&lt;br /&gt;But, as you might imagine, it is absolutely impossible to look this one up on Google.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-1786755355504385721?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/1786755355504385721/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=1786755355504385721' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/1786755355504385721'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/1786755355504385721'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2011/09/learned-some-javascript-and-maybe-more.html' title='Learned some Javascript (and maybe more) (I think)'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-8101789449176058149</id><published>2011-09-29T13:10:00.001-04:00</published><updated>2011-09-29T13:11:30.728-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='puppet'/><category scheme='http://www.blogger.com/atom/ns#' term='software engineering'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='sucking'/><category scheme='http://www.blogger.com/atom/ns#' term='frustration'/><title type='text'>How a technical presentation Q&amp;A session turned my head around.</title><content type='html'>Sometimes you learn something beyond what you expect.&lt;br /&gt;&lt;br /&gt;Last night, I attended a presentation at &lt;a href="http://purduelug.org/"&gt;my local LUG&lt;/a&gt;&amp;nbsp;of Puppet by Garrett Honeycutt of &lt;a href="http://puppetlabs.com/"&gt;Puppetlabs&lt;/a&gt;. Garrett had evidently been a PLUG guy when I was, but I didn't really recognize him. I did recognize his friend, so it could be my mind going.&lt;br /&gt;&lt;br /&gt;Anyway, Puppet, in a nutshell, is a configuration manager useful for keeping hundreds of machines doing what you want, using the same kinds of tools people use to manage software, including moving from Development to Test to Production. Some people I know who ride the big iron are finding their current means to manage their hundreds of machines to be a little too hodge-podge and daunting were there, and it seems they like the taste of that Kool-Aid. I was interested, and thinking it could be useful, but a bit more than anything I need.&lt;br /&gt;&lt;br /&gt;That's when it hit me. In our current workplace, we're not really doing that. There's one canonical instance of a thing, be it a Perl program, a Perl library, a Javascript module, a web page, a script, whatever. We have test and production databases, and for some of the modules, we're using tests like in &lt;a href="http://shop.oreilly.com/product/9780596100926.do"&gt;Perl Testing&lt;/a&gt;, which I must confess I never really "got". So, while we might be generating decent code, we're not engineering it and maintaining it the way we should.&lt;br /&gt;&lt;br /&gt;So, I'm spending much of today trying to wrap my head around that, hoping to establish Dev-Test-Production setup for my code. Thank you, Garrett and Mike and the rest, for kicking me the right direction without even meaning to.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-8101789449176058149?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/8101789449176058149/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=8101789449176058149' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/8101789449176058149'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/8101789449176058149'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2011/09/how-technical-presentation-q-session.html' title='How a technical presentation Q&amp;A session turned my head around.'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-630853509963450530</id><published>2011-09-26T11:23:00.000-04:00</published><updated>2011-09-26T11:23:29.694-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='bluetooth'/><title type='text'>It Exists!</title><content type='html'>Turns out that "Bluetooth for Location" has been solved already, with &lt;a href="http://sourceforge.net/projects/blueproximity/"&gt;BlueProximity&lt;/a&gt;. I'm still looking for a way that a recurring crontab thing can be set up, but a precedent has been set and licensed GPL, so I'm optimistic.&lt;br /&gt;&lt;br /&gt;Also, apt-getting bluetooth and bluez-utils made the broken little dongle shine blue. Just that easy.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-630853509963450530?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/630853509963450530/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=630853509963450530' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/630853509963450530'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/630853509963450530'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2011/09/it-exists.html' title='It Exists!'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-6449351289602757184</id><published>2011-09-25T23:43:00.000-04:00</published><updated>2011-09-25T23:43:42.531-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='arduino'/><category scheme='http://www.blogger.com/atom/ns#' term='location'/><category scheme='http://www.blogger.com/atom/ns#' term='bluetooth'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>How Can My Computer Know I'm At My Desk?</title><content type='html'>The problem is exactly as stated. I have my computer do certain alerting things, but unless I'm physically near, I don't it to do some of &amp;nbsp;'em. And it would be nice to be able to use it to enable certain security aspects, less "unlock when I show up" but rather "lock when I leave". But first, of course, we must have that mechanism.&lt;br /&gt;&lt;br /&gt;So what are our choices?&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;i&gt;Motion Sensor&lt;/i&gt; - I like it. I used to have one in my den to control the light. It's neat. For work areas, I strongly suggest them for your lights, and have on this blog in the past. But you don't always have motion, especially when you've messed up line-of-sight or have a moment of stillness. So, it's a factor, but not &lt;i&gt;the&lt;/i&gt; factor.&lt;/li&gt;&lt;li&gt;&lt;i&gt;Light Sensor&lt;/i&gt; - That won't tell me everything, but will tell us something, and that something is that the light switch is on at my desk. Not perfect, because often my coworkers turn the light on when I'm not yet there, but it's certainly better than nothing.&amp;nbsp;&lt;/li&gt;&lt;li&gt;&lt;i&gt;Location Sensing&lt;/i&gt; - My phone is the very definition of an Every Day Carry, and being a GPS-enabled Android which talks to Latitude, I can query Google to find out where I am. Except, where I am at work is in a subbasement, with no radio and no cellphone, so the location sensing defaults to a switch on the other side of campus, which hardly works. Maybe I should try it for "at home".&amp;nbsp;&lt;/li&gt;&lt;li&gt;&lt;i&gt;WiFi&lt;/i&gt; - If my phone is connected to my home network, my switch knows it and with a little coding, I can use it. Which is great, but when I'm at home, I often have WiFi off, and sometimes I use 4G (in the one corner of town where Sprint has 4G). Sometimes I don't though, which makes it a poor indicator at home. But it gets worse at work. My desktop is behind a firewall and my phone would be on the campus WiFi, so never the twain shall meet. I could write something that announces every 10 min or so that I'm on the campus network, should I ever get far enough into coding Android, but it isn't there yet.&lt;/li&gt;&lt;li&gt;&lt;i&gt;Bluetooth&lt;/i&gt; - This is the one I'm currently dreaming about. My dongle is Class 2, which means I have about 30 feet of range (and possibly less at the office). That's a nice range.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;Without the addition of hardware I don't yet own, I'm thinking that the best solution is Bluetooth. I think that I could have fun making a dingus with Arduino that does motion sensing and light sensing (and maybe a thermometer) so I can get all sorts of data I can play with, but I can't play with that at work tomorrow.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Any thoughts I'm missing besides USB dongle and smart card you can think of?&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-6449351289602757184?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/6449351289602757184/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=6449351289602757184' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/6449351289602757184'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/6449351289602757184'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2011/09/how-can-my-computer-know-im-at-my-desk.html' title='How Can My Computer Know I&apos;m At My Desk?'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-207288988401994213</id><published>2011-09-15T22:51:00.002-04:00</published><updated>2011-09-15T22:51:40.597-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='delicious'/><category scheme='http://www.blogger.com/atom/ns#' term='technology'/><category scheme='http://www.blogger.com/atom/ns#' term='news'/><title type='text'>The Delicious Fruit Has Become Bitter</title><content type='html'>I just got mail from Yahoo.&lt;br /&gt;&lt;br /&gt;It's the opt-out email. YouTube creators Chad Hurley and Steve Chen have bought it from Yahoo! and are going to try to get it going again.&lt;br /&gt;&lt;br /&gt;I wish them luck.&lt;br /&gt;&lt;br /&gt;I doubt will go anywhere.&lt;br /&gt;&lt;br /&gt;I got into Delicious when I was at the clinic, I think. There were two main selling points for the service:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Your bookmarks were saved in one central location, so that you could share them between your work machine, your home machine, your laptop, etc.&lt;/li&gt;&lt;li&gt;You could see what other people bookmarked and found valuable on various subjects.&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;Point #1 was crucial to me. You start getting computers, you start getting headaches about knowing where your links are. Point #2? I tried it a few times. It never was too valuable to me. When I set up a new computer, one of the first things I did was sign in with Delicious and download the Firefox plugin.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;When Chrome came along with their bookmark system, I jumped. Right now, a few games that don't work right in Chrome are all that keep me going back to Firefox, plus the occasional debugging, and I never ever log into Delicious. A few months ago, I downloaded the bookmarks from Delicious and put them into Evernote. I don't think I've surfed from it yet. I doubt half the content is still there.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-207288988401994213?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/207288988401994213/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=207288988401994213' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/207288988401994213'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/207288988401994213'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2011/09/delicious-fruit-has-become-bitter.html' title='The Delicious Fruit Has Become Bitter'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-1153857931758982869</id><published>2011-09-13T12:05:00.000-04:00</published><updated>2011-09-13T12:05:18.166-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='star wars'/><category scheme='http://www.blogger.com/atom/ns#' term='pop culture'/><title type='text'>Pop Culture Rant, not so much a Tech Rant</title><content type='html'>&lt;a href="http://popdose.com/george-lucas-doesnt-give-a-shit-about-you/"&gt;George Lucas doesn't give a sh*t about you.&lt;/a&gt;&amp;nbsp;It's survival of the fittest, friend, and George has the f*cking editing bay.&lt;br /&gt;&lt;br /&gt;&lt;iframe allowfullscreen="" frameborder="0" height="345" src="http://www.youtube.com/embed/2z9XTeeA43o" width="420"&gt;&lt;/iframe&gt;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;I think we saw what we needed to know about George Lucas in &lt;i&gt;Return of the Jedi&lt;/i&gt;. We know that Boba Fett's backpack has jets, but he couldn't jet out of the Sarlacc pit. This song is as cool as Fett seemed in &lt;i&gt;Empire Strikes Back&lt;/i&gt;, as cool as he's presented here by MC Chris — he'll chase you "from Endor to Hoth, from Ripley to Spock" — but he dropped into the Sarlacc pit like a sucker and couldn't get out even though he had the tools to. Forget, if you can, that&amp;nbsp;&lt;i&gt;Star Wars&lt;/i&gt;&amp;nbsp;begins with Jar Jar and ends with Ewoks and just focus on how the intense human drama at the end of &lt;i&gt;Empire&lt;/i&gt;&amp;nbsp;gave way to the fairly ham-handed beginning of &lt;i&gt;Return.&lt;/i&gt;&lt;br /&gt;&lt;i&gt;&lt;br /&gt;&lt;/i&gt;&lt;br /&gt;Watch the movies. Enjoy them. But remember that Lucas has lost the script. Don't invest yourself in Lucas, because he doesn't care about you.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-1153857931758982869?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/1153857931758982869/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=1153857931758982869' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/1153857931758982869'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/1153857931758982869'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2011/09/pop-culture-rant-not-so-much-tech-rant.html' title='Pop Culture Rant, not so much a Tech Rant'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://img.youtube.com/vi/2z9XTeeA43o/default.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-9165531259076908140</id><published>2011-09-09T09:41:00.002-04:00</published><updated>2011-09-09T09:51:28.417-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='passwords'/><category scheme='http://www.blogger.com/atom/ns#' term='frustration'/><title type='text'>Password Strangeness</title><content type='html'>&lt;div&gt;I'm in this group. This group has a web tool. This web tool is made with ease of use and trust as cornerstones, so there's one password. That password, for purposes of discussion, is &lt;code&gt;Abc123&lt;/code&gt;. Be it noted that I remember the letters and numbers, but not necessarily the cases.&lt;/div&gt;&lt;div&gt;While waiting for the bus to work, another member of the group wanted access to the web tool, and emailed me for the password. I did some checking on my Android phone and told him that the password was &lt;code&gt;ABC123&lt;/code&gt;, because that worked with my phone.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;When I got to a computer, we did some testing and found that neither &lt;code&gt;abc123&lt;/code&gt; and &lt;code&gt;ABC123&lt;/code&gt; before I checked the password configuration and found the right one.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So, why, when I put the password into this tool, did it take &lt;code&gt;ABC123&lt;/code&gt; as &lt;code&gt;Abc123&lt;/code&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-9165531259076908140?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/9165531259076908140/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=9165531259076908140' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/9165531259076908140'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/9165531259076908140'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2011/09/password-strangeness.html' title='Password Strangeness'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-4340829389874264599</id><published>2011-09-08T10:51:00.001-04:00</published><updated>2011-09-08T10:51:35.015-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='television'/><category scheme='http://www.blogger.com/atom/ns#' term='we live in the future'/><title type='text'>Configuration Joys</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/-7M-XvkpRI4w/TmjV44ix04I/AAAAAAAAB6w/O_bzB0E4sCo/s1600/harmony-200-remote-emea-glamour-images.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" height="320" src="http://1.bp.blogspot.com/-7M-XvkpRI4w/TmjV44ix04I/AAAAAAAAB6w/O_bzB0E4sCo/s320/harmony-200-remote-emea-glamour-images.png" width="291" /&gt;&lt;/a&gt;&lt;/div&gt;I just got a new remote. I don't suppose I really needed one. I have three in my bedroom (four if you count the wireless keyboard) and I'm more than fine with handling them. It wasn't "Hey, I need a new zapper in the bedroom" that lead me to jump on this.&lt;br /&gt;&lt;br /&gt;It was my RSS feed.&lt;br /&gt;&lt;br /&gt;I have Radio Shack stuck in there, mostly to see when Radio Shack starts selling the Arduino. What I saw was an announcement of Logitech's Harmony line of remotes. I had heard about them. A friend has a fairly advanced one that has a screen and allows you to combine button-presses for several devices into one action, such as "play movie" starting the DVD player and moving to the composite input.&lt;br /&gt;&lt;br /&gt;I got the &lt;a href="http://www.logitech.com/en-roeu/remotes/universal-remotes/devices/harmony-200-remote"&gt;Harmony 200&lt;/a&gt;, &amp;nbsp;a much less complex and cool remote. Also, at $20, much much cheaper. It can control three devices, which works well for the bedroom (TV, DVD, Cable) but the living room has TiVo too and the four-device Harmony 300 is $10 more.&lt;br /&gt;&lt;br /&gt;The selling point, the thing that made me go out and get it, was the programming. Well, the price, too, but that just meant it was possible. You plug it into USB and there's a quick-and-easy screen which lets you tell it this is my TV, this is my DVD player, etc. You can then customize the buttons. Then you sync the settings and you're done. No more messing with the "Press the Mode button for 4 seconds, look for the flashing LCD, then punch this four-digit number in" or the worse "Press Power then Down again and again until the TV goes off".&lt;br /&gt;&lt;br /&gt;I'll mess with finding different combinations, but this is a solid, well-made remote whose ROM I flash to bend it to my will.&lt;br /&gt;&lt;br /&gt;We live in the future.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-4340829389874264599?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/4340829389874264599/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=4340829389874264599' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/4340829389874264599'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/4340829389874264599'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2011/09/configuration-joys.html' title='Configuration Joys'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-7M-XvkpRI4w/TmjV44ix04I/AAAAAAAAB6w/O_bzB0E4sCo/s72-c/harmony-200-remote-emea-glamour-images.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-6296461704924360836</id><published>2011-08-16T15:02:00.003-04:00</published><updated>2011-08-16T15:20:11.670-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sql'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='frustration'/><title type='text'>More Fun With SQL</title><content type='html'>&lt;div&gt;I've mentioned this bit of code recently:&lt;/div&gt;&lt;div&gt;&lt;br/&gt;&lt;/div&gt;&lt;pre class="sql" name="code"&gt;        INSERT INTO accession_analysis (&lt;br /&gt;            accession_id ,  analysis_id ,&lt;br /&gt;            reference_id ,  status ,&lt;br /&gt;            status_text  ,  extra_parameters&lt;br /&gt;            )&lt;br /&gt;        SELECT&lt;br /&gt;            accession_id ,&lt;br /&gt;            ? , ? , ? , ? , ?, ?&lt;br /&gt;        FROM accessions&lt;br /&gt;        WHERE request_id = ?&lt;br /&gt;        ORDER BY accession_id&lt;br /&gt;&lt;/pre&gt;&lt;div&gt;Well, it's slightly different. Before we were just holding the current state ( waiting, working, success, failure ) and now we're holding text information, too, and you don't just want the current state, you want to be able to look back. So, in addition to &lt;code&gt;accession_analysis&lt;/code&gt; , we're adding &lt;code&gt;accession_analysis_status&lt;/code&gt;, which will have, so far, a unique id, an id for the AA it connects to, and then the the status information.&lt;/div&gt;&lt;div&gt;&lt;br/&gt;&lt;/div&gt;&lt;div&gt;And the run now. I have to add a run number to the &lt;code&gt;accession_analysis&lt;/code&gt; schema. I can do that, but that's not germane right now. &lt;/div&gt;&lt;div&gt;&lt;br/&gt;&lt;/div&gt;&lt;div&gt;What is germane is how to store the status into &lt;code&gt;accession_analysis_status&lt;/code&gt; at about the same time as it goes into &lt;code&gt;accession_analysis&lt;/code&gt;, getting the &lt;code&gt;id&lt;/code&gt; from the &lt;code&gt;accession_analysis&lt;/code&gt; table. It would be far easier if I was using an iterative approach, but then I'm blasting the DB with many connections instead of just one.&lt;/div&gt;&lt;div&gt;&lt;br/&gt;&lt;/div&gt;&lt;div&gt;An approach would be to find all the &lt;code&gt;accession_analysis&lt;/code&gt; elements without a matching   &lt;code&gt;accession_analysis_status&lt;/code&gt;, and then inserting them into &lt;code&gt;accession_analysis_status&lt;/code&gt;. Something like&lt;/div&gt;&lt;div&gt;&lt;br/&gt;&lt;/div&gt;&lt;pre class="sql" name="code"&gt;INSERT INTO accession_analysis_status ( &lt;br /&gt;    aa_id , status , status_text &lt;br /&gt;    ) &lt;br /&gt;SELECT id , status ,status_text &lt;br /&gt;FROM accession_analysis &lt;br /&gt;WHERE there's no aa_id corresponding to the id in accession_analysis&lt;br /&gt;&lt;/pre&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;But clearly, I don't know how to express this as SQL yet.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-6296461704924360836?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/6296461704924360836/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=6296461704924360836' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/6296461704924360836'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/6296461704924360836'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2011/08/more-fun-with-sql.html' title='More Fun With SQL'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-9125330319823850092</id><published>2011-08-15T03:38:00.001-04:00</published><updated>2011-08-15T09:44:48.502-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='computers'/><category scheme='http://www.blogger.com/atom/ns#' term='command-line'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>Command Line Comments</title><content type='html'>&lt;div&gt;Just read &lt;a href="http://lenz.unl.edu/2011/04/09/life-on-the-command-line.html"&gt;Life on the Command Line&lt;/a&gt;, wherein the author explains how he does &lt;i&gt;everything everything everything&lt;/i&gt; on the command line these days&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I'm largely sympathetic. Honestly. And I'm close. Look at my work Linux box and you'll see a good half-dozen terminal windows open. I'm a programmer whose two primary programming styles are command-line/batch/crontab and web programming, so I am much more comfortable with those styles and their explicit order than the GUI developers.&lt;br /&gt;&lt;br /&gt;But I have sort of a guilty secret.&lt;br /&gt;&lt;br /&gt;I spend most of my programming time using KomodoEdit.&lt;br /&gt;&lt;br /&gt;I have a fairly custom &lt;code&gt;.vimrc &lt;/code&gt; that allows me to do cool things in vi, but beyond crontab editing and other things that look for $EDITOR, I only use vi when I want to do lots of specific and repetitive find-replace stuff or need to do small changes, or when I'm using SSH to connect to a system and not using SSHFS to mount it. My heavy lifting for editors is done via KomodoEdit.&lt;br /&gt;&lt;br /&gt;And that isn't it. Not by a long shot.&lt;br /&gt;&lt;br /&gt;I have a significant amount of music. I used to use Rhythmbox as my media player because it allowed me to use and thus alias a command-line interface. On that system, I would have &lt;code&gt;rhythmbox-client --play &lt;/code&gt;,&lt;code&gt;rhythmbox-client --pause &lt;/code&gt;,  &lt;code&gt;rhythmbox-client --previous &lt;/code&gt; and  &lt;code&gt;rhythmbox-client --next &lt;/code&gt; aliased to  &lt;code&gt;play &lt;/code&gt;,   &lt;code&gt;pause &lt;/code&gt;,  &lt;code&gt;prev &lt;/code&gt; and  &lt;code&gt;next &lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;I stopped for a few reasons. I now have a Windows machine that I use for testing web dev in different browsers, and, when I play my media, I play via Windows Media Player, in part because playing and queueing media that I have but didn't have in my media library made Rhythmbox unhappy. But, between Amazom, Google, Rdio, Pandora and Spotify (which I love), I hardly listen to that huge library anymore, because either I have much of that library up already or I'm streaming stuff I want but don't have. And those tools don't give me a command-line option.&lt;br /&gt;&lt;br /&gt;It gets to what tool is powerful enough to allow me to do what I need to. With music, I need it on and going, and paused on occasion.&lt;br /&gt;&lt;br /&gt;Don't get me wrong. I'm with him at least in part about mail sorting. Before web tools and Thunderbird, my preferred mail client was PINE, but there's functional reasons that I can't remember anymore that I moved the one remaining command-line mail account from the nmap-based sorting from mh/nmh to procmail. IIRC, I liked the syntax for mh better but I found that SpamAssassin worked better with procmail, and I desperately needed SpamAssassin. The sorting choices I get from both Gmail and Zimbra are both clunkier than a nice mh or procmail script. But I spend little of my time in email, so that shouldn't make much of a difference.&lt;br /&gt;&lt;br /&gt;Anyway, interesting read.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-9125330319823850092?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/9125330319823850092/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=9125330319823850092' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/9125330319823850092'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/9125330319823850092'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2011/08/just-read-life-on-command-line-wherein.html' title='Command Line Comments'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-4886206507762918630</id><published>2011-08-10T16:54:00.000-04:00</published><updated>2011-08-10T16:54:49.804-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sql'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>Fun with SQL</title><content type='html'>If you want to put one thing into a database, that's easy.&lt;pre class="sql" name="code"&gt; INSERT INTO table_1 (field_1 , field_2 , field_3 ) VALUES ( 4 , 1 , 2 ) ; &lt;/pre&gt;I've been putting lots of things into &lt;code&gt;table_1&lt;/code&gt; that are in &lt;code&gt;table_2&lt;/code&gt;, where there are &lt;i&gt;n&lt;/i&gt; instances of &lt;code&gt;table_1&lt;/code&gt; in each &lt;code&gt;table_2&lt;/code&gt;. This lead me to something like this.&lt;pre class="perl" name="code"&gt; &lt;br /&gt;my $sql ;&lt;br /&gt;$sql = &lt;&lt; 'SQL'&lt;br /&gt;SELECT id FROM table_2 WHERE field_3 = ?&lt;br /&gt;SQL&lt;br /&gt;my $ptr = db_arrayref( $sql , $param-&gt;{ field_3 } ) ;&lt;br /&gt;&lt;br /&gt;$sql = &lt;&lt; 'SQL'&lt;br /&gt;INSERT INTO table_1 ( &lt;br /&gt;    field_1 , field_2 , field_3 &lt;br /&gt;    ) &lt;br /&gt;VALUES (&lt;br /&gt;    ? , ? , ?&lt;br /&gt;    )&lt;br /&gt;SQL&lt;br /&gt;&lt;br /&gt;map {&lt;br /&gt;   my @vals ;&lt;br /&gt;   push @vals , $param-&gt;{ a } ;&lt;br /&gt;   push @vals , $param-&gt;{ b } ;&lt;br /&gt;   push @vals , $_ ;&lt;br /&gt;    }  @$ptr ;&lt;br /&gt;&lt;/pre&gt;That's OK for what it is, but what that ends up meaning is lots of small SQL commands sent to the server. SQL handles the commands well, but the opening and closing of network connections is just sort of sucky, so, that's not optimal. So, if  you can just send one command, that's what you want. And in this case, the command is this:&lt;pre class="sql" name="code"&gt; &lt;br /&gt;INSERT INTO table_1 ( field_1 , field_2 , field_3 ) &lt;br /&gt;    SELECT &lt;br /&gt;    1 ,&lt;br /&gt;    2 ,&lt;br /&gt;    field_3 FROM table_2 WHERE field_3 = ?&lt;br /&gt;    ; &lt;/pre&gt;Isn't SQL wonderful?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-4886206507762918630?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/4886206507762918630/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=4886206507762918630' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/4886206507762918630'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/4886206507762918630'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2011/08/fun-with-sql.html' title='Fun with SQL'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-4321171304232056797</id><published>2011-08-01T15:02:00.000-04:00</published><updated>2011-08-01T15:02:10.633-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='removing pessimizations'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='sucking'/><category scheme='http://www.blogger.com/atom/ns#' term='frustration'/><title type='text'>Failure to Plan is Planning to Fail</title><content type='html'>I have a database table full of requests. When that table is filled, we also put together a wiki page for that request, because the the data we generate for each request can be fairly free-form. This means that we effectively divorce the state of the DB for a given request and the state of the wiki.&lt;br /&gt;&lt;br /&gt;There are certain fields that are on the wiki page and not the database. Specifically, contact information for the person making the request. It made sense to me, at the time. I think it was based upon the data separation issue, or that we actually hold that in a profile, too, but I can't remember right now.&lt;br /&gt;&lt;br /&gt;Now, my boss wants to be able to regenerate the wiki page for quick-and-easy refresh. Regenerate the DB stuff into a new wiki page and cut-and-paste the non-DB stuff from the old page to the new page. Easy-peasy. Except, I don't store all the data in the database.&lt;br /&gt;&lt;br /&gt;So, now, I'm looking at adding columns to the table to handle said contact information and spidering the contact info off the wiki pages. If I had just put it into the database in the first place...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-4321171304232056797?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/4321171304232056797/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=4321171304232056797' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/4321171304232056797'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/4321171304232056797'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2011/08/failure-to-plan-is-planning-to-fail.html' title='Failure to Plan is Planning to Fail'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-2491159999478132167</id><published>2011-07-29T16:10:00.002-04:00</published><updated>2011-07-29T16:10:20.122-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>More Javascript Didacticisms: Namespaces</title><content type='html'>&lt;div&gt;For the draft page in the Blogger dashboard, I'm seeing sixteen javascript libraries and five extensions running in Chrome. That's a lot. Think about that next time you type &lt;code&gt; var scratch = "something" &lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;If you want to use &lt;code&gt;scratch&lt;/code&gt; and so does the person who wrote the popup library, your code might not work. I learned this when I was writing test code to properly create objects for jQuery's post(). I was sharing a variable that contained the URL for the JSON I was grabbing, and when I had Before commented out, After worked perfectly, but otherwise, it all crashed.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;The solution? Objects.&lt;/div&gt;&lt;div&gt;&lt;pre class="javascript" name=" code"&gt;var my_ns = {&lt;br /&gt;    foo : x' ,&lt;br /&gt;    bar : 14 ,&lt;br /&gt;    blee : function () {&lt;br /&gt;        ...&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;$(function() {&lt;br /&gt;    my_ns.blee()&lt;br /&gt;    } )&lt;br /&gt;&lt;/pre&gt;&lt;pre class="javascript" name=" code"&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-2491159999478132167?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/2491159999478132167/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=2491159999478132167' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/2491159999478132167'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/2491159999478132167'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2011/07/more-javascript-didacticisms-namespaces.html' title='More Javascript Didacticisms: Namespaces'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-1064034842929795953</id><published>2011-07-28T14:57:00.003-04:00</published><updated>2011-07-28T14:58:23.498-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='jquery'/><category scheme='http://www.blogger.com/atom/ns#' term='ajax'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='frustration'/><title type='text'>Thank you, Stack Overflow!</title><content type='html'>I have to thank &lt;a href="http://stackoverflow.com/"&gt;Stack Overflow&lt;/a&gt; again.&lt;br /&gt;&lt;br /&gt;I code everything from SQL to Javascript, and that means that I don't really get to become expert in everything. I do alright, but there's occasionally things I just don't get, and I don't really have a community of developers around me to ask.&lt;br /&gt;&lt;br /&gt;My most recent problem relates to hashes in Javascript connecting to JSON. You can make arrays behave like hashes in Javascript:&lt;br /&gt;&lt;br /&gt;&lt;pre class="javascript" name="code"&gt;&lt;br /&gt;&lt;br /&gt;var hash = new Array()&lt;br /&gt;&lt;br /&gt;hash['foo'] = 1&lt;br /&gt;&lt;br /&gt;alert( hash.foo )&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;My problem was with post, the jQuery method to do AJAX with large data sets. This didn't work.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="javascript" name="code"&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;$.post( url , hash , function() { ... } , 'json' )&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Because hash is an abused array, not an object. Before I figured it out, today, thanks to SO, I make a long string that looked like &lt;code&gt; { 'foo' : '1' , 'bar' : '2' } &lt;/code&gt; and ran &lt;code&gt;eval&lt;/code&gt; on it. Bad bad bad bad &lt;i&gt;bad&lt;/i&gt;. I now know that it should work like this:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;pre class="javascript" name="code"&gt;&lt;br /&gt;&lt;br /&gt;var hash = {}&lt;br /&gt;&lt;br /&gt;hash['foo'] = 1&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;$.post( url , hash , function() { ... } , 'json' )&lt;/div&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Thanks again, StackOverflow!&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-1064034842929795953?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/1064034842929795953/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=1064034842929795953' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/1064034842929795953'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/1064034842929795953'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2011/07/i-have-to-thank-stack-overflow-again.html' title='Thank you, Stack Overflow!'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-7409327809088285875</id><published>2011-07-27T12:29:00.001-04:00</published><updated>2011-07-27T12:29:48.557-04:00</updated><title type='text'>What to do with massive amounts of computrons, plus quitting in front of people</title><content type='html'>&lt;iframe allowfullscreen="" frameborder="0" height="349" src="http://www.youtube.com/embed/vKmQW_Nkfk8" width="560"&gt;&lt;/iframe&gt;&lt;br /&gt;&lt;div&gt;I &lt;i&gt;am&lt;/i&gt;&amp;nbsp;in the bioinformatics space. Irony is, there's no way I could've paid to attend OSCON.&amp;nbsp;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-7409327809088285875?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/7409327809088285875/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=7409327809088285875' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/7409327809088285875'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/7409327809088285875'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2011/07/what-to-do-with-massive-amounts-of.html' title='What to do with massive amounts of computrons, plus quitting in front of people'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://img.youtube.com/vi/vKmQW_Nkfk8/default.jpg' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-1320586248405991899</id><published>2011-06-30T10:31:00.000-04:00</published><updated>2011-06-30T10:31:19.100-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='we live in the future'/><title type='text'>Dialup Slowdown</title><content type='html'>&lt;iframe width="480" height="273" src="http://www.youtube.com/embed/IF2v32xCD0Y" frameborder="0" allowfullscreen&gt;&lt;/iframe&gt; &lt;br /&gt;&lt;br /&gt;This is the dialup handshake, slowed down 700x. &lt;br /&gt;&lt;br /&gt;I used to have a 2400 baud (call it ~2Kb/m) and I'm now getting 5MB/s, which is more than a 700x speedup.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-1320586248405991899?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/1320586248405991899/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=1320586248405991899' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/1320586248405991899'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/1320586248405991899'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2011/06/dialup-slowdown.html' title='Dialup Slowdown'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://img.youtube.com/vi/IF2v32xCD0Y/default.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-6623853139913358581</id><published>2011-06-29T13:05:00.000-04:00</published><updated>2011-06-29T13:05:39.464-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='perl'/><title type='text'>My .perltidyrc</title><content type='html'>Especially when working with others, it is important to be able to format your code. Perl Best Practices convinced me to start using PerlTidy, and this is my current .perltidyrc.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;# my .perltidyrc config file&lt;br /&gt;#   http://perldoc.perl.org/perlstyle.html&lt;br /&gt;&lt;br /&gt;  --backup-and-modify-in-place&lt;br /&gt;  #--cuddled-else&lt;br /&gt;  --continuation-indentation=4&lt;br /&gt;  --indent-columns=4&lt;br /&gt;  --maximum-line-length=78&lt;br /&gt;  #--line-up-parentheses&lt;br /&gt;  --opening-brace-always-on-right&lt;br /&gt;  --noopening-sub-brace-on-new-line #  -nsbl        # opening sub braces on right&lt;br /&gt;  --indent-closing-brace  # thought this was -ibc&lt;br /&gt;  --indent-block-comments #  -icb         # indent comment blocs&lt;br /&gt;  --vertical-tightness=0&lt;br /&gt;  --vertical-tightness-closing=0&lt;br /&gt;  --closing-token-indentation=3&lt;br /&gt;  --stack-opening-tokens&lt;br /&gt;  #--stack-closing-tokens&lt;br /&gt;  --space-terminal-semicolon&lt;br /&gt;  --space-for-semicolon&lt;br /&gt;&lt;br /&gt;  --brace-tightness=0&lt;br /&gt;  --paren-tightness=0&lt;br /&gt;  --block-brace-tightness=0&lt;br /&gt;  --square-bracket-tightness=0&lt;br /&gt;  --no-outdent-long-quotes&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-6623853139913358581?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/6623853139913358581/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=6623853139913358581' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/6623853139913358581'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/6623853139913358581'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2011/06/my-perltidyrc.html' title='My .perltidyrc'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-3818096468609853584</id><published>2011-06-27T23:35:00.000-04:00</published><updated>2011-06-27T23:35:14.676-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='we live in the future'/><title type='text'>I Keep Telling People!</title><content type='html'>&lt;a href="http://www.reddit.com/r/raldi/comments/i91og/todays_real_life_is_yesterdays_science_fiction/"&gt;This guy on Reddit&lt;/a&gt;&amp;nbsp;points out that, in 1996, a simple statement of many of our regular lives would be taken as science fiction. &lt;br /&gt;&lt;blockquote&gt;&lt;em&gt;Mary pulled out her pocket computer and scanned the datastream. It established contact with satellites screaming overhead, triangulated her position, and indicated there was an available car just a few blocks away; she swiped her finger across the glass screen to reserve it. A few minutes later, she spotted the little green hatchback and tapped her bag against the door to unlock it. "Bummer," she said as she glanced at her realtime traffic monitor. "Accident on the Bay Bridge. I'll have to take the San Mateo. Computer, directions to Oakland airport. Fastest route." Meanwhile, she pulled up Kevin's flight on the viewscreen. The plane icon was blipping over the Sierra Nevadas and arrival would be in half an hour. She wrote him a quick message: "Running late. Be there soon. See if you can get a pic of the mountains for our virtual photospace."&lt;/em&gt;&lt;/blockquote&gt;This is not a new thought. I worked in a used bookstore during my first&amp;nbsp;sojourn&amp;nbsp;in academia, around the summer of 1991, five years before the point in question. At that time, I was big into cyberpunk science fiction. Bruce Sterling and William Gibson. I was putting things away, cleaning up the place, when I saw a book centered upon a computer hacker. It wasn't in the science fiction section. It wasn't even in the true crime section like Cliff Stoll's &lt;em&gt;The Cuckoo's Egg&lt;/em&gt;. It was in mystery. That was the point where science fiction stopped being about futurism for me.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-3818096468609853584?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/3818096468609853584/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=3818096468609853584' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/3818096468609853584'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/3818096468609853584'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2011/06/i-keep-telling-people.html' title='I Keep Telling People!'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-8041753287892148880</id><published>2011-06-12T00:23:00.000-04:00</published><updated>2011-06-12T00:23:42.910-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>Lovin' Me Some Gingerbread</title><content type='html'>So, last night, I forgot to plug in my phone, which is an HTC Evo, an Android phone. I've had it since November, and if I forgot the overnight charging, I'd have a dead phone.&lt;br /&gt;&lt;br /&gt;I had something like 77% charge this morning.&lt;br /&gt;&lt;br /&gt;I love the Power Management under Gingerbread.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-8041753287892148880?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/8041753287892148880/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=8041753287892148880' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/8041753287892148880'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/8041753287892148880'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2011/06/lovin-me-some-gingerbread.html' title='Lovin&apos; Me Some Gingerbread'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-3979707878889189254</id><published>2011-06-10T10:18:00.001-04:00</published><updated>2011-06-10T10:19:29.909-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='chrome'/><category scheme='http://www.blogger.com/atom/ns#' term='frustration'/><title type='text'>Remixing for Cache</title><content type='html'>I have a web thing. I did the server end stuff in Perl and right now adding some UI usefulness stuff with Javascript. I'm doing this using Chrome as my #1 browser, under Windows 7 64-bit, and I'm finding a problem.&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Specifically, I make changes in the .js file and can't get Chrome to load the changes. I know that I can get that with &lt;code&gt;CTRL SHIFT DEL &lt;/code&gt;, but with Firefox, if you hit&amp;nbsp;&lt;code&gt;CTRL SHIFT R &lt;/code&gt; on Firefox (and I think IE, but I've &lt;i&gt;never&lt;/i&gt;&amp;nbsp;been a big IE user so I'm not sure), and I somewhat recall that behavior as something Chrome did but no longer does. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Anyway, GRRR.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-3979707878889189254?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/3979707878889189254/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=3979707878889189254' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/3979707878889189254'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/3979707878889189254'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2011/06/remixing-for-cache.html' title='Remixing for Cache'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-3995263793583737342</id><published>2011-06-09T16:14:00.000-04:00</published><updated>2011-06-09T16:14:53.581-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='evo'/><category scheme='http://www.blogger.com/atom/ns#' term='telephony'/><category scheme='http://www.blogger.com/atom/ns#' term='sprint'/><category scheme='http://www.blogger.com/atom/ns#' term='frustration'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>Anger Subsides</title><content type='html'>I don't know if it was Sprint getting it's act together.&lt;br /&gt;&lt;br /&gt;I don't know if it was Google getting it's act together.&lt;br /&gt;&lt;br /&gt;I don't know if anyone from either saw &lt;a href="http://varlogrant.blogspot.com/2011/05/angry-at-sprint-angry-at-google-voice.html"&gt;my blog post&lt;/a&gt; and felt my anger.&lt;br /&gt;&lt;br /&gt;I don't know if moving from Froyo to Gingerbread made all the difference.&lt;br /&gt;&lt;br /&gt;But I have now fully connected my Sprint phone running Android to Google Voice. And I am happy.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-3995263793583737342?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/3995263793583737342/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=3995263793583737342' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/3995263793583737342'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/3995263793583737342'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2011/06/anger-subsides.html' title='Anger Subsides'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-2302326033348268580</id><published>2011-06-04T03:46:00.000-04:00</published><updated>2011-06-04T03:46:20.460-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='computers'/><category scheme='http://www.blogger.com/atom/ns#' term='hacks'/><category scheme='http://www.blogger.com/atom/ns#' term='hardware'/><title type='text'>Want To See Something Cool? or Why I Wish I Was A Hardware Hacker, Pt 2</title><content type='html'>&lt;a href="http://blog.2yb.org/2010/07/cd-case-wearable-computer.html?utm_source=feedburner&amp;amp;utm_medium=feed&amp;amp;utm_campaign=Feed%3A+BeagleBoard+%28BeagleBoard.org%29"&gt;Follow this link.&lt;/a&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Glasses-mounted display. Which is connected to a 1GHz&amp;nbsp;&lt;a href="http://beagleboard.org/"&gt;Beagle Board&lt;/a&gt;, powered by batteries to make it mobile.&amp;nbsp;Man, that's cool.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I thought about linking the image, but I'm not seeing "Creative Commons" anywhere on there.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Following the links to the guy's current &lt;a href="http://www.martinmagni.com/blog/cyborg/"&gt;blog&lt;/a&gt;, I saw that it's relatively simple to solder on an RCA cable, which makes the composite link to the myvu glasses. I'm thinking you could get readable console mode with that, which is good. Wouldn't want to try a windowed interface.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-2302326033348268580?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/2302326033348268580/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=2302326033348268580' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/2302326033348268580'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/2302326033348268580'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2011/06/want-to-see-something-cool-or-why-i.html' title='Want To See Something Cool? or Why I Wish I Was A Hardware Hacker, Pt 2'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-5600250786430251295</id><published>2011-05-23T09:55:00.000-04:00</published><updated>2011-05-23T09:55:26.215-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='computers'/><category scheme='http://www.blogger.com/atom/ns#' term='we live in the future'/><title type='text'>The Future of Desktops</title><content type='html'>&lt;embed allowfullscreen="true" allowscriptaccess="always" bgcolor="#000000" flashvars="config=http://www.themis-media.com/videos/config/2911-f2ec38f00580c7d9fd87b4cb2277da3b.js%3Fplayer_version%3D2.5%26embed%3D1" height="391" pluginspage="http://www.adobe.com/go/getflashplayer" quality="high" src="http://cdn2.themis-media.com/media/global/movies/player/flowplayer.commercial-3.2.5.swf" type="application/x-shockwave-flash" width="650" wmode="opaque"&gt;&lt;/embed&gt;&lt;br /&gt;I don't know that I agree 100% with this assessment, but I can say that I agree at least 80% with it. The new form factors of laptops, netbooks, tablets, game systems and smartphones are doing most of what the desktop was doing. You want to browse and write something at the desk or do you want to do it on the couch in front of the TV? (The TV has it's own set of computing additions, as I've covered previously, so I won't go in depth here. Except to say that a friend has a Samsung Smart TV, and &lt;i&gt;my goodness&lt;/i&gt;, what a sexy bitch it is.)&lt;br /&gt;&lt;br /&gt;Here's the thing: I get my money to buy post-PC gadgets by doing one of few jobs I don't think you can really do without the PC. I am a programmer, and I have two PCs at my desk and three monitors. And I &lt;i&gt;do&lt;/i&gt; use them. I have virtual desktops on each computer so I can switch between what I'm seeing on each. If I'm doing web development, I tend to have a web browser with documentation on one, editors on the other, and the page I'm working on at a third. One 13" or less screen isn't going to be able to take the place of 3 21"+ screens.&lt;br /&gt;&lt;br /&gt;I like the modularity of desktop machines. You can open them up and tell that this is the power supply, this is the hard drive, this is the motherboard, this is the CD drive, etc. If you know which part I think I touch on how archaic this thought is by my using "CD drive" and not DVD drive, Blu-Ray Drive or Optical Drive. A laptop isn't. If the screen goes, if the drive goes, if the USB port is busted, your only choice is to get a new one. It is, in engineering terms, a &lt;a href="http://en.wikipedia.org/wiki/Black_box"&gt;black box&lt;/a&gt;. You know the outputs, you know the inputs, but you don't have an idea of what's going on inside or how to change or fix it.&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://3.bp.blogspot.com/-0js1TS3jJrg/TY48Q0mWKrI/AAAAAAAABm8/ZnEfJfCd6_w/s1600/IMAG0238.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="191" src="http://3.bp.blogspot.com/-0js1TS3jJrg/TY48Q0mWKrI/AAAAAAAABm8/ZnEfJfCd6_w/s320/IMAG0238.jpg" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;A Black Box&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&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://1.bp.blogspot.com/-ObtFZEjWgzU/TdplGhy01qI/AAAAAAAABsE/8-NHpu9tn0s/s1600/nintendo_wii_b.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="240" src="http://1.bp.blogspot.com/-ObtFZEjWgzU/TdplGhy01qI/AAAAAAAABsE/8-NHpu9tn0s/s320/nintendo_wii_b.jpg" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Another Black Box&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&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/-V_J29xrloos/TdpkrSK1NiI/AAAAAAAABsA/f7GYpSWRtyU/s1600/dell_gx260_tower.jpg" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="320" src="http://4.bp.blogspot.com/-V_J29xrloos/TdpkrSK1NiI/AAAAAAAABsA/f7GYpSWRtyU/s320/dell_gx260_tower.jpg" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Not A Black Box&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;It is clear to me that, for most things, the desktop is a dead thing. And for most things, I don't mourn it. I for one welcome our new gadget overlords. I love having a screen in my car, streaming music and giving me directions. I love having our TV get content from Netflix and &lt;a href="http://thatguywiththeglasses.com/"&gt;That Guy With The Glasses&lt;/a&gt; as well as NBC and Comedy Central. I love being able to go from "The guy who played Ted Bundy in that movie" to "Mark Harmon" with a quick search of IMDB, without having to get up from the couch. I like it all and I want more.&lt;br /&gt;&lt;br /&gt;But the guys who tell the things how to do what they do will be sitting at a keyboard behind big screens for the foreseeable future.&lt;br /&gt;&lt;br /&gt;&lt;iframe allowfullscreen="" frameborder="0" height="349" src="http://www.youtube.com/embed/grbSQ6O6kbs" width="425"&gt;&lt;/iframe&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-5600250786430251295?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/5600250786430251295/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=5600250786430251295' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/5600250786430251295'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/5600250786430251295'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2011/05/future-of-desktops.html' title='The Future of Desktops'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-0js1TS3jJrg/TY48Q0mWKrI/AAAAAAAABm8/ZnEfJfCd6_w/s72-c/IMAG0238.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-8165255982127632663</id><published>2011-05-20T09:44:00.001-04:00</published><updated>2011-05-20T09:45:13.965-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='computers'/><category scheme='http://www.blogger.com/atom/ns#' term='new gear day'/><title type='text'>Unboxing Porn - Lenovo ideapad</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;This is my new laptop, a Lenovo ideapad.&lt;/div&gt;&lt;div class="separator" style="clear: both; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/--n2j20CZWMY/TdZIdpTJRrI/AAAAAAAABrk/I_xhcZpL7ws/s1600/IMAG0317.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="238" src="http://3.bp.blogspot.com/--n2j20CZWMY/TdZIdpTJRrI/AAAAAAAABrk/I_xhcZpL7ws/s400/IMAG0317.jpg" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;I have named it Gort.&lt;/div&gt;&lt;div class="separator" style="clear: both; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-align: center;"&gt;&lt;a href="http://2.bp.blogspot.com/-Xi3NkAQcMk8/TdZIjq2SbMI/AAAAAAAABro/XN8pI-jlRzM/s1600/IMAG0318.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="238" src="http://2.bp.blogspot.com/-Xi3NkAQcMk8/TdZIjq2SbMI/AAAAAAAABro/XN8pI-jlRzM/s400/IMAG0318.jpg" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;That fits the convention for all my computers.&amp;nbsp;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;span class="Apple-style-span" style="color: #0000ee;"&gt;&lt;img border="0" height="238" src="http://1.bp.blogspot.com/-8cncw722CVA/TdZIoRs_8eI/AAAAAAAABrs/K_kK7c44qq0/s400/IMAG0319.jpg" width="400" /&gt;&lt;/span&gt;&amp;nbsp;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;It's pretty. I like it.&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&amp;nbsp;&lt;a href="http://2.bp.blogspot.com/-rfN4wAsaIp0/TdZIXE9_5TI/AAAAAAAABrc/z-e0ZPYBjzk/s1600/IMAG0321.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="238" src="http://2.bp.blogspot.com/-rfN4wAsaIp0/TdZIXE9_5TI/AAAAAAAABrc/z-e0ZPYBjzk/s400/IMAG0321.jpg" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&amp;nbsp;I hope to do some programming on it soon.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-8165255982127632663?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/8165255982127632663/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=8165255982127632663' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/8165255982127632663'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/8165255982127632663'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2011/05/unboxing-porn-lenovo-ideapad.html' title='Unboxing Porn - Lenovo ideapad'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/--n2j20CZWMY/TdZIdpTJRrI/AAAAAAAABrk/I_xhcZpL7ws/s72-c/IMAG0317.jpg' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-9155799018661320937</id><published>2011-05-19T09:02:00.000-04:00</published><updated>2011-05-19T09:02:53.248-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='google'/><category scheme='http://www.blogger.com/atom/ns#' term='frustration'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>Problem with the new Music for Android, I think...</title><content type='html'>I like &lt;a href="http://buddymiller.com/"&gt;Buddy Miller&lt;/a&gt;. I like his new album, &lt;i&gt;&lt;a href="http://www.amazon.com/Majestic-Silver-Strings-Buddy-Miller/dp/B004I2EWMI"&gt;The Majestic Silver Strings&lt;/a&gt;&lt;/i&gt;, with Marc Ribot, Bill Frisell and Greg Leisz. But as much as it seems like something I'd do, I haven't listened to "Meds" full-time for the last 24 hours. Honestly, it does sound like something I would do, but no.&lt;br /&gt;&lt;br /&gt;Here's the thing. I've been using the new &lt;a href="https://market.android.com/details?id=com.google.android.music&amp;amp;feature=search_result"&gt;Music&lt;/a&gt; from Google on my Android phone. I have &lt;a href="https://market.android.com/details?id=fm.last.android&amp;amp;feature=search_result"&gt;Last.FM&lt;/a&gt; set to scrobble, and for nearly everything else (Pandora, old Music), it scrobbled the songs fine. I &lt;i&gt;think&lt;/i&gt;&amp;nbsp;the issue is that the new Music, which is still in beta, isn't telling whatever Last.FM reads that it paused or stopped, which means that Last.FM thinks that "Meds" is the Song That Never Ends. Oh so fun.&lt;br /&gt;&lt;br /&gt;So, how do I file this bug?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-9155799018661320937?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/9155799018661320937/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=9155799018661320937' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/9155799018661320937'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/9155799018661320937'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2011/05/problem-with-new-music-for-android-i.html' title='Problem with the new Music for Android, I think...'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-5694933137891205627</id><published>2011-05-13T15:31:00.000-04:00</published><updated>2011-05-13T15:31:32.882-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='hacks'/><category scheme='http://www.blogger.com/atom/ns#' term='frustration'/><title type='text'>Why I Wish I Was A Hardware Hacker</title><content type='html'>In our lab, we have a device&amp;nbsp;that we call the &lt;i&gt;Minus 80&lt;/i&gt;. We call it that because it is a freezer that is meant to store our samples at -80°C, or -112°F. For our purposes, as I understand them, this is not as much overkill as you might think, and there are people who get &lt;i&gt;very&lt;/i&gt;&amp;nbsp;concerned when it drops below, or rather, when it pops above -70°C. Drag out from the wall and point the big fan at the coils concerned. Conversations with HVAC guys are so loud you can hear them on the other side of a closed door concerned. Last summer, environmental issues surrounding this and other instruments (here meaning "not a computer") were a primary concern that affected use every day.&lt;br /&gt;&lt;br /&gt;The unit in question has a digital readout of the current temperature, on a glowing LED mounted at about shin-height, which is not optimal if you're hoping to monitor the temperature. Which leads me to something that I am very sure I saw on the &lt;a href="http://www.element14.com/community/community/experts/benheck"&gt;Ben Heck Show&lt;/a&gt;, or else on &lt;a href="http://makezine.com/"&gt;Make&lt;/a&gt;. An LED takes a current to light but also four signals to show the number. At least I think so; it's been over a decade since I last tried working with a breadboard. So, given the signal feeding the digital readout, we could run that into something like an Arduino, and from there through more normal means into our database, where we could do alerting should the thing get too warm when nobody is looking.&lt;br /&gt;&lt;br /&gt;Anyone who knows me knows that I love taking data in one form and turning it into another. Web to RSS. RSS to JSON. CSV to PNG. If I can get the temperature out of the freezer — the temperature data, that is — I am sure I can do with it whatever I need to. It is that physical step that befuddles me. Yes, I have been annoyed for a good long time about the Minus 80's lack of serial or USB interface. Now, I have a sense of how to I could actually get there myself.&lt;br /&gt;&lt;br /&gt;Not that the boss would let me take a soldering iron to his Minus 80. Which is a little &lt;i&gt;more&lt;/i&gt; frustrating....&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-5694933137891205627?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/5694933137891205627/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=5694933137891205627' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/5694933137891205627'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/5694933137891205627'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2011/05/why-i-wish-i-was-hardware-hacker.html' title='Why I Wish I Was A Hardware Hacker'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-7300708548013502708</id><published>2011-05-12T13:17:00.000-04:00</published><updated>2011-05-13T16:44:22.484-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cool'/><category scheme='http://www.blogger.com/atom/ns#' term='chrome'/><category scheme='http://www.blogger.com/atom/ns#' term='google'/><category scheme='http://www.blogger.com/atom/ns#' term='chromebook'/><category scheme='http://www.blogger.com/atom/ns#' term='we live in the future'/><category scheme='http://www.blogger.com/atom/ns#' term='computing'/><title type='text'>Don't Throw It In A River</title><content type='html'>&lt;iframe allowfullscreen="" frameborder="0" height="390" src="http://www.youtube.com/embed/TVqe8ieqz10" width="640"&gt;&lt;/iframe&gt;&lt;br /&gt;&lt;div&gt;The ChromeBook. It's a neat thing.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;As a CS guy, I spent a lot of time in the Sun Lab. There, there were row upon row upon row of then high-end Sun boxes, and a thing with them was that when you logged in on one, you had all the settings and configuration and background and files as you had when you logged on at any other machine, and anyone else who came after you had their own configurations. Since I graduated, I haven't seen that nearly as much.&lt;br /&gt;&lt;br /&gt;That's what I like about the idea of the ChromeBook. I use it, log off, pass it to my wife, and her stuff is there not mine. It means that each setup isn't its own delicate little flower, which interrupts our sense of ownership, but that's OK.&lt;br /&gt;&lt;br /&gt;I wonder if something like this is how we're going to handle car computing in the future.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-7300708548013502708?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/7300708548013502708/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=7300708548013502708' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/7300708548013502708'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/7300708548013502708'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2011/05/dont-throw-it-in-river.html' title='Don&apos;t Throw It In A River'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://img.youtube.com/vi/TVqe8ieqz10/default.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-8810889591417976025</id><published>2011-05-03T15:44:00.000-04:00</published><updated>2011-05-03T15:44:33.102-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='evo'/><category scheme='http://www.blogger.com/atom/ns#' term='telephony'/><category scheme='http://www.blogger.com/atom/ns#' term='sprint'/><category scheme='http://www.blogger.com/atom/ns#' term='frustration'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><title type='text'>Angry at Sprint, Angry at Google Voice</title><content type='html'>I am a Sprint user. I have carried an Evo since Thanksgiving. &lt;br /&gt;&lt;br /&gt;I have been a Google user for years. I have been a Google Voice user since it was GrandCentral. When I give people my phone number, I give them my Google Voice number rather than the phone's number. I jumped to having an Android phone as soon as I could swing it, for the smarts of it and in hopes that it would integrate with Google Voice.&lt;br /&gt;&lt;br /&gt;So, when I heard that &lt;a href="http://www.google.com/googlevoice/sprint/"&gt;Sprint was offering Google Voice integration&lt;/a&gt;, I was all over that, signing up and waiting for it to say "Set it up". Which happened today.&lt;br /&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/-GcNx6My5ubc/TcBOSrZbS1I/AAAAAAAABo8/Fq_f6FWHMDA/s1600/voice.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="177" src="http://3.bp.blogspot.com/-GcNx6My5ubc/TcBOSrZbS1I/AAAAAAAABo8/Fq_f6FWHMDA/s400/voice.png" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Currently, I have a certain amount of integration. When I'm called at Voice, it rings on my hip. When I call, their caller ID says my voice number. So, I'm largely integrated. But there is a number I never use, and I'd rather dump it and always use my Google Voice Number.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="color: red;"&gt;Unfortunately, Google Voice cannot be enabled on this Sprint phone.&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;b&gt;&lt;span class="Apple-style-span" style="color: red;"&gt;Please contact Sprint for more details as to why this cannot be enabled.&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;So, I called.&lt;br /&gt;&lt;br /&gt;Evidently, the problem is that the HTC Evo is incompatable with Google Voice. They didn't really get into how, but honestly, that seems absolutely stupid. They did suggest I upgrade my phone, but I have a great phone and I don't really see anything I want that I don't have now.&lt;br /&gt;&lt;br /&gt;Which makes me wonder what integration even means.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-8810889591417976025?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/8810889591417976025/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=8810889591417976025' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/8810889591417976025'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/8810889591417976025'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2011/05/angry-at-sprint-angry-at-google-voice.html' title='Angry at Sprint, Angry at Google Voice'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-GcNx6My5ubc/TcBOSrZbS1I/AAAAAAAABo8/Fq_f6FWHMDA/s72-c/voice.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-7960198823018176871</id><published>2011-04-19T15:03:00.000-04:00</published><updated>2011-04-19T15:03:34.983-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='removing pessimizations'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='frustration'/><category scheme='http://www.blogger.com/atom/ns#' term='httpd'/><title type='text'>The Down Side to HTTPS Everywhere</title><content type='html'>&lt;a href="http://www.eff.org/https-everywhere"&gt;HTTPS Everywhere&lt;/a&gt; is a project of the &lt;a href="http://www.eff.org/"&gt;Electronic Frontiers Foundation&lt;/a&gt; (EFF) that seeks to encourage the use of encryption on the web, including a Firefox Add-On that changes links to HTTPS for sites such as Twitter and Facebook. I've &lt;a href="http://varlogrant.blogspot.com/2010/10/encrypt-web.html"&gt;mentioned this before&lt;/a&gt;, and I still think it's a great idea.&lt;br /&gt;&lt;br /&gt;Google has released an encrypted site, &lt;a href="https://encrypted.google.com/"&gt;https://encrypted.google.com/&lt;/a&gt;, where your queries and responses are protected by encryption. But they don't support it for Images and Map queries. And I think I know why.&lt;br /&gt;&lt;br /&gt;A browser can only have &lt;i&gt;n&lt;/i&gt; connections to a website at one time. I think that's generally eight. This means that, if you have an image-heavy site, such as Google Image Search, you can only serve the page, the Javascript, the favicon, and five images, and you have to wait until that's done before you can start working on images six through thirteen, and you need to have all the images there before you can render. The trick is to have a Content Delivery Network (CDN), or a bunch of other servers to serve the images. That way, you can download eight at a time from each node and get 'em as fast as the network will let you.&lt;br /&gt;&lt;br /&gt;But, if you have an HTTPS-served page, the browser considers everything not coming from &lt;em&gt; that server&lt;/em&gt; as a potential breach, as well it should. This means that CDN is a huge problem. That, I think, is why Google isn't using HTTPS Everywhere.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-7960198823018176871?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/7960198823018176871/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=7960198823018176871' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/7960198823018176871'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/7960198823018176871'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2011/04/down-side-to-https-everywhere.html' title='The Down Side to HTTPS Everywhere'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-2557359593851464583</id><published>2011-04-17T10:06:00.001-04:00</published><updated>2011-04-17T10:58:24.690-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='television'/><category scheme='http://www.blogger.com/atom/ns#' term='frustration'/><title type='text'>Streaming Problem</title><content type='html'>&lt;div&gt;I run Boxee on two machines. First is a fairly modern Vista-running machine, connected via wired ethernet to my modem/router/switch/access-point. The second is a Dell Optiplex running XP that was being retired from university use when I got it, connected to the network with a Netgear USB WiFi dongle.&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I have demonstrated that I can serously hinder the ability of the second to stream, simply by surfing the web via my netbook. I don't know which part of the chain is the weak point, and even the strong points are not strong on a PC that old. My friend Patrick says that running CAT6 through the home is kinda worthless for most people because home broadband bandwidth are and will be much smaller than even older WiFi protocols. I understand this and believe it, but problems like this make me wonder.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-2557359593851464583?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/2557359593851464583/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=2557359593851464583' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/2557359593851464583'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/2557359593851464583'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2011/04/streaming-problem.html' title='Streaming Problem'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-3477336845102041353</id><published>2011-04-13T22:27:00.001-04:00</published><updated>2011-04-13T22:27:14.936-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='latitude'/><category scheme='http://www.blogger.com/atom/ns#' term='gps'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='we live in the future'/><title type='text'>Do People Really Want Geolocation?</title><content type='html'>Reading &lt;a href="http://www.readwriteweb.com/archives/2011_the_year_the_check-in_died.php"&gt;&lt;i&gt;2011: The Year the Check-in Died&lt;/i&gt;&lt;/a&gt;&amp;nbsp;on &lt;a href="http://www.readwriteweb.com/"&gt;ReadWriteWeb&lt;/a&gt;. Not too sure what to think of it. Of the people I know, only two people who live in the same city as I am have used any of the check-in services I've dealt with, and for neither was it often enough for the serendipity thing ("Hey! You're at the mall, too? How are you doing?!") to happen. I have yet to find another person who wants to share their lat and long via Google&amp;nbsp;Latitude&amp;nbsp;with me. And, I must admit, there's only a small set of people who I'd do that with.&lt;br /&gt;&lt;br /&gt;The author lists four reasons why people check in to places — Finding people near you, Rewards, Remembering things and Personal Branding&amp;nbsp;— then proceeds to explain why this is trivial and not lasting and nothing to base much on. There's just not much in it for people to tell others where they are.&lt;br /&gt;&lt;br /&gt;But I &lt;i&gt;want&lt;/i&gt; to know where I am. Or, rather, I want my desktop, home of my alerting crontabs, to know that I'm near my work, where it knows to alert me like this, or near my home, where it knows to alert me like that, or somewhere else, where it can alert me with a whiffleball bat. Or something. I don't need my friends to know where I am. I don't really want to tell advertisers or employers where I am. But it would be a great boon to me if I could tell where I am. Screen-based alerts are useless if nobody is at the screen.&lt;br /&gt;&lt;br /&gt;Be aware that Xerox PARC, the Palo Alto Research Center for the Xerox Corporation, invented computing as we know it. One of the things they had were badges that could tell where you were in the facility, so if someone called for you, the telephone nearest to you would ring, no matter where. That's great and all, but today, everyone has their phone on their hip, so standard wired phones are more and more useless and less and less used.&lt;br /&gt;&lt;br /&gt;When I used to work for the medical clinic, I tested badges that could unlock a computer when you got close, and unlock it when I walked away. It seems like it would be easy to write authentication modules that would allow the same thing with Bluetooth, but I'd rather have GPS rolling than Bluetooth most of the time.&lt;br /&gt;&lt;br /&gt;There's a Latitude API, but I haven't done more than poke at it. But I suspect this sort of thing will be the real use of location-based computing.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-3477336845102041353?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/3477336845102041353/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=3477336845102041353' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/3477336845102041353'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/3477336845102041353'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2011/04/do-people-really-want-geolocation.html' title='Do People Really Want Geolocation?'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-7257641010462681092</id><published>2011-04-13T00:57:00.001-04:00</published><updated>2011-04-13T01:02:36.541-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='social media'/><category scheme='http://www.blogger.com/atom/ns#' term='twitter'/><title type='text'>Proper Uses of Social Media: Conferences</title><content type='html'>I heard a story once, about a decade ago. A guy comes in to present on Deep Technical Subject A to a conference room full of people. They all had laptops, and the guy thinks, more and more as his talk goes on, that he's dying, that they're all there by fiat and everyone's just sitting and browsing and hoping for the presentation to be over.&lt;br /&gt;&lt;div&gt;He goes through his slides, giving it his best, and gets to "Are there any questions?"&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;And the questions are good. Well thought out and to the point. Turns out that everyone was on IRC and discussing the points of the presentation as he presented.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;We still have IRC, but you can still wear bow ties and spats if you want. Today's thing is Twitter, and many conference suggest a hash tag by which you can follow and discuss the current goings-on. I've seen it suggested for a few things, and I've been disappointed in the past. I can only hope that it's a flyover-country thing and bigger events in bigger areas have more vibrant tweets. Purdue's BoilerWeb 2011 had some great discussions on the #bweb11 hashtag, and there was some nice interaction at Indiana Linuxfest.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I can understand if people don't want to dive into a stream of people mindlessly photographing their meals for everyone to see, but here is a case where it really makes sense.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-7257641010462681092?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/7257641010462681092/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=7257641010462681092' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/7257641010462681092'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/7257641010462681092'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2011/04/proper-uses-of-social-media-conferences.html' title='Proper Uses of Social Media: Conferences'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-595401586422213295</id><published>2011-04-13T00:38:00.000-04:00</published><updated>2011-04-13T00:38:30.234-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='automobiles'/><category scheme='http://www.blogger.com/atom/ns#' term='technology'/><category scheme='http://www.blogger.com/atom/ns#' term='we live in the future'/><title type='text'>Podcasts and Synergy</title><content type='html'>&lt;table cellpadding="0" cellspacing="0" class="tr-caption-container" style="float: right; margin-left: 1em; text-align: right;"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-XU4xNV9yMEg/TaUUxMvQWYI/AAAAAAAABnU/4dP6A1r4Z2E/s1600/3948820856_b23fd261d7_b.jpg" imageanchor="1" style="clear: right; margin-bottom: 1em; margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="320" src="http://4.bp.blogspot.com/-XU4xNV9yMEg/TaUUxMvQWYI/AAAAAAAABnU/4dP6A1r4Z2E/s320/3948820856_b23fd261d7_b.jpg" width="240" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;Image from &lt;a href="http://www.flickr.com/photos/vr/"&gt;vanRijn&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;I've put Google Listen on my phone, listening to podcasts while I drive. One of them is &lt;a href="http://spectrum.ieee.org/"&gt;Spectrum&lt;/a&gt; from the &lt;a href="http://ieee.org/"&gt;IEEE&lt;/a&gt;, and &lt;a href="http://spectrum.ieee.org/podcast/geek-life/tools-toys/why-the-kinect-connected-with-game-players"&gt;the one that came on my player&lt;/a&gt; was about the Kinect. I have never used the Kinect, as I'm not much of a gamer. Sometimes I'll sit down and play the Wii with the boys, but I have used it more as a Netflix player. So, I'll never use it as intended.&lt;br /&gt;&lt;br /&gt;But the interview is not about intention. It is about capability. The Kinect is able to multiple identify people, both by voice and by vision, in noisy, chaotic environments. People are already starting to hack the Kinect to allow &lt;a href="http://www.youtube.com/watch?v=NwVBzx0LMNQ"&gt;&lt;i&gt;Minority Report&lt;/i&gt;&lt;/a&gt; interfaces and the like.&lt;br /&gt;&lt;br /&gt;The second thing I heard was on &lt;a href="http://hackerpublicradio.org/"&gt;Hacker Public Radio&lt;/a&gt;, which I started to get into after Indiana LinuxFest. The&amp;nbsp;&lt;a href="http://hackerpublicradio.org/eps/hpr0697.mp3"&gt;podcast&lt;/a&gt;&amp;nbsp;itself is a pre-interview discussion between KDE spokesman Aaron Seigo and &lt;a href="http://identi.ca/frostbite"&gt;Jonathan Nadeau&lt;/a&gt; of &lt;a href="http://frostbitesystems.org/"&gt;Frostbite Systems&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Accessability questions have been floating in my head recently. There's lots of buzz about &lt;a href="http://www.section508.gov/"&gt;Section 508&lt;/a&gt;&amp;nbsp;in the circles I float through, enough so I've attended two compliance talks in 2011, and my wife has been trying to be a productive person while having severe pain in her right elbow and forearm that keep her from being able to type. She's been playing with speech recognition software, finally trying the Windows 7 native setup that came with her new laptop.&lt;br /&gt;&lt;br /&gt;But honestly, when thinking about accessability, I wasn't &lt;i&gt;really&lt;/i&gt; thinking about accessibility. I think that there's research at the end of the line for this train of thought that will serve to help accessibility, but it isn't foremost in my head here.&lt;br /&gt;&lt;br /&gt;I was driving. I was thinking about cars.&lt;br /&gt;&lt;br /&gt;As I think I've mentioned, I've been looking at some travel applications. I tend to have either Listen or a media player of one sort or another playing when I drive, rather than CDs or even worse, radio. (I have only one objection to Amazon Cloud Player, which is that it wants to run only on WiFi, and by and large, I want to use my phone as a media player when I'm mobile, away from WiFi, but maybe the coming of 4G or the next software fix from Sprint will fix that.) I have a &lt;a href="http://www.tomtom.com/"&gt;TomTom&lt;/a&gt; GPS showing my location and speed and I sometimes use Sprint or Google for directions, too. Also, I've been looking into &lt;a href="http://www.vlingo.com/"&gt;Vlingo&lt;/a&gt;, which gives a voice interface to phones. I noticed a bug, hopefully fixed soon, where I hit the &lt;i&gt;Talk Now&lt;/i&gt; button while listening to a podcast, and told it to call my wife. Normally, when you tell it to call, it shuts up the media player, Listen included, but here it didn't. So, I'm trying to pause the player and/or mute the player, while on the Interstate.&lt;br /&gt;&lt;br /&gt;I know. &lt;i&gt;I know.&lt;/i&gt; The &lt;i&gt;point&lt;/i&gt; of the exercise is to keep from having this sort of attention-sucking frustration from occurring while I'm driving, because I don't want to hurt myself, my stuff, or other people and their stuff, pretty much in that order. Haven't been too keen of Vlingo since. It's cool enough, but you shouldn't have to press a button while driving to say "I wanna talk now".&lt;br /&gt;&lt;br /&gt;And I don't think the Vlingo is alone. Watch just a few high-end car reviews on &lt;a href="http://www.topgear.com/uk/"&gt;Top Gear&lt;/a&gt; and you'll know that the UIs for even fancy cars are crap.&lt;br /&gt;&lt;br /&gt;Ultimately, to do a driving interface right, you have to assume that there will be no vision at all. Most of the things you do while driving (besides avoiding obstacles and other drivers) occur without vision: you use your sense of touch to feel the vibration and you hear the engine to know when to shift. You see the red &lt;i&gt;Check Engine&lt;/i&gt; light but you take it in when it starts to sound or feel funny. You can even get away with not often checking the speedometer by staying at a similar speed to your fellow drivers. If you're going to do much computing while driving, it'll have to be via voice. And once that shows up in high-end vehicles, that browser is going to rival Firefox and Chrome and IE at the top of the browser food chain.&lt;br /&gt;&lt;br /&gt;(As a pure aside, I think Opera will go there. I don't like Opera and haven't for over a decade, but I know I'm biased on the subject, but it seems like a place that Opera would go, more than anyone else.)&lt;br /&gt;&lt;br /&gt;But as we needed the keyboard and then the mouse to get the WIMP interface for computers into the office and the home, we need to rock a voice interface to get the computer into the car. Which is where the Kinect comes in. I kinda think that the car will be a big docking station for future computers, as seat settings and address books and the like are highly personal but a great deal of hardware is there for anyone who sits down. Kinect-based technology would be necessary to distinguish between the driver, the passenger in the front seat who talks with his hands and the loud kids in the back seat. The recognition between conversations between user and computer and conversations between driver and passengers is crucial, and one I think that Microsoft Research and Kinect are closest.&lt;br /&gt;&lt;br /&gt;There's going to be a small LED screen for the backup camera in the New Car's rear-view mirror (and some cars of today already have it) and a Kinect as well. Of this I am sure.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-595401586422213295?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/595401586422213295/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=595401586422213295' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/595401586422213295'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/595401586422213295'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2011/04/podcasts-and-synergy.html' title='Podcasts and Synergy'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-XU4xNV9yMEg/TaUUxMvQWYI/AAAAAAAABnU/4dP6A1r4Z2E/s72-c/3948820856_b23fd261d7_b.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-2561493415591890391</id><published>2011-04-08T11:36:00.001-04:00</published><updated>2011-04-08T11:37:31.664-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='web apps'/><category scheme='http://www.blogger.com/atom/ns#' term='boilerweb'/><title type='text'>Comments on BoilerWeb 2011 #bweb11</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/-XDW5_1CEaBo/TZ3AmthrYyI/AAAAAAAABnM/v13atCki0sU/s1600/IMAG0246.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" height="191" src="http://4.bp.blogspot.com/-XDW5_1CEaBo/TZ3AmthrYyI/AAAAAAAABnM/v13atCki0sU/s320/IMAG0246.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;I took a paid vacation yesterday and attended &lt;a href="http://www.purdue.edu/"&gt;Purdue&lt;/a&gt;'s &lt;a href="http://www.itap.purdue.edu/boilerweb/"&gt;BoilerWeb &lt;/a&gt;conference. I had a blast. I saw old coworkers and classmates and bosses and had a good ol' time.&amp;nbsp;&lt;span class="fullpost"&gt;    &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;Last year, evidently, it was a one-track thing, but interest was such that there were two tracks. This leads to some minor minor complaints. First was the lack of electricity available. For the first track, this was remedied by an attendee (who shares a job and workspace with one of the organizers) bringing in some power strips from the office, but the orientation of the other room and the modular setup of the floor meant that there was only one jack available at the back of the room. If you're going to follow along, liveblog, tweet and such for an all-day event, you need available power.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;But that is my only complaint, and I can only categorize that as a minor gripe. And &lt;a href="http://varlogrant.blogspot.com/2011/03/notes-on-indiana-linuxfest.html"&gt;unlike the Indiana Linuxfest&lt;/a&gt;, I felt the printed and online scheduling information&amp;nbsp;for this conference&amp;nbsp;was top notch. (Not a slam, ILF guys. Just a pointer on what can be done better next year.)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;First pair of presentations were &lt;i&gt;Know Your Limits&lt;/i&gt;, &amp;nbsp;covering load testing, and &lt;i&gt;jQuery Plugins&lt;/i&gt;. I felt that jQuery Plugins was much more in line with my needs. I write Javascript. I try to write jQuery, which I learned about from a co-worker, but I'm much more the JS guy now and I mostly have experience with my own code, so I don't know the best practices, and have a great tendency to spend time writing my own stuff instead of using used and tested existing plugins. Plus, as I figured out, I kinda clog up the existing namespace, which isn't good. The presenter was very effective, and funny. I really liked his intro use of "Final Countdown" by Europe and high-fiving much of the audience, cheesy at it was, and the &lt;a href="http://builtbywill.com/bweb11/#/slide/1"&gt;presentation&lt;/a&gt; showed him eating his own dogfood, so to speak.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Next choice was &lt;i&gt;Introduction to Responsive Design&lt;/i&gt;&amp;nbsp;vs &lt;i&gt;NanoHUB&lt;/i&gt;. I've know people working with NanoHUB for a while" and while I respect them and their work, it is really orthogonal to anything I expect to ever work with. Meanwhile, Responsive Design as presented was all about writing once and presenting from everything from the desktop to the smartphone with three simple design aspects: Flexible Grid, @Media Queries, and Flexible Images. The coolest part of that, the part that works best with me as a developer, is @media queries. Traditionally, that's used to differentiate different style sheets based upon whether you're looking at it on the screen or printing it. Now, you can put that into the stylesheet and not have to define it in several pages, and make distinctions based upon windows size IN THE CSS. So, one stylesheet. That's the win.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Next was &lt;i&gt;Introduction to Content Strategy&lt;/i&gt;, which in a way is fundamental and in a way is meta to this sort of conference. "Content is king" but we spend more time and more money creating the context than the content. We create a framework and say its done, but it isn't done.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;My first degree was in Journalism and Mass Communication, and as part of the degree, we were required to get an internship. There was a requirement that set our program apart at that time: it had to be a paid internship, because if the internship was unpaid (as the majority of journalism internships were), there was the assumption that you would not be used for real work and thus you wouldn't learn anything. Years later, as I was starting Computer Science, there was a course where they brought in people from industry to present what you could do with a CS degree. One of the first presenters mentioned that he had internships and that you should send him resumes. I asked if they were paid internships. Imagine if I had asked if we would be breathing oxygen and using electricity to light the office. That's the kind of response. As a society, we do not value the content creators like we value the interface creators. This talk kinda covered that, and offered some means to run the process to make and keep your content current.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;There was a presentation on &lt;i&gt;Food For The Heart&lt;/i&gt;, which had Ruby on Rails and data munging aspects I was curious about — need to create a test server and learn some RoR stuff — but instead went to the &lt;i&gt;Class Hacks&lt;/i&gt; presentation on Mixable. Best way to describe it is kinda Facebook for Classrooms, and it does connect to Facebook. By the tweeting of people who saw the "Food" presentation, the main take-away is that &lt;a href="http://www.fatsecret.com/"&gt;Fat Secret&lt;/a&gt;&amp;nbsp;has a nutrition API. This is something I should take a look at. What has my curiosity is Mixable, which I've started to get into for the community of it. Also, a little bit of inspiration in terms of design. I do web design like a web developer: without a real eye for aesthetics and with a tendency to implement new aspects of CSS only until I understand all the controls and get bored. Anyway, Mixable is cool so far.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The talk on &lt;i&gt;Rapid Development in Groups&lt;/i&gt; was like being told to eat my vegetables. I know I should start using revision control. I know I should look into MVCs. I know I should eat my vegetables. Being told is not as useful as one might think. The talk &lt;i&gt;Design Patterns Every Web Developer Should Know&lt;/i&gt;&amp;nbsp;sort of fit into that. Design Patterns is a subject I have heard about, but don't really understand well enough to know why I should spend my valuable time diving deeper. I've started to look into the three presented, but the presenter had time and audience to dive further into each of the three, so the opportunity was a bit wasted, to the point where "Understand the Facade patttern" has joined the vegetable list, too.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;All in all, I think I'm energized and more curious about the possibilities of the newest generation of web technologies. Great conference, guys. Make it better next year.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-2561493415591890391?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/2561493415591890391/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=2561493415591890391' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/2561493415591890391'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/2561493415591890391'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2011/04/comments-on-boilerweb-2011-bweb11.html' title='Comments on BoilerWeb 2011 #bweb11'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-XDW5_1CEaBo/TZ3AmthrYyI/AAAAAAAABnM/v13atCki0sU/s72-c/IMAG0246.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-5509219128747064797</id><published>2011-04-06T13:36:00.000-04:00</published><updated>2011-04-06T13:36:29.646-04:00</updated><title type='text'>Why does it all have to be so terribly loud?</title><content type='html'>&lt;iframe width="425" height="344" src="http://www.youtube.com/embed/ts-2lg5fpQ4?fs=1" frameborder="0" allowfullscreen=""&gt;&lt;/iframe&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="fullpost"&gt;&lt;pre name="code" class="python"&gt;&lt;/pre&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-5509219128747064797?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/5509219128747064797/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=5509219128747064797' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/5509219128747064797'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/5509219128747064797'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2011/04/why-does-it-all-have-to-be-so-terribly.html' title='Why does it all have to be so terribly loud?'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://img.youtube.com/vi/ts-2lg5fpQ4/default.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-1368183552604903375</id><published>2011-04-05T13:54:00.000-04:00</published><updated>2011-04-05T13:54:16.289-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='frustration'/><category scheme='http://www.blogger.com/atom/ns#' term='html'/><category scheme='http://www.blogger.com/atom/ns#' term='css'/><title type='text'>CSS Table Printing Problem</title><content type='html'>So, I have a page that holds lots of tables. These tables are all the schema for a database I use for a project. All 31 of them. The page is basically the &lt;code&gt;DESCRIBE &lt;i&gt;table&lt;/i&gt;&lt;/code&gt; for each table. We're talking usually about 4-8 rows per table. A main reason for creating this page is so we can have the schema taped to the wall.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The problem gets to be that of &lt;i&gt;widows&lt;/i&gt; and &lt;i&gt;orphans&lt;/i&gt;. In layout, a widow is the last line of a paragraph occurring after a page break, while an orphan is a first line of a paragraph occurring before a page break Or, in this case, tables. And it is considered to be bad.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&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/-Befxt3pEhv0/TZs_58klKgI/AAAAAAAABnI/q4ZoweGXSJg/s1600/Screenshot-Second+Generation+--+Schema+-+Mozilla+Firefox.png" imageanchor="1" style="margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" height="191" src="http://4.bp.blogspot.com/-Befxt3pEhv0/TZs_58klKgI/AAAAAAAABnI/q4ZoweGXSJg/s320/Screenshot-Second+Generation+--+Schema+-+Mozilla+Firefox.png" width="320" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;A widowed row.&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;Using &lt;code&gt;THEAD&lt;/code&gt; and &lt;code&gt;TBODY&lt;/code&gt; allows the browser (in this case, Firefox on Linux) to repeat the head of the table, which is nice, but one row of the table isn't enough.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Clearly, these are short enough that forcing the browser to keep the table together through a page break shouldn't be too wasteful, unlike if this was a &lt;code&gt;SELECT * FROM &lt;i&gt;table&lt;/i&gt;&lt;/code&gt; on a table with hundreds or thousands of rows. But it seems this isn't possible with CSS. CSS has&amp;nbsp;&lt;code&gt;page-break-before&lt;/code&gt;,&amp;nbsp;&amp;nbsp;&lt;code&gt;page-break-after&lt;/code&gt; and&amp;nbsp;&amp;nbsp;&lt;code&gt;page-break-inside&lt;/code&gt;, but they are insufficient. You can force a page break before or after an element, but that's not it. If you can fit seven or eight tables on a page, why would you not put them on a page? And there's three options for&amp;nbsp;&amp;nbsp;&lt;code&gt;page-break-inside&lt;/code&gt;: &lt;i&gt;avoid&lt;/i&gt;, &lt;i&gt;auto&lt;/i&gt; and &lt;i&gt;inherit&lt;/i&gt;. The choice of &lt;i&gt;auto&lt;/i&gt;&amp;nbsp;translates to "break it anywhere", while &lt;i&gt;avoid&lt;/i&gt; has all the practical use of "break it anywhere" and &lt;i&gt;inherit&lt;/i&gt;&amp;nbsp;simply means "do what the parent did", which of course means "break it anywhere".&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;There are CSS properties for &lt;i&gt;widows&lt;/i&gt; and &lt;i&gt;orphans&lt;/i&gt;, but they don't seem to work for tables. Well, less with tables than tables wrapped in DIVs.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-1368183552604903375?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/1368183552604903375/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=1368183552604903375' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/1368183552604903375'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/1368183552604903375'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2011/04/css-table-printing-problem.html' title='CSS Table Printing Problem'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-Befxt3pEhv0/TZs_58klKgI/AAAAAAAABnI/q4ZoweGXSJg/s72-c/Screenshot-Second+Generation+--+Schema+-+Mozilla+Firefox.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-7020210021480958035</id><published>2011-03-28T16:58:00.000-04:00</published><updated>2011-03-28T16:58:06.299-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='linuxfest'/><title type='text'>Notes on Indiana Linuxfest</title><content type='html'>Last Friday, Saturday and Sunday were &lt;a href="http://www.indianalinux.org/"&gt;Indiana Linuxfest&lt;/a&gt;, and I had the opportunity to attend Saturday. I got there in time to catch most of the opening keynote (9am) so I was a bit too wiped to really do the party and see &lt;a href="http://dualcoremusic.com/"&gt;dual core&lt;/a&gt;, which saddened me, but I had to be not-sucky on Sunday.&lt;br /&gt;&lt;br /&gt;Here are some notes:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;The flyer should have a venue map so you know right off where you're going. The talks should be organized by day, and if there's going to be a presenter bio, the talk should have the presenter's name on it, so you know who is giving what talk.&lt;/li&gt;&lt;li&gt;First presentation I saw was on Open Hardware, and I came in late. This sucks, because it was cool. Talked some about the &lt;a href="http://www.arduino.cc/"&gt;Arduino&lt;/a&gt;, which I &lt;i&gt;really&lt;/i&gt;&amp;nbsp;need to get, because they're cool. Also mentioned were &lt;a href="http://beagleboard.org/"&gt;Beagle Boards&lt;/a&gt; (I think), which is cool because they're computers the size of a 3.5" floppy disc. Also, the &lt;a href="http://processors.wiki.ti.com/index.php/EZ430-Chronos"&gt;EZ430&lt;/a&gt;, a programmable watch from Texas Instruments. This is everything I thought the programmable Timex Iron Man watch was going to be. His last line was "We live in the future; We might as well start taking advantage of it." A man after my own heart.&lt;/li&gt;&lt;li&gt;Dan Klein,&amp;nbsp;a Googler from Pittsburgh, gave a talk called &lt;i&gt;&lt;a href="http://www.usenix.org/event/lisa09/tech/slides/klein.pdf"&gt;Frank Lloyd Wright was Right&lt;/a&gt;.&lt;/i&gt;&amp;nbsp;In this, he told a story about his hometown, where Wright was asked to suggest a plan to fix some of the architecture problems with Pittsburgh. His advice? "Raze it to the ground and start over." Don't just patch and make due with incremental change, but start over and do it right this time. The presenter suggested this should be the way to take on many of the problems with computing infrastructure, as well.&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.proffitt.org/"&gt;Brian Proffitt&lt;/a&gt; talked about "The Death of the Linux Desktop (and I feel fine)". Great presentation by a great presenter, with good discussion.&lt;/li&gt;&lt;li&gt;The Bloomington Hackerspace, &lt;a href="http://www.bloominglabs.org/index.php/Main_Page"&gt;BloomingLabs&lt;/a&gt;, set up shop at the 'Fest, and that was cool. Hands-on is always cool. I got to pick my first padlock! Yay!&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;I could go on, but I won't. But I hope they consider this enough of a win to do it again next year, and and I hope and plan to make Ohio LinuxFest in September.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-7020210021480958035?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/7020210021480958035/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=7020210021480958035' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/7020210021480958035'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/7020210021480958035'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2011/03/notes-on-indiana-linuxfest.html' title='Notes on Indiana Linuxfest'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-5449355033006798513</id><published>2011-03-28T11:21:00.000-04:00</published><updated>2011-03-28T11:21:28.444-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='removing pessimizations'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>On The Importance of Unique Strings</title><content type='html'>I find generalized mail notices to be counterproductive. I get a &lt;i&gt;lot&lt;/i&gt; of mail, from many dozens of mailing lists, from many dozens of commercial ventures I occasionally throw money at or want to throw money at, and more. I don't pay attention to it always. I write things to check things and send me email, and even then, I don't often read it. So why would I want to have every little thing beep and pop up and eat my attention when it arrives? Especially when, as a programmer, a lot of problem solving just goes away when that sort of beep draws me out?&lt;br /&gt;&lt;br /&gt;So, a while ago, I wrote &lt;a href="http://varlogrant.blogspot.com/2009/11/jbiff-announcing-new-mail-via.html"&gt;jBiff&lt;/a&gt;, which announces when I have mail (the traditional roll of &lt;code&gt;biff&lt;/code&gt; and &lt;code&gt;xbiff&lt;/code&gt;) via Jabber/XMPP (thus the "J"). I wrote it so I could configure search strings, so that I could have it biff when I got mail from:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;My boss and coworkers&lt;/b&gt;&amp;nbsp;- because I can name no worse feeling than hearing my boss come up behind me and asking "Did you get my email?"&lt;/li&gt;&lt;li&gt;&lt;b&gt;My wife and kids&lt;/b&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;My parents&lt;/b&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;A select set of friends&lt;/b&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;The office voice mail&lt;/b&gt;&lt;/li&gt;&lt;li&gt;&lt;b&gt;My bank&lt;/b&gt; -&amp;nbsp;which tells me when I have run out of money&lt;/li&gt;&lt;li&gt;&lt;b&gt;The Weather Channel&lt;/b&gt; - which tells me when there's severe weather in my area. (I work in a sub-basement so I can't just look out the window.)&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;And it's pretty much in that order. If you're top of that list, I'll get warned within two minutes of receiving the mail, and the bottom get checked every twenty minutes, all thanks to crontab.&lt;br /&gt;&lt;br /&gt;So, I was surprised at getting alerted that a boutique amp manufacturer has given away a 2x12" cabinet. I'm not remotely surprised at receiving this email (and no, I didn't win) but I am surprised that it popped up on Google Talk. And it took a little poking.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;My eldest son is named "Niel". Not "Neil" or "Neal", but "Niel", as my grandfather was named "Niels" and I wanted to honor my history. And ensure that nobody's going to spell either his first name correctly on first pass, to go with nobody ever being able to pronounce his last name. I can be cruel.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;And the representative from the boutique amp manufacturer is named "Daniel". &lt;br /&gt;&lt;br /&gt;Da&lt;b&gt;niel&lt;/b&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Because I used my son's first name, not his whole email name, I got alerted. I have since fixed it, but as a reminder to both myself and others, I'm putting this out there: Don't match a short string when you can match a longer, more unique string, or else you'll get false positives.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-5449355033006798513?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/5449355033006798513/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=5449355033006798513' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/5449355033006798513'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/5449355033006798513'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2011/03/on-importance-of-unique-strings.html' title='On The Importance of Unique Strings'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-3882620389016015031</id><published>2011-03-24T15:49:00.001-04:00</published><updated>2011-03-24T16:35:47.421-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='perl'/><title type='text'>Now There IS An App For That</title><content type='html'>&lt;a href="http://varlogrant.blogspot.com/2011/03/is-there-app-for-that.html"&gt;I had to do something.&lt;/a&gt; This was something. So I did this.&lt;br /&gt;&lt;br /&gt;This program collects the functions by module in a directory full of modules and checks a code base against it. This tells you which functions you are actually using. Which isn't quite what I wanted, but close.&lt;br /&gt;&lt;br /&gt;I can see some additions I could want. Setting the library directory and code directories via &lt;code&gt;Getopt::Long&lt;/code&gt; would be the first one. And it doesn't &lt;i&gt;quite&lt;/i&gt; tell me what I want to know in all cases. If I use a function in a program that never gets called, it still gives me a result. But this is a place to start.&lt;br /&gt;&lt;br /&gt;And because of this, I now know that, within the stack of previously-invented wheels called CPAN, there's a module called Regexp::Common that holds a stack of established regular expressions. I wanted to pull out all comments out of my programs for testing, so that a commented-out function doesn't count.&lt;br /&gt;&lt;br /&gt;&lt;pre class="perl" name="code"&gt;#!/usr/bin/perl&lt;br /&gt;&lt;br /&gt;use 5.010 ;&lt;br /&gt;use strict ;&lt;br /&gt;use warnings ;&lt;br /&gt;&lt;br /&gt;use Cwd 'abs_path' ;&lt;br /&gt;use Regexp::Common qw /comment/ ;&lt;br /&gt;&lt;br /&gt;use subs qw{&lt;br /&gt;    check_programs&lt;br /&gt;    module_list&lt;br /&gt;&lt;br /&gt;    decomment&lt;br /&gt;&lt;br /&gt;    drop_pm&lt;br /&gt;    get_module_subs&lt;br /&gt;    pull_package_name&lt;br /&gt;    pull_module_name&lt;br /&gt;    pull_sub_name&lt;br /&gt;    } ;&lt;br /&gt;&lt;br /&gt;my $modules     = module_list '/path/to/my/lib' ;&lt;br /&gt;my $directories =  [&lt;br /&gt;    '/code/directory/one',&lt;br /&gt;    '/code/directory/two',&lt;br /&gt;    '/code/directory/three', ] ;&lt;br /&gt;&lt;br /&gt;my $data = check_programs( $directories, $modules ) ;&lt;br /&gt;&lt;br /&gt;for my $mod ( sort keys %$data ) {&lt;br /&gt;    my $module = $data-&gt;{ $mod } ;&lt;br /&gt;    say $mod ;&lt;br /&gt;    for my $sub ( sort keys %$module ) {&lt;br /&gt;        my $subroutine = $module-&gt;{ $sub } ;&lt;br /&gt;        say join "\t", '',&lt;br /&gt;            ( $subroutine-&gt;{ count } ? $subroutine-&gt;{ count } : 0 ) ,&lt;br /&gt;            $sub,&lt;br /&gt;            ;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;exit ;&lt;br /&gt;&lt;br /&gt;########## ######### ######### ######### ######### #########&lt;br /&gt;########## #########     Subroutines     ######### #########&lt;br /&gt;########## ######### ######### ######### ######### #########&lt;br /&gt;&lt;br /&gt;#--------- --------- --------- --------- --------- --------- ---------&lt;br /&gt;# The core of the program&lt;br /&gt;sub check_programs {&lt;br /&gt;        my ( $directories, $modules ) = @_ ;&lt;br /&gt;        my $data ;&lt;br /&gt;        for my $program_dir ( @$directories ) {&lt;br /&gt;            my $program_directory = abs_path $program_dir ;&lt;br /&gt;            chdir $program_directory ;&lt;br /&gt;&lt;br /&gt;            #say $program_directory ;&lt;br /&gt;            my @directory = glob '*.cgi *.pl *.pm' ;&lt;br /&gt;&lt;br /&gt;            my $programs ;&lt;br /&gt;            @$programs = map {&lt;br /&gt;                { $_ =&gt; get_program( $_ ) }&lt;br /&gt;                } @directory ;&lt;br /&gt;            for my $program ( @$programs ) {&lt;br /&gt;                my $k ;&lt;br /&gt;                ( $k ) = keys %$program ;&lt;br /&gt;                my $v = $program-&gt;{ $k } ;&lt;br /&gt;&lt;br /&gt;                #say join "\t", '', $k ;&lt;br /&gt;                for my $module ( @$modules ) {&lt;br /&gt;                    my $mk ;&lt;br /&gt;                    ( $mk ) = keys %$module ;&lt;br /&gt;                    my $mv = $module-&gt;{ $mk } ;&lt;br /&gt;&lt;br /&gt;                    #say join "\t", '', '', $mk ;&lt;br /&gt;                    for my $sub ( @$mv ) {&lt;br /&gt;                        my $result = $v =~ /$sub/ ? 1 : 0 ;&lt;br /&gt;&lt;br /&gt;                        #$result&lt;br /&gt;                        #    and say join "\t", '', '', '', $result, $sub ;&lt;br /&gt;                        $data-&gt;{ $mk }-&gt;{ $sub }-&gt;{ exists } = 1 ;&lt;br /&gt;                        if ( $result ) {&lt;br /&gt;                            $data-&gt;{ $mk }-&gt;{ $sub }-&gt;{ count }++ ;&lt;br /&gt;                            push @{ $data-&gt;{ $mk }-&gt;{ $sub }-&gt;{ used } },&lt;br /&gt;                                abs_path $k ;&lt;br /&gt;                                }&lt;br /&gt;                        }&lt;br /&gt;                    }&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;        return $data ;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;#--------- --------- --------- --------- --------- --------- ---------&lt;br /&gt;# returns the contents of a filename, if it contains 'perl' in the top&lt;br /&gt;sub get_program {&lt;br /&gt;        my ( $filename ) = @_ ;&lt;br /&gt;        if ( -f $filename ) {&lt;br /&gt;            if ( open my $fh, '&lt;', $filename ) {&lt;br /&gt;                my @lines =&lt;br /&gt;                    map { decomment $_ } &lt;$fh&gt; ;&lt;br /&gt;&lt;br /&gt;                #return 0 if $lines[0] !~ m/perl/ ;&lt;br /&gt;                return join '', @lines ;&lt;br /&gt;                close $fh ;&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;        return 0 ;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;#--------- --------- --------- --------- --------- --------- ---------&lt;br /&gt;# removes Perl comments&lt;br /&gt;sub decomment {&lt;br /&gt;        my ( $code ) = @_ ;&lt;br /&gt;&lt;br /&gt;        #chomp $code ;&lt;br /&gt;        $code =~ s/$RE{comment}{Perl}// ;&lt;br /&gt;        return $code ;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;#--------- --------- --------- --------- --------- --------- ---------&lt;br /&gt;# returns an array ref of module names with an array of subroutines&lt;br /&gt;# the module contains&lt;br /&gt;sub module_list {&lt;br /&gt;        my ( $dir ) = @_ ;&lt;br /&gt;        my $directory = abs_path $dir ;&lt;br /&gt;        chdir $directory ;&lt;br /&gt;&lt;br /&gt;        my $output ;&lt;br /&gt;        my @directory = glob '*.pm' ;&lt;br /&gt;&lt;br /&gt;        @$output = map {&lt;br /&gt;            {&lt;br /&gt;                ( pull_module_name join '/', $directory, $_ . '.pm' ) =&gt;&lt;br /&gt;                    ( get_module_subs join '/', $directory, $_ . '.pm' )&lt;br /&gt;                    }&lt;br /&gt;            }&lt;br /&gt;            map { drop_pm $_ } @directory ;&lt;br /&gt;&lt;br /&gt;        return $output ;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;#--------- --------- --------- --------- --------- --------- ---------&lt;br /&gt;# returns an array ref to all the functions (minus internal functions&lt;br /&gt;# whose name starts with _) within a given module&lt;br /&gt;sub get_module_subs {&lt;br /&gt;        my ( $mod_path ) = @_ ;&lt;br /&gt;        my @output ;&lt;br /&gt;        if ( -f $mod_path ) {&lt;br /&gt;            if ( open my $fh, '&lt;', $mod_path ) {&lt;br /&gt;                my @lines = &lt;$fh&gt; ;&lt;br /&gt;                push @output, grep { !/^_/ }&lt;br /&gt;                    map  { pull_sub_name $_ }&lt;br /&gt;                    grep { /^\s*sub / } @lines ;&lt;br /&gt;                close $fh ;&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;        @output = sort @output ;&lt;br /&gt;        return \@output ;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;#--------- --------- --------- --------- --------- --------- ---------&lt;br /&gt;# return the package name of a module&lt;br /&gt;sub pull_module_name {&lt;br /&gt;        my ( $mod_path ) = @_ ;&lt;br /&gt;        my @output ;&lt;br /&gt;        if ( -f $mod_path ) {&lt;br /&gt;            if ( open my $fh, '&lt;', $mod_path ) {&lt;br /&gt;                my @lines = &lt;$fh&gt; ;&lt;br /&gt;                push @output, map { pull_package_name $_ }&lt;br /&gt;                    grep { /^\s*package / } @lines ;&lt;br /&gt;                close $fh ;&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;        return $output[ 0 ] ;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;#--------- --------- --------- --------- --------- --------- ---------&lt;br /&gt;# return the package name of a 'package Package::Name ;' string&lt;br /&gt;sub pull_package_name {&lt;br /&gt;        my ( $in ) = @_ ;&lt;br /&gt;        chomp $in ;&lt;br /&gt;        $in = ( split m{\s*package\s*}, $in )[ 1 ] ;&lt;br /&gt;        $in = ( split m/\s*;\s*/,       $in )[ 0 ] ;&lt;br /&gt;        return $in ;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;#--------- --------- --------- --------- --------- --------- ---------&lt;br /&gt;# return only the subroutine name from a 'sub sub_name { ' string&lt;br /&gt;sub pull_sub_name {&lt;br /&gt;        my ( $in ) = @_ ;&lt;br /&gt;        chomp $in ;&lt;br /&gt;        $in = ( split m{\s*sub\s*}, $in )[ 1 ] ;&lt;br /&gt;        $in = ( split m/\s*{\s*/,   $in )[ 0 ] ;&lt;br /&gt;        return $in ;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;#--------- --------- --------- --------- --------- --------- ---------&lt;br /&gt;# remove '.pm' from end of module file names&lt;br /&gt;sub drop_pm {&lt;br /&gt;        my ( $in ) = @_ ;&lt;br /&gt;        $in =~ s/\.pm$// ;&lt;br /&gt;        return $in ;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-3882620389016015031?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/3882620389016015031/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=3882620389016015031' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/3882620389016015031'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/3882620389016015031'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2011/03/now-there-is-app-for-that.html' title='Now There IS An App For That'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-4411219846277247252</id><published>2011-03-24T10:41:00.001-04:00</published><updated>2011-03-24T12:10:42.975-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='modules'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='perl'/><title type='text'>Is There An "App" For That?</title><content type='html'>So, I've been developing a workflow for quite some time. I have SQL tables feeding data into Perl-generated web sites and JSON feeds feeding AJAX pages using jQuery, and if I think about it, I could probably feed two or three more technology buzzwords into there, too. CSS, for sure.&lt;br /&gt;&lt;br /&gt;A big problem is that, as I proceeded, I had no idea what I was doing for a lot of it. What I know about writing Perl modules, I know due to this workflow. Well, I knew "start with &lt;code&gt;Package&lt;/code&gt; and end with &lt;code&gt;1 ;"&lt;/code&gt;, but beyond that, not a whole lot. The &lt;a href="http://stackoverflow.com/questions/2156598/whats-a-good-way-to-refactor-a-monster-perl-module-into-submodules"&gt;web has helped this process&lt;/a&gt; a lot, and now I'm not too ashamed at what I have.&lt;br /&gt;&lt;br /&gt;(Object orientation. Moose. It could use improvement and I would learn from the experience. But that isn't today's topic.)&lt;br /&gt;&lt;br /&gt;So, by and large, I have modules handling the SQL queries, then passing hashes or hashrefs, depending on what I want. But, as I said, I was figuring out what I'm doing as I go along. I'd get the problem, think "I need these tables", write modules to interface with the tables, write programs that use the modules, fail to write tests for the modules because what tests I could imagine are either trivially stupid or highly dependent on the state of the database (I have &lt;i&gt;Perl Testing&lt;/i&gt; on my desk and have worked through the first two chapters, so I know it's a failing, but see the note on object orientation.)&lt;br /&gt;&lt;br /&gt;In a practical sense, if I'm dealing with a &lt;i&gt;foo&lt;/i&gt;, I will have a table &lt;code&gt;foo&lt;/code&gt; and maybe &lt;code&gt;foo_attributes&lt;/code&gt; connecting with it. Then I'd write the module &lt;code&gt; Foo.pm&lt;/code&gt; with &lt;code&gt;create_foo&lt;/code&gt;, &lt;code&gt;update_foo&lt;/code&gt;, &lt;code&gt;delete_foo&lt;/code&gt;, &lt;code&gt;read_foo&lt;/code&gt; and &lt;code&gt;get_foo_list&lt;/code&gt; for a list of all the foos in the table. I can tell which tables I'm dealing with from the function name, for the most part. When it gets to the interaction of foos, bars and blees, it gets hairy, but that's why I get paid the big bucks, right?&lt;br /&gt;&lt;br /&gt;Right now, I'm looking to document the schema and &lt;code&gt;DROP TABLE cruft &lt;/code&gt; before adding a few more features, which means what I'd like to do is look through my code base for all the modules I'm responsible for, search for all the functions I'm calling in each, and give me a list that might look something like this:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;list_foo.cgi&lt;/code&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;VarLogRant::Foo&lt;/code&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;get_foo_list&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;read_foo&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;Now, I have a naive text-parsing concept of how I could do this, but honestly, I can't imagine that I'm the first person who would want something like this, and I know that the Perl community loves to build tools for building tools, so is there something I should be looking at before I dive into this myself?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-4411219846277247252?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/4411219846277247252/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=4411219846277247252' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/4411219846277247252'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/4411219846277247252'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2011/03/is-there-app-for-that.html' title='Is There An &quot;App&quot; For That?'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-8640144903179011105</id><published>2011-03-16T12:23:00.000-04:00</published><updated>2011-03-16T12:23:41.861-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='perl'/><category scheme='http://www.blogger.com/atom/ns#' term='ironman'/><title type='text'>The Schwartzian Mindset</title><content type='html'>&lt;blockquote&gt;Yeah, but your scientists were so preoccupied with whether or not they could, they didn't stop to think if they should. &lt;strong&gt;Dr. Ian Malcolm &lt;/strong&gt; &lt;/blockquote&gt;&lt;br /&gt;I have recently come to a knowledge of the power of &lt;code&gt;map&lt;/code&gt; and &lt;code&gt;grep&lt;/code&gt; when dealing with hashes and arrays of data. &lt;br /&gt;&lt;br /&gt;The key to entering this mindset is the &lt;a href="http://en.wikipedia.org/wiki/Schwartzian_transform"&gt;Schwartzian Transform&lt;/a&gt;. Here is a canonical example.&lt;br /&gt;&lt;pre class="perl" name="code"&gt;@sorted = map  { $_-&gt;[0] }&lt;br /&gt;          sort { $a-&gt;[1] cmp $b-&gt;[1] }&lt;br /&gt;          map  { [$_, foo($_)] }&lt;br /&gt;               @unsorted;&lt;/pre&gt;For years, I looked at that and said "Huh?", then wrote &lt;code&gt; for my $i ( @unsorted ) { ... } &lt;/code&gt; or something like that. In fact, let's look at a for-loop implementation that would get similar results.&lt;br /&gt;&lt;pre class="perl" name="code"&gt;my @sorted ;&lt;br /&gt;for my $i ( @unsorted ) {&lt;br /&gt;          my $j = foo($i) ;&lt;br /&gt;          $hash{$j} = $i ;&lt;br /&gt;          }&lt;br /&gt;for my $k ( sort { $a cmp $b } keys %hash ) {&lt;br /&gt;          push @sorted , $hash{ $k } ;&lt;br /&gt;          }&lt;/pre&gt;&lt;br /&gt;That's a lot more code, and it would not surprise me at all if my code was far slower than the Wikipedia example code, but I understood for loops from my first year of programming, so I can look at the second example and immediately understand it, and would still understand it if I came back and looked at it in a month.&lt;br /&gt;&lt;br /&gt;Of course, you can comment this sort of thing to explain it to your later self.&lt;br /&gt;&lt;pre class="perl" name="code"&gt;@sorted = map  { $_-&gt;[0] } # taking away the sorting field&lt;br /&gt;          sort { $a-&gt;[1] cmp $b-&gt;[1] } #sorting by the 2nd field in the anonymous arrays&lt;br /&gt;          map  { [$_, foo($_)] } # an array of 2-element anonymous arrays&lt;br /&gt;               @unsorted; # the original unsorted array &lt;/pre&gt;&lt;br /&gt;I find myself using the &lt;code&gt;map&lt;/code&gt; and &lt;code&gt;grep&lt;/code&gt; method a lot lately. It avoids a lot of extra arrays floating around, but as I looked at the Schwartzian Transform and boggled for years, I could see myself, or the next person holding this seat, looking at the code for hours and failing to get it. But at least, now that I can code like that, I can wonder if I should...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-8640144903179011105?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/8640144903179011105/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=8640144903179011105' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/8640144903179011105'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/8640144903179011105'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2011/03/schwartzian-mindset.html' title='The Schwartzian Mindset'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-1108659759229276186</id><published>2011-03-11T11:18:00.001-05:00</published><updated>2011-03-11T11:19:37.153-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rant'/><category scheme='http://www.blogger.com/atom/ns#' term='computers'/><title type='text'>Computing and Simplicity</title><content type='html'>As I was preparing lunch the other day, I noticed two co-workers poking at a computer. One looks at me and says "Aren't computers supposed to make things simpler?"&lt;br /&gt;&lt;br /&gt;No.&lt;br /&gt;&lt;br /&gt;A thousand times, no.&lt;br /&gt;&lt;br /&gt;Computers are supposed to allow us greater and more numerous avenues of possibility.&lt;br /&gt;&lt;br /&gt;I say that all science is computer science these days because if you can do something without having to handle large amounts of complicated data, using computers to tell machines to manipulate things far smaller than you can do by hand, without using modern instruments and the computers that control them — if you can find out what you want to find out without that, it was probably done years ago.&lt;br /&gt;&lt;br /&gt;I say that because computer networking allows for computer networking, for knowing people via Facebook and Twitter and Skype and wikis and chatrooms and whatever, which gives you connections based on interests, not proximity.&lt;br /&gt;&lt;br /&gt;If you want simplicity, go out and find a plot of land. Plant seeds. Let it rain. The seeds grow. You harvest and eat the seeds, and plant some. Let that be the whole of your life. That's simple. And it's not for me. The whole of civilization has been built so that more and more people can justify not doing that.&lt;br /&gt;&lt;br /&gt;(Lest anyone accuse me of slamming farmers, I have farmers in the family, and they more fully embrace and become more expert in more technologies than anyone else I know. They aren't keeping it simple, either.)&lt;br /&gt;&lt;br /&gt;Of course, I &lt;i&gt;said&lt;/i&gt; this.&lt;br /&gt;&lt;br /&gt;Which is not what people struggling with computers want to hear. They want to hear how to take their means of using PowerPoint to generate HTML and/or images which they then put on the Wiki and make it work, and that philosophic postulates which do not address the problem at hand make them angry.&lt;br /&gt;&lt;br /&gt;Of course, I noted that they had fallen victim to &lt;a href="http://www.imdb.com/title/tt0093779/"&gt;one of the classic blunders&lt;/a&gt;, the most famous of which is "Never get involved in a land war in Asia", but only slightly less well-known is "Never use Microsoft Office if you can help it."&lt;br /&gt;&lt;br /&gt;This time, I wisely kept this thought to myself.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-1108659759229276186?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/1108659759229276186/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=1108659759229276186' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/1108659759229276186'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/1108659759229276186'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2011/03/as-i-was-preparing-lunch-other-day-i.html' title='Computing and Simplicity'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-5936521403484900255</id><published>2011-02-25T00:35:00.000-05:00</published><updated>2011-02-25T00:35:11.969-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='puzzles'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='perl'/><title type='text'>Capital Idea 3 - Going 'Round In Circles</title><content type='html'>I thought I had an idea to solve the state capital issue.&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Go through each line in the list in order of length&lt;/li&gt;&lt;li&gt;If both points of the line are not handled twice ( connected on either side ), place it into the path&lt;/li&gt;&lt;li&gt;Quit when every point (state capital) is hit twice&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;This gives you all the points, but it does not give you an order.&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;pull line out of path&lt;/li&gt;&lt;li&gt;for each line in the path&amp;nbsp;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;check if one of the points&lt;/li&gt;&lt;li&gt;if one of the points is the one we want,&amp;nbsp;throw it into the output array&lt;/li&gt;&lt;li&gt;&amp;nbsp;else put it into the dummy path array&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;push line into path&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;There is a problem, however.&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Nothing I have done guarantees that all the states are connected. And in this case, I know that the states are not all connected.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Back to the drawing board.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-5936521403484900255?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/5936521403484900255/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=5936521403484900255' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/5936521403484900255'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/5936521403484900255'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2011/02/capital-idea-3-going-round-in-circles.html' title='Capital Idea 3 - Going &apos;Round In Circles'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-253866660154361409</id><published>2011-02-18T13:50:00.000-05:00</published><updated>2011-02-18T13:50:28.834-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='puzzles'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='perl'/><title type='text'>Capital Idea 2 - So Far Away</title><content type='html'>Rather than query Google Maps to get driving distances between capitals, I found latitude and longitude and use these functions to determine the distance, then ran it against all thousand-some possible distances, so it is ultimately a hash check rather than a calculation to find a distance.&lt;br /&gt;&lt;br /&gt;&lt;span class="fullpost"&gt;&lt;pre name="code" class="perl"&gt;sub haversine {&lt;br /&gt;    my ( $lat1, $lon1, $lat2, $lon2 ) = @_ ;&lt;br /&gt;&lt;br /&gt;    my $theta = $lon1 - $lon2 ;&lt;br /&gt;    my $dist =&lt;br /&gt;        sin( deg2rad( $lat1 ) ) *&lt;br /&gt;        sin( deg2rad( $lat2 ) ) +&lt;br /&gt;        cos( deg2rad( $lat1 ) ) *&lt;br /&gt;        cos( deg2rad( $lat2 ) ) *&lt;br /&gt;        cos( deg2rad( $theta ) ) ;&lt;br /&gt;&lt;br /&gt;    $dist = acos( $dist ) ;&lt;br /&gt;    $dist = rad2deg( $dist ) ;&lt;br /&gt;    $dist = $dist * 60 * 1.1515 ;&lt;br /&gt;    return $dist ;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;sub acos {&lt;br /&gt;    my ( $rad ) = @_ ;&lt;br /&gt;    my $ret = atan2( sqrt( 1 - $rad**2 ), $rad ) ;&lt;br /&gt;    return $ret ;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;sub deg2rad {&lt;br /&gt;    my ( $deg ) = @_ ;&lt;br /&gt;    return ( $deg * $pi / 180 ) ;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;sub rad2deg {&lt;br /&gt;    my ( $rad ) = @_ ;&lt;br /&gt;    return ( $rad * 180 / $pi ) ;&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-253866660154361409?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/253866660154361409/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=253866660154361409' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/253866660154361409'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/253866660154361409'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2011/02/capital-idea-2-so-far-away.html' title='Capital Idea 2 - So Far Away'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-6169744686631337003</id><published>2011-02-18T12:28:00.006-05:00</published><updated>2011-02-18T13:14:47.642-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='puzzles'/><category scheme='http://www.blogger.com/atom/ns#' term='hacks'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='perl'/><title type='text'>Programming Challenge: A Capital Idea!</title><content type='html'>In the last Purdue Perl Mongers meeting, Mark suggested a challenge. Going from state capital to state capital of the "lower 48" (no Alaska, no Hawaii) , without skipping one and without repeating one, what are the longest and shortest distances. We guessed without knowledge, and then, after the meeting was over, we started working on it.&lt;br /&gt;&lt;br /&gt;As you may know, this is a restatement of the &lt;a href="http://en.wikipedia.org/wiki/Travelling_salesman_problem"&gt;Travelling Salesman problem&lt;/a&gt; and as such is NP-Hard. There are, in this case, &lt;a href="http://www.wolframalpha.com/input/?i=48+factorial"&gt;48!&lt;/a&gt; possible answers.&lt;br /&gt;&lt;br /&gt;My immediate thought was to specify the most extreme unused distance for each capital, longest or shortest, depending. I also thought to start at Maine, seeing as it's the furthest out of all the state capitals. &lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/-vcnPDSRW2Xk/TV6vvvvBppI/AAAAAAAABmI/SjSBCN6pILY/s1600/shortest.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 320px;" src="http://4.bp.blogspot.com/-vcnPDSRW2Xk/TV6vvvvBppI/AAAAAAAABmI/SjSBCN6pILY/s400/shortest.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5575086623533672082" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;You should be able to see some problems. For example, Arizona wasn't the shortest choice until it was the last choice. I'm not remotely happy with the Midwest and New England sections, either. So the fastest choice of algorithm wasn't the best choice. Running the naive longest-path against each state showed that Tennessee and Kentucky were the best starting point, which shocked the heck out of me. &lt;br /&gt;&lt;br /&gt;I added some code to pick the closest &lt;span style="font-style:italic;"&gt;n&lt;/span&gt; and recurse through those, and that cleared up the Arizona problem quickly, but it will take a lot of redoing to get it to back up to the Tennessee-to-Michigan jump, much less the New England jumble. Considering a quick read-through of threading modules, which could help me get through my too-many-possibilities, but also considering ways to rethink this as a breadth-first problem.&lt;br /&gt;&lt;br /&gt;I'm also seriously considering just making a web interface and solving it myself. I can't be sure it's the best possible, but I can vgrep for issues and optimizations.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-6169744686631337003?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/6169744686631337003/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=6169744686631337003' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/6169744686631337003'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/6169744686631337003'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2011/02/programming-challenge-capital-idea.html' title='Programming Challenge: A Capital Idea!'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-vcnPDSRW2Xk/TV6vvvvBppI/AAAAAAAABmI/SjSBCN6pILY/s72-c/shortest.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-5335729529025975760</id><published>2011-02-12T10:21:00.000-05:00</published><updated>2011-02-12T10:21:49.148-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='office suites'/><title type='text'>Office Software for an Open-Source-Loving Programmer</title><content type='html'>I'm a programmer and IT helpdesk guy for a lab at a major university. I rarely touch office suites. I do, on occasion, prepare presentations for user groups I'm involved in, but as I've found I'm more comfortable diving into whatever applications I'm working with, that's a fairly rare thing. The office tool I most often use is a spreadsheet, which allows me to see CSV data (and we deal with a lot of CSV data) in the formatted way it's meant to be thought of.&lt;br /&gt;&lt;br /&gt;For my personal purposes, I've Gone Google.&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/-09uRxWW2MzI/TVaZTjDNdMI/AAAAAAAABl4/QBjtawETxBU/s1600/IMAG0206.jpg" imageanchor="1" style="margin-left:1em; margin-right:1em"&gt;&lt;img border="0" height="239" width="400" src="http://4.bp.blogspot.com/-09uRxWW2MzI/TVaZTjDNdMI/AAAAAAAABl4/QBjtawETxBU/s400/IMAG0206.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;When your life is spread out among seven computers and a smartphone, connecting your stuff back to the cloud makes more than a little sense. I get the "you don't own your data" arguments, but for now, it fits my needs fairly well.&lt;br /&gt;&lt;br /&gt;But it doesn't really fit my office's needs. Genomics data can be big. &lt;em&gt;&lt;strong&gt;Big&lt;/strong&gt;&lt;/em&gt;. Loading it up to Google isn't really where I want to go. Which leads to the real crux of this discussion.&lt;br /&gt;&lt;br /&gt;I could go Microsoft Office. There was a technical reason that you might prefer Office, in that genomics data can be big, and Excel allowed for 65536 rows by 256 columns, which was more than double what I could get out of OpenOffice.org. However, it seems that this has been changed since I last tried it. &lt;br /&gt;&lt;br /&gt;The problem there is that I prefer to go with a Linux desktop, both for the power of it and for the freedom of it, and Office is a Microsoft product that you can't run (without virtualization or something) on Linux machines. Ubuntu comes with OpenOffice.org, so that's my default go-to for those times I do need to play with an office suite product. &lt;br /&gt;&lt;br /&gt;But....&lt;br /&gt;&lt;br /&gt;I was listening to the &lt;a href="http://twit.tv/FLOSS"&gt;FLOSS Weekly&lt;/a&gt; show about FOSDEM, and the mention of LibreOffice got me curious. Each time I've opened OpenOffice, I've thought that it was slow and cumbersome beyond what it does. If there's a noticeable improvement in it's speed, it's well worth considering.&lt;br /&gt;&lt;br /&gt;You know, for the seven times a year I really really need it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-5335729529025975760?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/5335729529025975760/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=5335729529025975760' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/5335729529025975760'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/5335729529025975760'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2011/02/office-software-for-open-source-loving.html' title='Office Software for an Open-Source-Loving Programmer'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-09uRxWW2MzI/TVaZTjDNdMI/AAAAAAAABl4/QBjtawETxBU/s72-c/IMAG0206.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-788451416029235432</id><published>2011-02-10T10:44:00.002-05:00</published><updated>2011-02-10T10:47:57.305-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='removing pessimizations'/><category scheme='http://www.blogger.com/atom/ns#' term='crontab'/><title type='text'>Named Times in Crontab</title><content type='html'>I first dealt with &lt;code&gt;crontab&lt;/code&gt; in the late 1990s, and I still run many of those same crontabs. I mean, same program, same times. So, my understanding of that tool is very tied to that time. &lt;br /&gt;&lt;br /&gt;Of course, very little changes in technology over 15 years. &amp;lt;/sarcasm&amp;gt; So I recently looked through &lt;code&gt;man 5 crontab&lt;/code&gt; and found that there are special strings for certain common times. &lt;div style="text-align:center"&gt; &lt;table style="border:1px solid blue;background: lightblue; margin:0 auto;" &gt;  &lt;tr&gt;&lt;th&gt;      &lt;code&gt; @reboot    &lt;/code&gt; &lt;/th&gt;&lt;td&gt;   Run once, at startup.  &lt;/td&gt;&lt;/tr&gt;   &lt;tr&gt;&lt;th&gt;      &lt;code&gt; @yearly    &lt;/code&gt; &lt;/th&gt;&lt;td&gt;   Run once a year, "0 0 1 1 *".  &lt;/td&gt;&lt;/tr&gt;   &lt;tr&gt;&lt;th&gt;      &lt;code&gt; @annually  &lt;/code&gt; &lt;/th&gt;&lt;td&gt;   (same as @yearly)  &lt;/td&gt;&lt;/tr&gt;   &lt;tr&gt;&lt;th&gt;      &lt;code&gt; @monthly   &lt;/code&gt; &lt;/th&gt;&lt;td&gt;   Run once a month, "0 0 1 * *".  &lt;/td&gt;&lt;/tr&gt;   &lt;tr&gt;&lt;th&gt;      &lt;code&gt; @weekly    &lt;/code&gt; &lt;/th&gt;&lt;td&gt;   Run once a week, "0 0 * * 0".  &lt;/td&gt;&lt;/tr&gt;   &lt;tr&gt;&lt;th&gt;      &lt;code&gt; @daily     &lt;/code&gt; &lt;/th&gt;&lt;td&gt;   Run once a day, "0 0 * * *".  &lt;/td&gt;&lt;/tr&gt;   &lt;tr&gt;&lt;th&gt;      &lt;code&gt; @midnight  &lt;/code&gt; &lt;/th&gt;&lt;td&gt;   (same as @daily)  &lt;/td&gt;&lt;/tr&gt;   &lt;tr&gt;&lt;th&gt;      &lt;code&gt; @hourly    &lt;/code&gt; &lt;/th&gt;&lt;td&gt;   Run once an hour, "0 * * * *".  &lt;/td&gt;&lt;/tr&gt; &lt;/table&gt;&lt;/div&gt;&lt;br /&gt;Some of these come with variable utility. What are you doing on a system that's &lt;code&gt;@yearly&lt;/code&gt;? Sending "Happy New Year!" to everybody you know? There's much here that strikes me as better done connecting to a calendar. In fact, I'm hatching an idea of setting up a calendar in Google Calendar to do that sort of wide-ranging crontabby or batchy stuff. If something runs less common than weekly, it doesn't get into my crontabs.&lt;br /&gt;&lt;br /&gt;Except...&lt;br /&gt;&lt;br /&gt;I'm really drawn to the &lt;code&gt;@reboot&lt;/code&gt; string. For my work setup, I have FUSE mounts to a great number of machines (which I really use) and a specific line to configure the line-in to go directly to line-out so I can route my Windows box and Android phone through my Linux box to my headphones. I've put those commands into my crontab at &lt;code&gt;@reboot&lt;/code&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-788451416029235432?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/788451416029235432/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=788451416029235432' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/788451416029235432'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/788451416029235432'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2011/02/named-times-in-crontab.html' title='Named Times in Crontab'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-1914875063555021726</id><published>2011-02-08T22:31:00.002-05:00</published><updated>2011-02-08T22:46:33.606-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='networking'/><title type='text'>Items from the Feed - Tying Down The Uplink</title><content type='html'>&lt;object classId="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="480" height="418" id="VideoPlayerLg51117"&gt;&lt;param name="movie" value="http://www.g4tv.com/lv3/51117" /&gt;&lt;param name="allowScriptAccess" value="always" /&gt;&lt;param name="allowFullScreen" value="true" /&gt;&lt;embed src="http://www.g4tv.com/lv3/51117" type="application/x-shockwave-flash" name="VideoPlayer" width="480" height="382" allowScriptAccess="always" allowFullScreen="true" /&gt;&lt;/object&gt;&lt;div style="margin:0;text-align:center;width:480px;font-family:Arial,sans-serif;font-size:12px;color:#FF9B00;"&gt;&lt;a href="http://www.g4tv.com/" style="color:#FF9B00;" target="_blank"&gt;Video Game&lt;/a&gt; - &lt;a href="http://www.g4tv.com/e32011" style="color:#FF9B00;" target="_blank"&gt;E3 2011&lt;/a&gt; - &lt;a href="http://www.g4tv.com/attackoftheshow/thefeed/index.html" style="color:#FF9B00;" target="_blank"&gt;The Feed&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;A couple of issues here. First, Sara Underwood is pretty, but that voice! Almost like fingernails on a chalkboard.&lt;br /&gt;&lt;br /&gt;Anyway, one of the issues she brings up is wide-open home networks. The warning wasn't folks coming into your WiFi, infecting your PCs and stealing private stuff. It's glomming onto your network and "stealing" your bits. &lt;br /&gt;&lt;br /&gt;Honestly, before I moved, I never encrypted my WiFi. I never thought it was worth it. Different neighborhood, with more people closer, and the new access point came with it up by default. As long as they don't use enough to mess up your video streaming, why not?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-1914875063555021726?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/1914875063555021726/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=1914875063555021726' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/1914875063555021726'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/1914875063555021726'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2011/02/items-from-feed-tying-down-uplink.html' title='Items from the Feed - Tying Down The Uplink'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-80807454028928411</id><published>2011-02-08T11:23:00.004-05:00</published><updated>2011-02-08T16:47:31.295-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='automobiles'/><category scheme='http://www.blogger.com/atom/ns#' term='technology'/><title type='text'>Pondering the Future, the Shock of the New, and Defining The Terms</title><content type='html'>I think I have to start with &lt;span style="font-style:italic;"&gt;The New X&lt;/span&gt; here. I've gone on about &lt;span style="font-style:italic;"&gt;The New Telephone&lt;/span&gt; and &lt;span style="font-style:italic;"&gt;The New Television&lt;/span&gt; without really defining my conception, my mindset. I think it's obvious what I mean with those, but when I hit the next topic on my mind, you get a certain Bob Barker connotation.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_1wdUwIPTY7U/TVFwpl5tGRI/AAAAAAAABlI/hB-jnWPrqmw/s1600/new_car.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 214px;" src="http://3.bp.blogspot.com/_1wdUwIPTY7U/TVFwpl5tGRI/AAAAAAAABlI/hB-jnWPrqmw/s320/new_car.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5571358073885104402" /&gt;&lt;/a&gt;&lt;small style="font-size:8px"&gt;Image by &lt;a href="http://www.flickr.com/photos/psycho-pics/2930346128"&gt;Wayne Silver&lt;/a&gt;&lt;/small&gt;&lt;br /&gt;&lt;big style="display:block;text-align: center"&gt;&lt;em&gt;THE NEW CAR!&lt;/em&gt;&lt;/big&gt;&lt;br /&gt;&lt;br /&gt;I have a concept in my mind of life between 1955 and 1985 (only about half of which I lived through) where the Old Telephone and Television live. The Old Television, for example, consists of complete boxes, with the beginnings of plug-ins from VCRs and Atari game machines. The New Television, still being designed and tested, will involve multiple sources, time-shifting, and modularization such that the screen is but a monitor, one of many.&lt;br /&gt;&lt;br /&gt;But TV is fundamentally information. As long as you can see it and hear it, who cares whether it comes from the air, a coax cable or a Cat5e jack? The New Car is different. It is first and foremost a mechanical thing, and thus the issues involved are different. &lt;br /&gt;&lt;br /&gt;A person from 1970 stepping into today wouldn't understand cell phones and would be befuddled by the collection of remotes on the TV, but I am very certain she could get into a 2010 car, start it, and drive it around. "Three on the Tree" isn't nearly as popular as it used to be, but the gas pedal, brake pedal, speedometer, turn signals, AC, rear-view mirror would all be about where she'd expect them to be and would behave about how she'd expect them to behave. There would be a few hiccups possible &amp;mdash; electric motors and hybrids, OBDII and continuously variable transmissions are three things that come to mind &amp;mdash; but they don't particularly affect the driving experience too much. The mechanics of automobiles have been abstracted away from the act of driving, and that's a good thing.&lt;br /&gt;&lt;br /&gt;What &lt;span style="font-style:italic;"&gt;is&lt;/span&gt; changing is the information-related aspects of driving, as fast and as good as the car companies can do it. As the driver of a car &lt;a href="http://en.wikipedia.org/wiki/Toyota_Yaris"&gt;that was the cheapest new car we could find&lt;/a&gt;, much of what I know is from driving rentals when my car is in the shop, and from watching &lt;span style="font-style:italic;"&gt;Top Gear&lt;/span&gt;. I see in-dash navigation, but you don't really want to be looking down at the dash too much when driving, and an in-dash system won't have the quick update times of navigating with your phone. Car audio systems have connecting to your iPod and iPhone down just as Android is beginning to dominate the market. &lt;br /&gt;&lt;br /&gt;For the car market, electronics is a trailing concern. You want it to be so, clearly, because making the car faster, safer and more economical are the leading concerns. But it makes the choices dated. I saw a video from CNet's Car Tech section where the reviewer talks about the &lt;a href="http://reviews.cnet.com/sedan/2011-toyota-camry-se/4505-10865_7-34476533.html"&gt;Toyota Camry&lt;/a&gt;, mentioning the 6-disc CD player (in the last days of optical media?) and optional dual DVD players in the back seat for too much money, which he suggests you skip and get iPads instead.&lt;br /&gt;&lt;br /&gt;I told a friend a few months ago that I wanted to put a computer in a car. He asked "What would you do with that?" The thing that I mentioned is combining OBDII data with GPS so I can connect what I was doing and where I was doing it to what the engine was doing. I'm not a mechanic, so I don't really know what I'd do with that information. That information becomes really usable when you breach the firewall and start connecting to engine, transmission and brake electronics. Currently, you can get aftermarket chips to change the behavior of your engine and such, but that's warranty-voiding stuff, and also, tight inner-loop microprocessor kind of work. It won't wait until the OS pages, queries a database and returns a proper response. &lt;br /&gt;&lt;br /&gt;Plus, of course, the standard interface vectors for electronics elsewhere are attention-sucking accident-causing crap for autos.&lt;br /&gt;&lt;br /&gt;So, I forsee the creation of The New Car, joining long-term reliable mechanics with high-turnover electronics, as a long-term process that will cause grumbling for a long long time.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-80807454028928411?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/80807454028928411/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=80807454028928411' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/80807454028928411'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/80807454028928411'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2011/02/pondering-future-shock-of-new-and.html' title='Pondering the Future, the Shock of the New, and Defining The Terms'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_1wdUwIPTY7U/TVFwpl5tGRI/AAAAAAAABlI/hB-jnWPrqmw/s72-c/new_car.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-2082363258578782103</id><published>2011-02-07T11:44:00.004-05:00</published><updated>2011-02-08T08:38:22.418-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='frustration'/><title type='text'>Time Estimation Hell</title><content type='html'>There&amp;#39;s two main tasks on my desk right now. The first is adding a new instrument to one of our web workflows. It&amp;#39;s my code, so I&amp;#39;m the one to do the diffs. The second is the Sikuli thing. To recap: We install VirtualBox, create a Ubuntu 10.10 64-bit virtual machine, upgrade libCV to 2.1, install Sikuli, ssh into a Linux compute server to run the Java GUI data modification server, then write Jython in order to script the thing. This will allow us to munge and generate PDFs and such for several things in order. Every time I deal with this program, I feel the nearly-but-not-quite-overwhelming urge to scrap that, decompile the Java bytecode and rewrite the thing in a way that&amp;#39;s batchable. I haven&amp;#39;t been overwhelmed, so I stick with the Sikuli solution.&lt;p&gt;I still think Sikuli is neat. I think I have to be clear. It&amp;#39;s just that this is becoming a much more complex thing than I am comfortable with.&lt;p&gt;This is why, when the boss appeared over my right shoulder, I was working on the other one. It&amp;#39;s web work. I like web work. It&amp;#39;s mostly Perl. I like Perl. I wrote everything involved, from the SQL tables to the Javascript interface bits. I get all of the things I wrote. It is a comfortable place, which means it&amp;#39;s a job I can get done and feel productive. I felt I could git &amp;#39;r done, check the thing off, and then deal with the confusing time sink.&lt;p&gt;Nothing quite like the boss showing up behind you to tell you that, no, your priorities must change. There&amp;#39;s a whole bunch of .DAT files to be munged, and what we have isn&amp;#39;t cutting it. So, when will it be done?&lt;p&gt;No clue.&lt;p&gt;No clue on several sorts of issues. I started this as a programmer who never did much more than recursive and iterative Fibonacci in Python, so     I am not familiar and comfortable enough with the language to really say I know how to do anything fast. I&amp;#39;m still on the learning curve there.&lt;p&gt;Plus, I don&amp;#39;t really know what all the problems are. I don&amp;#39;t know how to solve the problems I don&amp;#39;t know that exist. We&amp;#39;re combining two machines and two Java applications with ssh, X11 and other things. It is a complex thing.&lt;p&gt;But those things are relatively minor. The more fundamental thing is that I do not think of tasks in time terms. How long a task takes is how long it takes. I don&amp;#39;t want to think about the time aspect. It distracts from thinking about how to actually do the task. If I come up with the clever solution, it&amp;#39;s done. If I don&amp;#39;t, it takes forever.&lt;p&gt;Is this a common thing for programmers? Or am I the odd duck?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-2082363258578782103?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/2082363258578782103/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=2082363258578782103' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/2082363258578782103'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/2082363258578782103'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2011/02/time-estimation-hell.html' title='Time Estimation Hell'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-201379598714174924</id><published>2011-02-05T19:53:00.000-05:00</published><updated>2011-02-05T19:53:16.211-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='netbook'/><category scheme='http://www.blogger.com/atom/ns#' term='ubuntu'/><category scheme='http://www.blogger.com/atom/ns#' term='we live in the future'/><title type='text'>We Live In The Future Redux</title><content type='html'>I have my trusty netbook on my lap. In one of my USB ports, I have a thumbdrive with the Ubuntu Netbook Live CD on it. I'm installing Ubuntu Netbook 10.10 right now. But not on my netbook's SSD. I'm installing it on an 8GB SD card.&lt;br /&gt;&lt;br /&gt;I remember getting hard drives smaller than that. Storage-wise, I mean. Physically, they were the size of today's DVD drives. I'm sure that the performance of an SD card will bed poor compared to an SSD card, but a second face for $20 is kinda cool. Dual-boot on the cheap. My friend Patrick put Ubuntu on a thumbdrive so he could have "GoodOS" on his work laptop. I wanted to have something that wouldn't hang out too much. I don't use my SD slot often, so keeping it there works for me.&lt;br /&gt;&lt;br /&gt;It's still configuring, so I can't say much. But such powerful and modular hardware is neat.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-201379598714174924?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/201379598714174924/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=201379598714174924' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/201379598714174924'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/201379598714174924'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2011/02/we-live-in-future-redux.html' title='We Live In The Future Redux'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-8795876600628474505</id><published>2011-02-05T13:41:00.007-05:00</published><updated>2011-02-05T15:50:50.124-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='gps'/><category scheme='http://www.blogger.com/atom/ns#' term='television'/><category scheme='http://www.blogger.com/atom/ns#' term='google'/><title type='text'>New-To-Us TiVo, New-To-Us GPS</title><content type='html'>We have a TiVo. Finally. Yeah, I know we're ... a decade past the curve here? Something like that. I have to add that the TiVo+satellite box sucks because that means only one tuner, which means you cannot record this and watch that. But I have to say, the folks who say that the user interface to TiVo is a cut above? They have something there.&lt;br /&gt;&lt;br /&gt;What sucks outright is the IR blasters. Well, they're OK, except there's no feedback loop. It would be far better to have the TiVo &lt;em&gt;be&lt;/em&gt; the satellite box. I understand the HDMI interconnections of the Google TV box (of which there's really only the Logitech Revue, last I checked) have bi-directional communication, and that's what you really want. &lt;br /&gt;&lt;br /&gt;It's a bit funny, though. We have a PC running Boxee and a Wii that does good Netflix. So far, we're widely distributed. I want a newer, faster PC for Boxee (and other duties, like home file+print server), and with the TiVo we now have access to Amazon On Demand. (Not like we've used it yet. We're still a Red Box family, and spinning discs of optical media at DVD quality is definitely a trailing-edge technology, no matter the shiny red vending machine.)&lt;br /&gt;&lt;br /&gt;For Christmas, my father gave me his old TomTom. I have always wanted a stand-alone GPS, but not really for car use. Well, yes and no. I want a list of discrete lat&amp;long coordinates I can map. I'm sure I can have that with the Evo phone, but I haven't really dived into that. Anyway, the point at this juncture is that I have a phone with a navigation feature, my wife had a phone with a navigation feature, and 2 of 3 sons had phones with navigation features. I thought "Hey, I'll never use this".&lt;br /&gt;&lt;br /&gt;There are two reasons I've started to. First is the mount. I can mount the TomTom to the window and keep it in a good position. I don't have a good cellphone mount for the Evo. I love having the rolling map and the speedometer even when I don't have a destination set. &lt;br /&gt;&lt;br /&gt;The second is duplication. I can have my phone set to do phone things, or provide audio, or even just on my belt as it should, and not worry about it forgetting my destination. Don't know how I'll really integrate it into my driving, though.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-8795876600628474505?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/8795876600628474505/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=8795876600628474505' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/8795876600628474505'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/8795876600628474505'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2011/02/new-to-us-tivo-new-to-us-gps.html' title='New-To-Us TiVo, New-To-Us GPS'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-2923153441750673892</id><published>2011-02-03T20:24:00.004-05:00</published><updated>2011-02-03T20:30:56.781-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='television'/><category scheme='http://www.blogger.com/atom/ns#' term='new gear day'/><title type='text'>New Multimedia Keyboard</title><content type='html'>I have the biggest remote I have ever seen.&lt;br /&gt;&lt;br /&gt;&lt;div&gt;It's the &lt;a href="http://www.iogear.com/product/GKM561R/"&gt;GKM561R&lt;/a&gt; keyboard from &lt;a href="http://www.iogear.com/"&gt;IOGear&lt;/a&gt;, which I got through &lt;a href="http://newegg.com/"&gt;NewEgg&lt;/a&gt;. It's got a built in trackball, which makes it better for multimedia settings than the Logitech wireless desktop I got before. I have always used Logitech wireless keyboards before, and I'm sure I'll get one again, but the mouse stopped working and got lost, and for multimedia applications, it makes sense.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://3.bp.blogspot.com/_1wdUwIPTY7U/TUtLi3d206I/AAAAAAAABlE/LrcHz5D9IAU/s1600/GKM561R_A.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="174" src="http://3.bp.blogspot.com/_1wdUwIPTY7U/TUtLi3d206I/AAAAAAAABlE/LrcHz5D9IAU/s320/GKM561R_A.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: x-small;"&gt;Image from &lt;a href="http://www.kvmgalore.com/"&gt;KVMGalore&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;There was a weird thing. The W key had fallen off, but it was securely in the packaging and was easy to replace.  I'm loving the addition of a TV PC.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-2923153441750673892?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/2923153441750673892/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=2923153441750673892' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/2923153441750673892'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/2923153441750673892'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2011/02/new-multimedia-keyboard.html' title='New Multimedia Keyboard'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_1wdUwIPTY7U/TUtLi3d206I/AAAAAAAABlE/LrcHz5D9IAU/s72-c/GKM561R_A.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-7070800518456956827</id><published>2011-02-02T14:44:00.000-05:00</published><updated>2011-02-02T14:44:48.097-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='arduino'/><category scheme='http://www.blogger.com/atom/ns#' term='geekery'/><category scheme='http://www.blogger.com/atom/ns#' term='hardware'/><title type='text'>The Internet of Things? The Semantic Web?</title><content type='html'>I have a dream.&lt;br /&gt;&lt;br /&gt;&lt;div&gt;I dream of a lamp. A lamp using LEDs. A lamp that changes color, depending on the ambient temperature outdoors. If the weather outside is frightful, the lamp indoors is blue-to-purple. If Summer's here and the time is right, the light is yellow, orange or even red.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This dream is in part inspired by my workplace in the subbasement of my building. I can very easily forget the season, even, when I'm head-down into my work, so any reminder of the conditions outisde would be good.&lt;br /&gt;&lt;br /&gt;This is an example of what was called Ubiquitous Computing or Pervasive Computing, depending on who generated the buzzword. In essence, the data is everywhere around you, not just on your PC.&lt;br /&gt;&lt;br /&gt;The thing that's really keeping me from realizing this dream is a lack of electronics skill.&lt;br /&gt;&lt;br /&gt;But that's a smaller thing today.&lt;br /&gt;&lt;br /&gt;There's a thing called an Arduino, which is an Open Source bit of hardware that begins to open up the world of programming small things. I'm fairly sure I could, given an Arduino and a breadboard, begin to dummy this up.&lt;br /&gt;&lt;br /&gt;This kinda gets me to categorization issues. Does this concept, an internet-aware fixture that determines the shade by the weather report fall under the Semantic Web? Or is it more tightly connected to the Internet of Things concept? Or is it a bit of both, like a Reese's cup?&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-7070800518456956827?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/7070800518456956827/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=7070800518456956827' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/7070800518456956827'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/7070800518456956827'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2011/02/internet-of-things-semantic-web.html' title='The Internet of Things? The Semantic Web?'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-826397437618542172</id><published>2011-01-28T09:58:00.000-05:00</published><updated>2011-01-28T09:58:21.903-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='TV'/><category scheme='http://www.blogger.com/atom/ns#' term='networking'/><title type='text'>Netflix As SpeedTest</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://4.bp.blogspot.com/_1wdUwIPTY7U/TULXi3nLaII/AAAAAAAABk8/H0sNSSkMRhw/s1600/isp_usa.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;img border="0" height="276" src="http://4.bp.blogspot.com/_1wdUwIPTY7U/TULXi3nLaII/AAAAAAAABk8/H0sNSSkMRhw/s400/isp_usa.png" width="400" /&gt;&lt;/span&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;a href="http://techblog.netflix.com/2011/01/netflix-performance-on-top-isp-networks.html"&gt;This&lt;/a&gt; is cool.&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;When you think about it, watching a movie from Netflix or something is a great way to test a network. This is a graph of different big ISPs and their throughput. &lt;/span&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;span class="Apple-style-span" style="font-size: 17px;"&gt;&lt;i&gt;In the metric below, we’re filtering for titles that have HD streams available, and for devices capable of playing HD streams (which also filters out mobile networks), to highlight what’s achievable in terms of HD performance on the various ISP networks.&lt;/i&gt;&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt; What I find interesting is the high numbers for Comcast. Their light-blue line is consistently #2 on this graph here. I have said that nobody loves Comcast, they either hate Comcast or resign themselves to having to have them, but the data clearly puts them as having a good network.&lt;/span&gt;&lt;br /&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: left;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;(Thanks, &lt;a href="http://lifehacker.com/5745703/see-how-fast-netflix-streaming-actually-delivers-on-your-isp"&gt;LifeHacker&lt;/a&gt;)&lt;/span&gt;&lt;/div&gt;&lt;span class="fullpost"&gt;    &lt;/span&gt;&lt;br /&gt;&lt;pre class="perl" name="code"&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-826397437618542172?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/826397437618542172/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=826397437618542172' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/826397437618542172'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/826397437618542172'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2011/01/netflix-as-speedtest.html' title='Netflix As SpeedTest'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_1wdUwIPTY7U/TULXi3nLaII/AAAAAAAABk8/H0sNSSkMRhw/s72-c/isp_usa.png' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-6326488223173745973</id><published>2011-01-24T15:21:00.002-05:00</published><updated>2011-02-03T20:46:19.383-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='graphical programming'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='sikuli'/><title type='text'>Sikuli X Stress Test</title><content type='html'>&lt;iframe allowfullscreen="" class="youtube-player" frameborder="0" height="480" src="http://www.youtube.com/embed/Jfgmy_zERQY" title="YouTube video player" type="text/html" width="600"&gt;&lt;/iframe&gt;&lt;br /&gt;&lt;br /&gt;This video is of a stress test I built for Sikuli, a GUI scripting engine. It uses CV libraries to identify and interact with visual elements on your desktop. I've talked about it, but I haven't shown it, as I haven't had A means to. I'm now running Windows 7 on a fast computer, and I have Microsoft Expression Encoder installed. So, likely I'll have more screenvids in the future.&lt;br /&gt;&lt;br /&gt;As you'll see in the code, I'm writing in modules. The first code I show is meant to provide functions for the second code I show.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;b&gt;checking_test&lt;/b&gt;&lt;/div&gt;&lt;br /&gt;&lt;pre name="code" class="python"&gt;&lt;br /&gt;from sikuli.Sikuli import *&lt;br /&gt;&lt;br /&gt;def clickAllLikeThis( image ):&lt;br /&gt; for i in findAll(image):&lt;br /&gt;  click(i)&lt;br /&gt;&lt;br /&gt;def checkAll():&lt;br /&gt; a_unchecked = findAll(unchecked) &lt;br /&gt; for u in a_unchecked:&lt;br /&gt;  click(u)&lt;br /&gt;&lt;br /&gt;def uncheckAll():&lt;br /&gt; a_checked = findAll(checked)&lt;br /&gt; for c in a_checked:&lt;br /&gt;  click(c)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;b&gt;module_test&lt;/b&gt;&lt;/div&gt;&lt;br /&gt;&lt;pre name="code" class="python"&gt;&lt;br /&gt;# works on all platforms&lt;br /&gt;import sys&lt;br /&gt;import os&lt;br /&gt;# get the directory containing your running .sikuli&lt;br /&gt;myPath = os.path.dirname(getBundlePath())&lt;br /&gt;if not myPath in sys.path: sys.path.append(myPath)&lt;br /&gt;import checking_test&lt;br /&gt;unchecked = "1295894889335.png"&lt;br /&gt;checked = "1295894985817.png"&lt;br /&gt;popup( "Checking all unchecked" )&lt;br /&gt;checking_test.clickAllLikeThis( unchecked )&lt;br /&gt;popup("Unchecking all Checked")&lt;br /&gt;checking_test.clickAllLikeThis( checked )&lt;br /&gt;#clickAllLikeThis( checkbox )&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div&gt;The PNG strings are converted in the Sikuli editor, which has screengrab capabilities and converts the file name to the image.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I'm very glad that I'm able to separate functions into separate modules. I'm somewhat disturbed that I'm not getting 100% coverage from the elements I'm trying to get clicked. But it's a neat thing nonetheless.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-6326488223173745973?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/6326488223173745973/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=6326488223173745973' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/6326488223173745973'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/6326488223173745973'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2011/01/sikuli-x-stress-test.html' title='Sikuli X Stress Test'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://img.youtube.com/vi/Jfgmy_zERQY/default.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-9072504362461842933</id><published>2011-01-21T10:08:00.001-05:00</published><updated>2011-01-21T10:13:08.370-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='complaint'/><category scheme='http://www.blogger.com/atom/ns#' term='x11'/><category scheme='http://www.blogger.com/atom/ns#' term='sucking'/><category scheme='http://www.blogger.com/atom/ns#' term='frustration'/><category scheme='http://www.blogger.com/atom/ns#' term='solaris'/><title type='text'>Java Interface issue that makes no sense to me</title><content type='html'>There's a Java tool I have to use, called Blast2GO. It's a Genomics thing and I'm &lt;i&gt;very&lt;/i&gt; sure that program itself is not the problem, but it &lt;i&gt;is&lt;/i&gt; the only reason I'm using Java. We run this on data wholesale, so we're waiting with bated breath for them to release a command-line interface or API for it, but until then, there's the GUI. And if you're repeating a GUI interface a couple dozen times in a row (easily), it becomes more and more likely that you'll forget something. &lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So, we're trying to automate it. We're using Sikuli. In a way, Sikuli is a wonder. It uses computer vision libraries to find and click things in a GUI environment. It has allowed us to automate much of the interface, which is a wonder. &lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In another way, it's totally wrong. GUIs are not a pipeable environment, and if you're going to automate something, command-line scripting is the simplest way. Stupid interface issues pop up rarely that way, while my wrangling with Sikuli is all about handling stupid interface issues.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;And the most stupid, the most unsolvable stupid interface issue is this: I run Blast2GO on a Solaris server because that's where the data lives. So, I use X Windows to redirect the output onto my local machine. And right now, wherever I run it from, I lose the ability to navigate menus via arrow keys and move through open and save windows via tab. And, for the life of me, I have no idea why. But whenever I run it on those servers, I can't use those keys. This makes the scripting much harder.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Any idea why Java would be doing this to me? Is it a Solaris issue? A Java issue? An X Windows issue? Help!&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-9072504362461842933?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/9072504362461842933/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=9072504362461842933' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/9072504362461842933'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/9072504362461842933'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2011/01/java-interface-issue-that-makes-no.html' title='Java Interface issue that makes no sense to me'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-8642098963104472903</id><published>2011-01-14T15:02:00.000-05:00</published><updated>2011-01-14T15:02:34.725-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='graphical programming'/><category scheme='http://www.blogger.com/atom/ns#' term='news'/><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='ubuntu'/><category scheme='http://www.blogger.com/atom/ns#' term='rss'/><category scheme='http://www.blogger.com/atom/ns#' term='yahoo pipes'/><title type='text'>Graphical Programming with Yahoo Pipes</title><content type='html'>Let us start with the need. I found a tool to allow me to &lt;a href="http://www.omgubuntu.co.uk/2011/01/news-scrolling-rss-ticker-for-your-desktop/"&gt;scroll RSS feeds across my desktop&lt;/a&gt;, just like every news channel. &amp;nbsp;This is a neat thing, but I found that I didn't like the way it did RSS feeds. Instead of cycling through them, it kept using one. So, I set about solving that by combining feeds.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_1wdUwIPTY7U/TTClSL2hmbI/AAAAAAAABkY/mqPTM_E67lE/s1600/Screenshot-Pipes%253A+editing+%2527Lafayette+News+Feed%2527+-+Google+Chrome.png" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" height="286" src="http://2.bp.blogspot.com/_1wdUwIPTY7U/TTClSL2hmbI/AAAAAAAABkY/mqPTM_E67lE/s400/Screenshot-Pipes%253A+editing+%2527Lafayette+News+Feed%2527+-+Google+Chrome.png" width="400" /&gt;&lt;/a&gt;The method I chose was &lt;a href="http://pipes.yahoo.com/"&gt;Yahoo Pipes&lt;/a&gt;. When I decided to check Craigslist for items of certain types (Fender guitars, especially) in local areas (where I decided I could reasonably drive, should the catch of a lifetime come around), I used Pipes, mostly as an excuse to learn it. With Google Reader being the recipient of those feeds, I didn't need to massage them too much. The news I fed News was twitter feeds from news sites I wanted to follow, mostly local news and weather.&lt;br /&gt;&lt;br /&gt;To the right, we see the "code" I used to combine seven news sources, (mostly) remove redundancies, do some slight editing to the content and ensure that only the day's news shows up. It's all Twitter RSS, so &lt;a href="http://www.disruptiveconversations.com/2007/03/yahoopipes_and_.html"&gt;there's one date format&lt;/a&gt;, but that format is not usably sortable. I format today's date in the same format and filter out if it isn't there, but the better solution is to take a Unix timestamp of the current time and date (representing seconds since Jan. 1, 1970), subtract 24*24*60 (number of seconds in a day) and drop out entries that were not published during that time. That will take a slightly larger amount of cleverness to do that, but I think I'll crack that nut eventually.&lt;br /&gt;&lt;br /&gt;The thing I notice is, while a graphical solution seems tailor-made to mimic flowcharts, there's no splitting here. It's all very linear, with minor loops and filters. I suppose I could get a more funnel-looking program if I handled the inputs separately.&amp;nbsp;The more I play with Yahoo Pipes, the more I like it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-8642098963104472903?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/8642098963104472903/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=8642098963104472903' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/8642098963104472903'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/8642098963104472903'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2011/01/graphical-programming-with-yahoo-pipes.html' title='Graphical Programming with Yahoo Pipes'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_1wdUwIPTY7U/TTClSL2hmbI/AAAAAAAABkY/mqPTM_E67lE/s72-c/Screenshot-Pipes%253A+editing+%2527Lafayette+News+Feed%2527+-+Google+Chrome.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-2829984054513746905</id><published>2011-01-13T12:39:00.001-05:00</published><updated>2011-01-13T13:17:18.300-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='technology'/><title type='text'>Quick Notes: The Doomed Dozen, The New Radio</title><content type='html'>&lt;a href="http://www.maximumpc.com/"&gt;MaximumPC&lt;/a&gt; has list of &lt;a href="http://www.maximumpc.com/article/features/12_technologies_brink_disappearing"&gt;12 Technologies on the Bring of Disappearing&lt;/a&gt;. This is a bit more long-view than I normally go, but it makes sense. &lt;div&gt;&lt;blockquote&gt;&lt;/blockquote&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;The Doomed Half-Dozen&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;Pre-recorded Physical Media&lt;/li&gt;&lt;li&gt;Stereoscopic (with glasses) 3D TVs&lt;/li&gt;&lt;li&gt;eBook Readers&lt;/li&gt;&lt;li&gt;Consumer-Level Hard Drives&lt;/li&gt;&lt;li&gt;Keys&lt;/li&gt;&lt;li&gt;Handheld Gaming Consoles&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;&lt;b&gt;The Half-Dozen Survivors&lt;/b&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;Digital Music/Media Players&lt;/li&gt;&lt;li&gt;Landline telephone&lt;/li&gt;&lt;li&gt;Internal Combustion Automobile Engine&lt;/li&gt;&lt;li&gt;The PC&lt;/li&gt;&lt;li&gt;The Keyboard&lt;/li&gt;&lt;li&gt;The Mouse&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;I do have some quibbles with the list, and some more quibbles with the presentation of the list. For instance, if you're going to keep the landline phone alive as a bulwark against power-outages, then why show a portable phone, whose base unit will die as soon as the power is cut? And the eBook reader holds a niche in that the screen makes it a low-energy device, opposed to the power-hungry notebooks, tablets and smartphones. They're mostly single-taskers, to borrow an Alton Brown term, but they can grow up and out the same way the digital media player is. &lt;a href="http://www.maximumpc.com/article/features/12_technologies_brink_disappearing"&gt;The list is well-worth reading&lt;/a&gt;, though. &lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So, our car is in the shop, and the insurance company has us in a rental. It's a swank piece of motor art, with &lt;i&gt;gratis&lt;/i&gt; satellite radio. We're not too used to it, but we're getting there. The Old Radio has been dead to me for quite some time, as it struck me that there wasn't anything I wasn't sick of being sent to me over those airwaves. The little I hear on the XM/Sirius channels I get over DishTV has been interesting, but never interesting enough for me to even consider it for myself. I have a large enough MP3 collection that I could go some months without repeating a song. (That I do repeat songs has something to do with being a musician, with the limits of Rhythmbox's shuffle function, and with the limits of the SD card in my phone.) And, quite honestly, I don't spend enough time on the road to make it worthwhile.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;But I'm beginning to wonder about my wife. She does spend great amounts of time on the road, and given her preference for talk radio, I'm thinking it might be good fit for her. Her stations come out of Chicago and are mostly static when she comes to pick me up. But then, I'm wondering if streaming it with 3G or 4G smartphones would be a better solution. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;What are your thoughts about dying technologies and/or the New Radio? &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-2829984054513746905?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/2829984054513746905/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=2829984054513746905' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/2829984054513746905'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/2829984054513746905'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2011/01/quick-notes-doomed-dozen-new-radio.html' title='Quick Notes: The Doomed Dozen, The New Radio'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-7658756515041402512</id><published>2011-01-04T13:59:00.000-05:00</published><updated>2011-01-04T13:59:41.418-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='defining terms'/><title type='text'>Defining Terms: Copy-and-Paste vs Cargo-Cult</title><content type='html'>During WWII, in the South Pacific, major sea battles left many sinking cargo ships, whose cargo then floated to neighboring islands. Sufficiently advanced technology is indistinguishable from magic, and the inhabitants of these islands had been barely touched by the events of the 20th century so far, so they took the cargo as signs of gods who should be worshipped. Thus a &lt;strong&gt;&lt;code&gt;cargo cult programmer&lt;/code&gt;&lt;/strong&gt;&amp;nbsp;is a person who takes the sample code as the work of a diety, not to be understood and changed but to sit, inviolate, in the code base.&lt;br /&gt;&lt;br /&gt;In contrast, &lt;strong&gt;&lt;code&gt;copy-and-paste programming&lt;/code&gt;&lt;/strong&gt; is taking a solution for one case and copying it, pasting it, making a small change for the next case, and so on. If there's one line of change in a 20-line copied chunk, this means that there are 19 lines that are duplicated, and if there's a problem, 19 lines that have to be serially debugged and fixed wherever you left them, and you might easily forget many of them. It's better to pull as much as you can to a subroutine so if there's a bug, there is one and only one place you have to go to fix it.&lt;br /&gt;&lt;br /&gt;Clearly, two anti-patterns you should try to avoid in your programming life, to be sure, but if you copy code from a website and paste it into your own program, you are not a copy-and-paste programmer. Please respect the distinction.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-7658756515041402512?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/7658756515041402512/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=7658756515041402512' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/7658756515041402512'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/7658756515041402512'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2011/01/defining-terms-copy-and-paste-vs-cargo.html' title='Defining Terms: Copy-and-Paste vs Cargo-Cult'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-2746536767758569623</id><published>2010-12-09T00:23:00.000-05:00</published><updated>2010-12-09T00:23:23.976-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cool'/><category scheme='http://www.blogger.com/atom/ns#' term='telephony'/><category scheme='http://www.blogger.com/atom/ns#' term='cellphones'/><category scheme='http://www.blogger.com/atom/ns#' term='television'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><category scheme='http://www.blogger.com/atom/ns#' term='networking'/><title type='text'>The New Telephony meets the New Television: Expensive Remote</title><content type='html'>&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://1.bp.blogspot.com/_1wdUwIPTY7U/TQBaALVackI/AAAAAAAABdA/rjcsdIX7fpc/s1600/boxee.jpg" imageanchor="1" style="clear: right; float: right; margin-bottom: 1em; margin-left: 1em;"&gt;&lt;img border="0" height="320" src="http://1.bp.blogspot.com/_1wdUwIPTY7U/TQBaALVackI/AAAAAAAABdA/rjcsdIX7fpc/s320/boxee.jpg" width="320" /&gt;&lt;/a&gt;&lt;/div&gt;I have fairly close to the top end of the smartphones, the HTC Evo Android phone. I have a Vista computer connected to the Internet. I have just installed &lt;a href="http://boxee.tv/"&gt;Boxee&lt;/a&gt;&amp;nbsp;on said TV. Thing is, this TV, while it has a big screen and all, is across the room from me, and the keyboard and mouse are corded.&lt;br /&gt;&lt;br /&gt;I did say I have an Android phone, right?&lt;br /&gt;&lt;br /&gt;While it is a wonder of technology that can talk to WiFi, Bluetooth and 3G/4G mobile networks, and do much cooler stuff. I can watch video. I can make video. It is a cool thing. Being able to control my other computer is minor, but still cool.&lt;br /&gt;&lt;br /&gt;I've done something like this before. Years ago, I had a Palm III. You could install an app that made your Palm into a programmable universal remote. That's cool, but that's coolness relying on IR and line-of-site and the IR source was meant for sending electronic business cards 3 feet away, not turning on a DVD player 10 feet away. This works over wireless networking, so line of sight is done, and thanks for that.&lt;br /&gt;&lt;br /&gt;I'm also new to virtualizing interfaces. I've been a big fan of Synergy2 to allow you to have one keyboard for two or more computers. I just didn't expect it to touch the smartphone.&lt;br /&gt;&lt;br /&gt;I &lt;i&gt;know&lt;/i&gt; I'm at best second or third wave on this sort of thing. MythTV's been around for over 5 years, and many of these concepts are very stable. Microsoft's been putting these capabilities as part of their advertisements these days. And I &lt;i&gt;know&lt;/i&gt; there are things involved here that I'm taking the goofy way around with. Big example is moving media onto my Android. (I call it&amp;nbsp;&lt;code&gt;RoyBatty&lt;/code&gt;, by the way. Considered going with&amp;nbsp;&lt;code&gt;RickDeckard&lt;/code&gt;, but no.) The old reliable way to do it would be to plug in the USB/charging cable. The slightly cooler way is via Bluetooth. My way is to use Dropbox. It's a cool and wonderful cross-platform thing. I was expecting full syncing, but it turns out to be pick-and-choose, which is &lt;i&gt;okay&lt;/i&gt;, but it means I'm more active.) I think the really cool solution would be to using uPnP/DLNA. This means I have to start learning how to make that stuff work.&lt;br /&gt;&lt;br /&gt;But seriously, this really convinces me that the New Television is a big monitor, receiving signal from whatever device you want, and not really the interface device in and of itself.&lt;br /&gt;&lt;br /&gt;Now, if you excuse me, I'll watch some Revision3 on my computer as I go to bed.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-2746536767758569623?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/2746536767758569623/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=2746536767758569623' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/2746536767758569623'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/2746536767758569623'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2010/12/new-telephony-meets-new-television.html' title='The New Telephony meets the New Television: Expensive Remote'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_1wdUwIPTY7U/TQBaALVackI/AAAAAAAABdA/rjcsdIX7fpc/s72-c/boxee.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-3117096639492300881</id><published>2010-12-06T11:41:00.002-05:00</published><updated>2010-12-06T16:51:12.891-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='frustration'/><category scheme='http://www.blogger.com/atom/ns#' term='html'/><title type='text'>Stupid HTML Error</title><content type='html'>Code Block A.&lt;br /&gt;&lt;pre name="code" class="html"&gt;&lt;br /&gt;&amp;lt;form&gt;&lt;br /&gt;    &amp;lt;table id="target"&gt;&lt;br /&gt;        &amp;lt;tr&gt;&amp;lt;td&gt; &amp;lt;input type="text" name="foo"&gt;&amp;lt;/dr&gt;&amp;lt;/tr&gt;&lt;br /&gt;    &amp;lt;/table&gt;&lt;br /&gt;&amp;lt;/form&gt;&lt;/pre&gt;&lt;br /&gt;Code Block B.&lt;br /&gt;&lt;pre name="code" class="html"&gt;&lt;br /&gt;&amp;lt;table id="target"&gt;&lt;br /&gt;    &amp;lt;form&gt;&lt;br /&gt;        &amp;lt;tr&gt;&amp;lt;td&gt;&amp;lt;input type="text" name="foo"&gt;&amp;lt;/dr&gt;&amp;lt;/tr&gt;&lt;br /&gt;    &amp;lt;/form&gt;&lt;br /&gt;&amp;lt;/table&gt;&lt;/pre&gt;Not much difference, is there? In fact, I'd say they're functionally identical, unless you set &lt;code&gt;form&lt;/code&gt; as a block in your CSS. But there is a difference if you're going to use Javascript to add to the form. If you append to the table, you'll get something like this.&lt;br /&gt;&lt;pre name="code" class="html"&gt;&lt;br /&gt;&amp;lt;table id="target"&gt;&lt;br /&gt;    &amp;lt;form&gt;&lt;br /&gt;        &amp;lt;tr&gt;&amp;lt;td&gt; &amp;lt;input type="text" name="foo"&gt;&amp;lt;/dr&gt;&amp;lt;/tr&gt;&lt;br /&gt;    &amp;lt;/form&gt;&lt;br /&gt;    &amp;lt;tr&gt;&amp;lt;td&gt; &amp;lt;input type="text" name="bar"&gt;&amp;lt;/dr&gt;&amp;lt;/tr&gt;&lt;br /&gt;&amp;lt;/table&gt;&lt;/pre&gt;&lt;br /&gt;And this will not be part of the form when you press submit. Which I have conveniently left out of the code blocks. Hrmm. Still, watch for that. It's the problem that hounded me over the weekend.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-3117096639492300881?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/3117096639492300881/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=3117096639492300881' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/3117096639492300881'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/3117096639492300881'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2010/12/stupid-html-error.html' title='Stupid HTML Error'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-7347508080325329249</id><published>2010-11-29T17:50:00.000-05:00</published><updated>2010-11-29T17:50:35.309-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='gizmo'/><category scheme='http://www.blogger.com/atom/ns#' term='cellphones'/><category scheme='http://www.blogger.com/atom/ns#' term='android'/><category scheme='http://www.blogger.com/atom/ns#' term='new gear day'/><title type='text'>First Real Day With Android/EVO</title><content type='html'>I received the thing Friday and poked at it all weekend. I don't think I'll have to decide to love this thing.&lt;br /&gt;&lt;br /&gt;But I have found a problem. Or at least a non-solution.&lt;br /&gt;&lt;br /&gt;I work in a sub-basement. This means no cell connection. I mean, if I sat six feet to the south, there's a slight chance I could get a quarter-bar just enough for a ring. But I don't. So, I have been dreaming of ways to get my phone on. My way has been Google Voice and Gizmo. This meant that I cart my netbook with me. I had been hoping that I could answer calls via WiFi, but that seems to be a no-go.&lt;br /&gt;&lt;br /&gt;There's also a Voyage app, but it only works on GSM phones, not CDMA phones like mine. What might work is Skype, but that strikes me as a mighty big if.&lt;br /&gt;&lt;br /&gt;So, we'll see how things go.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-7347508080325329249?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/7347508080325329249/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=7347508080325329249' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/7347508080325329249'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/7347508080325329249'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2010/11/first-real-day-with-androidevo.html' title='First Real Day With Android/EVO'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-1604018749730994500</id><published>2010-11-17T10:17:00.000-05:00</published><updated>2010-11-17T10:17:30.904-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='bug report'/><category scheme='http://www.blogger.com/atom/ns#' term='fail'/><category scheme='http://www.blogger.com/atom/ns#' term='routeshout'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='frustration'/><title type='text'>Have Mercy! A RouteShout Signage Bug</title><content type='html'>I now live where the buses go, and I've been taking a bus to work for a little over a month. I can't say there haven't been problems, but I can and must admit that they've all been self-inflicted.&lt;br /&gt;&lt;br /&gt;They have signs under all the bus stops saying "Text this code to 25252 and find out how long the wait is". I have tried it, and it fails.&lt;br /&gt;&lt;br /&gt;Turns out, this is not an in-house thing, but a service provided through a company called &lt;a href="http://www.routeshout.com/"&gt;RouteShout&lt;/a&gt;. There's more than just texting, though. There's an iPhone app, an Android app, a &lt;a href="http://m.routeshout.com/"&gt;mobile site&lt;/a&gt;&amp;nbsp;for those with older, less-smart phones and an &lt;a href="http://www.routeshout.com/main/api"&gt;API&lt;/a&gt;. That's the point where I said "cool" and dove in. And found the problem.&lt;br /&gt;&lt;br /&gt;Say you have a bus stop. Say CityBus labelled it &lt;code&gt;BUS666&lt;/code&gt;. Well, if you're gonna get on a bus someplace, you'll want to come back near there, too. So, we can think of&amp;nbsp;&lt;code&gt;BUS666&lt;/code&gt; as where you get picked up and where you get let off. Except, sometimes the bus will go up and down the same road. For example, the bus I take from my apartment goes around a mall and comes back. So&amp;nbsp;&lt;code&gt;BUS666&lt;/code&gt; is on both sides of the street. If I'm waiting on the north side of the street, I don't care about buses coming to the south side, except when they're coming around and back to the north side. So, we have&amp;nbsp;&lt;code&gt;BUS666N&lt;/code&gt; and&amp;nbsp;&lt;code&gt;BUS666S&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;But the signs still say&amp;nbsp;&lt;code&gt;BUS666&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;And if you text&amp;nbsp;&lt;code&gt;BUS666&lt;/code&gt; to 25252, rather than&amp;nbsp;&lt;code&gt;BUS666N&lt;/code&gt;. Which makes the texting interface useless. And you have to get inside the API to figure out where the problem is.&lt;br /&gt;&lt;br /&gt;(As it turns out,&amp;nbsp;&lt;code&gt;BUS666&lt;/code&gt; is one stop, not two, and doesn't have this problem. It also is far away from anywhere I take the bus to, so using it as an example doesn't lead to people knowing where I live.)&lt;br /&gt;&lt;br /&gt;Again, this is a signage bug. The RouteShout service works perfectly, as far as I've seen. I think I'll put together a Perl module from the API and put that on CPAN. Yay to them.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-1604018749730994500?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/1604018749730994500/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=1604018749730994500' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/1604018749730994500'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/1604018749730994500'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2010/11/have-mercy-routeshout-signage-bug.html' title='Have Mercy! A RouteShout Signage Bug'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-4248408000839317539</id><published>2010-11-10T12:05:00.000-05:00</published><updated>2010-11-10T12:05:50.984-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='games'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='perl'/><title type='text'>Solving a Brain Teaser with word lists and Perl</title><content type='html'>I'm a programmer. When I see a problem, I get tempted to code the solution. One place where this temptation comes into play is brain teaser problems. Once, a while ago, a radio show had a brain teaster where you take the phrase &lt;b&gt;PRECHRISTMAS SALE&lt;/b&gt;, turn it into a 4x4 block and find the longest word you can without reusing a letter. I used Perl and found six eight-letter words.&lt;br /&gt;&lt;br /&gt;And, of course I used my powers on Sudoku. &lt;br /&gt;&lt;br /&gt;Now, I've seen a &lt;a href="http://www.mentalfloss.com/blogs/archives/73467"&gt;problem&lt;/a&gt; that's inspired me again. &lt;br /&gt;&lt;blockquote&gt;By changing one letter at a time to form different English words, and leaving all other letters in their original positions, convert SIXTH into TENTH in the fewest steps possible. Good luck!&lt;br /&gt;&lt;b&gt;&lt;/b&gt;&lt;br /&gt;&lt;pre&gt;&lt;b&gt;S I X T H&lt;br /&gt;_ _ _ _ _&lt;br /&gt;_ _ _ _ _&lt;br /&gt;_ _ _ _ _&lt;br /&gt;_ _ _ _ _&lt;br /&gt;_ _ _ _ _&lt;br /&gt;_ _ _ _ _&lt;br /&gt;T E N T H&lt;/b&gt;&lt;/pre&gt;&lt;/blockquote&gt;&lt;b&gt;There are Spoilers below&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;As I learned with &lt;code&gt;PRECHRISTMASSALE&lt;/code&gt;, which I've since found is Boggle, if you're going to find words, you first need to know words. So, I pulled and adapted my Boggle code for coming up with a dictionary list.&lt;br /&gt;&lt;pre class="perl" name="code"&gt;sub dictionary {&lt;br /&gt;    my ( $length ) = @_ ;&lt;br /&gt;    my %done ;&lt;br /&gt;    my %word ;&lt;br /&gt;    my $dir = './Dict' ;&lt;br /&gt;    my $dirhandle ;&lt;br /&gt;    opendir $dirhandle, $dir ;&lt;br /&gt;    my $file ;&lt;br /&gt;    while ( defined( $file = readdir $dirhandle ) ) {&lt;br /&gt;        next if $file =~ m(^\.)mx ;&lt;br /&gt;        open my $filehandle, '&amp;lt;', $dir . q{/} . $file ;&lt;br /&gt;        while ( &amp;lt;$filehandle&amp;gt; ) {&lt;br /&gt;            chomp ;&lt;br /&gt;            $_ = lc $_ ;&lt;br /&gt;            next if $done{ $_ }++ ;&lt;br /&gt;            next if length != $length ;&lt;br /&gt;            $word{ $_ }++ ;&lt;br /&gt;            }&lt;br /&gt;        close $filehandle ;&lt;br /&gt;        }&lt;br /&gt;    closedir $dirhandle ;&lt;br /&gt;    return sort { $a cmp $b } keys %word ;&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;Of course, you need to be in the same directory as a directory full of dictionaries. I used a few I pulled from &lt;a href="ftp://ftp.cerias.purdue.edu/pub/dict/wordlists/dictionaries/"&gt;the CERIAS FTP site&lt;/a&gt;, and probably has some overlap, but better that then missing a word and thus a connection.&lt;br /&gt;&lt;br /&gt;I then started poking at the words, trying to find the next. I came up with a way to get all the proper alternatives, given a word. I then pulled it into a subroutine.&lt;br /&gt;&lt;pre class="perl" name="code"&gt;sub get_word_choices {&lt;br /&gt;    my ( $word ) = shift ;&lt;br /&gt;    my @word = split m{}mx, $word ;&lt;br /&gt;    my @output ;&lt;br /&gt;    for my $pos ( 0 .. scalar @word - 1 ) {&lt;br /&gt;        my @local = @word ;&lt;br /&gt;        $local[ $pos ] = '.' ;&lt;br /&gt;        my $local = join '', @local ;&lt;br /&gt;        my @words = grep { m{$local}mx } grep { !m{$word}mx } @dictionary ;&lt;br /&gt;        next if scalar @words == 0 ;&lt;br /&gt;        push @output , @words ;&lt;br /&gt;        }&lt;br /&gt;    return @output ;&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;I should probably pass &lt;code&gt;@dictionary&lt;/code&gt; rather than leave it as a global, but certainly, you don't want to re-parse the dictionary file each time.&lt;br /&gt;&lt;br /&gt;It struck me about this point that I should have all I need to automatically solve this, not leaving me to use this tool to piece something together.&lt;br /&gt;&lt;br /&gt;I am not as happy with this part as I could be.&lt;br /&gt;&lt;pre class="perl" name="code"&gt;sub check_words {&lt;br /&gt;    my $word2 = shift ;&lt;br /&gt;    my @words = @_ ;&lt;br /&gt;    return if scalar @words &amp;gt; 7 ;&lt;br /&gt;    my $last = $words[-1] ;&lt;br /&gt;    if ( $last eq $word2 ) {&lt;br /&gt;        say '' ;&lt;br /&gt;        say join ' ' , @words , scalar @words ;&lt;br /&gt;        }&lt;br /&gt;    my @choices = get_word_choices( $last ) ;&lt;br /&gt;    #say join ' ' , @words ;&lt;br /&gt;    for my $choice ( @choices ) {&lt;br /&gt;        next if grep { m{$choice}mx } @words ;&lt;br /&gt;        check_words( $word2 , @words , $choice ) ;&lt;br /&gt;        }&lt;br /&gt;    print join ' ' ,  '' , scalar @words ;&lt;br /&gt;    return ;&lt;br /&gt;    }&lt;br /&gt;&lt;/pre&gt;It's depth-first search and it's &lt;em&gt;long&lt;/em&gt;. Which, I suppose, is unavoidable for depth-first search. Consider this solution:&lt;br /&gt;&lt;pre&gt;sixth&lt;br /&gt;sixte&lt;br /&gt;sixty&lt;br /&gt;silty&lt;br /&gt;tilty&lt;br /&gt;tinty&lt;br /&gt;tenty&lt;br /&gt;tenth &lt;/pre&gt;&lt;em&gt;sixth&lt;/em&gt; to &lt;em&gt;sixty&lt;/em&gt; is just as legal a jump as &lt;em&gt;sixth&lt;/em&gt; to &lt;em&gt;sixte&lt;/em&gt;. If I used an iterative process with a better data structure, I could use a shortest path algorithm and bypass &lt;em&gt;sixte&lt;/em&gt;. And, of course, by putting &lt;code&gt;print&lt;/code&gt; to give me some appreciation of progress, I'm bogging the thing way down. So, that's where I'd rewrite to make this better.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-4248408000839317539?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/4248408000839317539/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=4248408000839317539' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/4248408000839317539'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/4248408000839317539'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2010/11/solving-brain-teaser-with-word-lists.html' title='Solving a Brain Teaser with word lists and Perl'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-2284689138850576183</id><published>2010-11-08T10:44:00.000-05:00</published><updated>2010-11-08T10:44:29.220-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='television'/><title type='text'>Somehow The New Television is listening to Me</title><content type='html'>And not in the creepy HAL2000 kind of way.&lt;br /&gt;&lt;br /&gt;I was searching for info on Net Neutrality, wrapping my head around it, and found &lt;a href="http://www.hulu.com/watch/170294/attack-of-the-show-net-neutrality-with-verizon-and-google"&gt;this bit&lt;/a&gt; from G4's &lt;i&gt;Attack of the Show&lt;/i&gt;&amp;nbsp;on Hulu. Next clip on the channel was on Bluetooth headsets, and it was presented by Dungeons and Dragons. Which was a bit of a wow for me.&lt;br /&gt;&lt;br /&gt;I've been &lt;a href="http://varlogrant.blogspot.com/2010/08/every-now-and-then-i-turn-it-on-again.html"&gt;clear on this&lt;/a&gt;, but let me restate that I am not categorically against advertising because advertising, properly done, is content. Consider the copy of &lt;i&gt;The Productive Programmer&lt;/i&gt; on my desk right now. The last page before the back cover is an ad that says you can read this book online for 45 days at Safari Online. If you're reading a book called &lt;i&gt;The Productive Programmer&lt;/i&gt;, you're more than likely a programmer. Which means you deal with computers a lot. Reading this book online will make sense to you, as you read much online. It's as much content to you as the book's suggestions for Desktop shortcuts. This doesn't mean that you, as the programmer reading this book, will jump up and start reading online any more than it means that you will immediately pick up Virtual Desktop Manager to get virtual desktops on your XP dev box. But it'll be something at least interesting to you.&lt;br /&gt;&lt;br /&gt;However, if the back-of-the-book ad was Chanel #5 or Audis or Levi's jeans, it would be far less clear that there's a connection between the audience and the advertisement. This is where mass-market media starts to fall apart. They make a statistical model of their audience, or who they want their audience to be, and advertisers who want to sell to that audience buy ads. If you are not in that statistical model, or the statistical model is too general, the ads will not speak to you.&lt;br /&gt;&lt;br /&gt;I haven't been an RPG gamer in two decades. D&amp;amp;D is not going to sell me, but it seems a more natural fit to the G4 audience than cars.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-2284689138850576183?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/2284689138850576183/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=2284689138850576183' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/2284689138850576183'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/2284689138850576183'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2010/11/somehow-new-television-is-listening-to.html' title='Somehow The New Television is listening to Me'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-145332831106508186.post-5499289483887844147</id><published>2010-11-05T15:14:00.000-04:00</published><updated>2010-11-05T15:14:30.610-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='telephony'/><category scheme='http://www.blogger.com/atom/ns#' term='television'/><category scheme='http://www.blogger.com/atom/ns#' term='we live in the future'/><title type='text'>The New Television is similar to the (Older) New Telephone</title><content type='html'>When I was in college about a decade ago, I knew some people who didn't have a "landline", or a traditional wired telephone in their place of residence. It made sense to me for college students. If you're out and studying, going to classes, working between classes, etc., it made sense that you weren't home enough to hear your phone ringing, so it's best to just have the mobile phone and not worry about it. For students, sure that made perfect sense. For adults, however, I wasn't sure. Come ten years after, you have more and more people who are dropping the landline that are out of school. There are sticking points, like how E911 for mobile isn't quite as far as for traditional telephony*, but it's a trade-off more and more making.&lt;br /&gt;&lt;br /&gt;I have an adapter for my old-school TV that allows me to plug my netbook's VGA and watch YouTube, or whatever, on the big screen. My Wii can do Netflix, as can my friend's iPhone. Android is coming soon. Hulu can bring most of my favorite shows to me. Not &lt;i&gt;everything&lt;/i&gt;, but close and closer all the time. If this is true, if you can get all the moving pictures you need from the internets and don't need the co-ax run. And we're not talking people who can't afford cable. We're talking people &lt;a href="http://www.dslreports.com/shownews/Cord-Cutters-Young-Educated-And-Employed-111157"&gt;who decided that they just didn't need another wire run and time-sink in their lives&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The comments highlight a few of the hinderances with this. First, if you want to watch live events, like sporting events or news, you're out of luck. If there's a way to see &lt;i&gt;Big Bang Theory&lt;/i&gt;&amp;nbsp;or &lt;i&gt;The Marty Stuart Show&lt;/i&gt; or new episodes of Discovery shows online, I've yet to see it. And this model is more-or-less fine if you know what you watch and watch what you know, but it locks you out of searching through and finding the next cool thing you didn't know existed. So, TV-wise, I'm not a cord-cutter yet. But I'm moving that way.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;em&gt;&lt;b&gt;*&lt;/b&gt; The two times I've had to dial 911, I was calling because of a car accident. &lt;/em&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/145332831106508186-5499289483887844147?l=varlogrant.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://varlogrant.blogspot.com/feeds/5499289483887844147/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=145332831106508186&amp;postID=5499289483887844147' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/5499289483887844147'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/145332831106508186/posts/default/5499289483887844147'/><link rel='alternate' type='text/html' href='http://varlogrant.blogspot.com/2010/11/new-television-is-similar-to-older-new.html' title='The New Television is similar to the (Older) New Telephone'/><author><name>Dave Jacoby</name><uri>https://profiles.google.com/114091415913150177607</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh3.googleusercontent.com/-qZQfNlcR3J0/AAAAAAAAAAI/AAAAAAAAB0Q/CTsnIZwSsr8/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry></feed>
