<?xml version='1.0' encoding='UTF-8'?><rss xmlns:atom='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' version='2.0'><channel><atom:id>tag:blogger.com,1999:blog-8499998</atom:id><lastBuildDate>Sun, 06 May 2012 07:06:05 +0000</lastBuildDate><category>mapReduce</category><category>cost</category><category>rackspace</category><category>javascript</category><category>s3</category><category>mongoDB</category><category>cloud files</category><title>leifw</title><description></description><link>http://leifw.wickland.net/</link><managingEditor>noreply@blogger.com (Leif Wickland)</managingEditor><generator>Blogger</generator><openSearch:totalResults>210</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-8499998.post-5775973804163006414</guid><pubDate>Wed, 11 Apr 2012 04:30:00 +0000</pubDate><atom:updated>2012-04-11T08:24:48.106-06:00</atom:updated><title>Montana Wedding Photography: Katherine and Christopher</title><description>For the past two years, I've been having a blast second-shooting weddings for the awesome &lt;span id="goog_1206845878"&gt;&lt;/span&gt;&lt;a href="http://wanderingalbatrossphotography.com/"&gt;Wandering Albatross Photography&lt;/a&gt;&lt;span id="goog_1206845879"&gt;&lt;/span&gt;. &amp;nbsp;Last summer, I got to shoot &lt;a href="http://wanderingalbatrossphotography.wordpress.com/2011/08/26/hometown-icons-katherine-christopher/"&gt;Katherine and Christopher&lt;/a&gt;'s wedding in Helena, Montana.&lt;br /&gt;
&lt;br /&gt;
Here are some of my favorite shots from that day.&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/-DJuDFpub2Ag/T4Re_OZqRCI/AAAAAAAAGxk/iZVdmp-XfYM/s1600/chriskatherine084.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/-DJuDFpub2Ag/T4Re_OZqRCI/AAAAAAAAGxk/iZVdmp-XfYM/s1600/chriskatherine084.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="http://4.bp.blogspot.com/-7lb3WCFsgqI/T4RfFTa-LYI/AAAAAAAAGxs/C7CXYc0SliM/s1600/chriskatherine147.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/-7lb3WCFsgqI/T4RfFTa-LYI/AAAAAAAAGxs/C7CXYc0SliM/s1600/chriskatherine147.jpg" /&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: center;"&gt;
&lt;a href="http://4.bp.blogspot.com/-PcfOFjnT-n8/T4RfKdqo4GI/AAAAAAAAGx0/PDRxkYjcwYQ/s1600/chriskatherine252.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/-PcfOFjnT-n8/T4RfKdqo4GI/AAAAAAAAGx0/PDRxkYjcwYQ/s1600/chriskatherine252.jpg" /&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: center;"&gt;
&lt;a href="http://3.bp.blogspot.com/-ijTU2MX8a0s/T4RfOllr0pI/AAAAAAAAGx8/RE0e4q4qWcM/s1600/chriskatherine444.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://3.bp.blogspot.com/-ijTU2MX8a0s/T4RfOllr0pI/AAAAAAAAGx8/RE0e4q4qWcM/s1600/chriskatherine444.jpg" /&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: center;"&gt;
&lt;a href="http://4.bp.blogspot.com/-E3qCr2eKRrE/T4RfQ1DwfMI/AAAAAAAAGyE/QIvNRgWaiiw/s1600/chriskatherine467.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="http://4.bp.blogspot.com/-E3qCr2eKRrE/T4RfQ1DwfMI/AAAAAAAAGyE/QIvNRgWaiiw/s1600/chriskatherine467.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8499998-5775973804163006414?l=leifw.wickland.net' alt='' /&gt;&lt;/div&gt;</description><link>http://leifw.wickland.net/2012/04/montana-wedding-photography-katherine.html</link><author>noreply@blogger.com (Leif Wickland)</author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/-DJuDFpub2Ag/T4Re_OZqRCI/AAAAAAAAGxk/iZVdmp-XfYM/s72-c/chriskatherine084.jpg' height='72' width='72'/><thr:total>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-8499998.post-1922661054705552335</guid><pubDate>Fri, 13 Jan 2012 18:37:00 +0000</pubDate><atom:updated>2012-01-13T11:42:11.529-07:00</atom:updated><title>JavaScript's encodeURIComponent and character sets</title><description>The&lt;a href="http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf"&gt; EcmaScript 5 standard&lt;/a&gt; (section 15.1.3.4) and the Mozilla Developer Network page on &lt;a href="https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/encodeURIComponent"&gt;encodeURIComponent&lt;/a&gt; both say that the string will be encoded to UTF-8, regardless of the underlying page's character set.  That seemed entirely too convenient to believe, so I wrote a page that would let me exercise it.  I hit it with modern browsers as well as Firefox 2 and Internet Explorer 5.5 and 6.  Amazingly, they handled it correctly, even for pages in obscure character sets like &lt;a href="http://en.wikipedia.org/wiki/GBK"&gt;GBK&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;Sleep well tonight in the knowledge that your characters are safe in hands of encodeURIComponent.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8499998-1922661054705552335?l=leifw.wickland.net' alt='' /&gt;&lt;/div&gt;</description><link>http://leifw.wickland.net/2012/01/javascripts-encodeuricomponent-and.html</link><author>noreply@blogger.com (Leif Wickland)</author><thr:total>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-8499998.post-2814003080361561204</guid><pubDate>Fri, 21 Oct 2011 05:05:00 +0000</pubDate><atom:updated>2011-10-21T08:43:55.841-06:00</atom:updated><title>How I spent my summer vacation</title><description>&lt;h2&gt;
Backpacking!&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Stillwater Valley (4 days, 26 miles)&lt;/li&gt;

&lt;li&gt;Granite Peak Attempt (2 days, 20 miles)&lt;/li&gt;

&lt;li&gt;Glacier National Park Transit (6 days, 70 miles)&lt;/li&gt;

&lt;li&gt;Lava Lake Family Trip (2 days, 7 miles)&lt;/li&gt;

&lt;li&gt;Garnet Peak Lookout (2 days, 8 miles)&lt;/li&gt;

&lt;/ul&gt;

&lt;b&gt;Total: 16 days, ~120 miles&lt;/b&gt;&lt;p&gt;&lt;/p&gt;
&lt;a href="https://picasaweb.google.com/lh/photo/79SQheOO1odaFtFwIFYBfQ?feat=embedwebsite"&gt;&lt;img src="https://lh5.googleusercontent.com/-fzXQcJpfAMc/TqD4kPesw7I/AAAAAAAAGWo/kMxjpCLgWXQ/s800/LWW_7724.jpg" height="800" width="533" /&gt;&lt;/a&gt;
&lt;a href="https://picasaweb.google.com/lh/photo/omlPty-MCJ6l5d9xWqOcwg?feat=embedwebsite"&gt;&lt;img src="https://lh4.googleusercontent.com/-159HhGSVwuE/TqD56jl9pcI/AAAAAAAAGW4/qYc1IEAfzuc/s800/LWW_7864.JPG" height="531" width="800" /&gt;&lt;/a&gt;
&lt;p&gt;&lt;/p&gt;
It was a good summer.

(Apologies for the painfully white guy in the pictures.)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8499998-2814003080361561204?l=leifw.wickland.net' alt='' /&gt;&lt;/div&gt;</description><link>http://leifw.wickland.net/2011/10/how-i-spent-my-summer-vacation.html</link><author>noreply@blogger.com (Leif Wickland)</author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='https://lh5.googleusercontent.com/-fzXQcJpfAMc/TqD4kPesw7I/AAAAAAAAGWo/kMxjpCLgWXQ/s72-c/LWW_7724.jpg' height='72' width='72'/><thr:total>1</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-8499998.post-9794621630217696</guid><pubDate>Mon, 18 Jul 2011 16:21:00 +0000</pubDate><atom:updated>2011-07-18T10:21:58.223-06:00</atom:updated><title>What Stuck with Me from GlueCon</title><description>I recently gave a &lt;a href="http://j.mp/pmYDmB"&gt;tech talk&lt;/a&gt; reflecting on some of the highlights of &lt;a href="gluecon.com/2011/"&gt;GlueCon&lt;/a&gt;.  It covered the failure of SOAP, a survey of NoSQL data models, and a brief introduction to node.js.&lt;br&gt;&lt;br&gt;
&lt;iframe src="https://docs.google.com/present/embed?id=dc9spn43_224f7mx7mmt&amp;size=l" frameborder="0" width="700" height="559"&gt;&lt;/iframe&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8499998-9794621630217696?l=leifw.wickland.net' alt='' /&gt;&lt;/div&gt;</description><link>http://leifw.wickland.net/2011/07/what-stuck-with-me-from-gluecon.html</link><author>noreply@blogger.com (Leif Wickland)</author><thr:total>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-8499998.post-2960581920467732888</guid><pubDate>Wed, 08 Jun 2011 01:14:00 +0000</pubDate><atom:updated>2011-06-07T21:09:54.597-06:00</atom:updated><title>Mastered</title><description>The ol' postal service delivered the diploma cover for my master's in computer science today.  This was after receiving my diploma rolled up tightly in a cardboard tube a couple weeks back with a postcard voucher for a diploma cover.  That was after skipping (sorry, Mom) the six hour graduation ceremony I wasn't keen to sit through at the beginning of May.  That was after actually finishing up last December.  That was after taking (cough) 9 (eh hem) years to finish it while working full-time, being married, moving a few times, throwing away 9 credits due to transfer, throwing away another pile of credits after abandoning my first thesis, finishing a basement, designing and building another house, and raising a baby to a pre-schooler.  
&lt;p&gt;
I am far prouder of this degree than I ever was my bachelor's.  I was raised with the expectation of getting a college degree.  It was always a foregone conclusion in my mind that I would finish that one.  I struggled a bit with my bachelor's (I'm looking at you &lt;a href="http://www.letu.edu/academics/catalog/index.htm?cat_type=tu&amp;cat_year=2002&amp;course=301"&gt;Electric Circuits I&lt;/a&gt;), but I never had reason or occasion to consider quitting.  I can't count the times I wanted to give up on the master's.  
&lt;p&gt;
Special thanks to my wife and daughter for putting up with me during all that, to my adviser, Rocky Ross, for helping me finish, to Neal Richter for nagging my butt into gear more than once, and to Erich Hannan, my boss through most of that interval, for supporting me doing work and school.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8499998-2960581920467732888?l=leifw.wickland.net' alt='' /&gt;&lt;/div&gt;</description><link>http://leifw.wickland.net/2011/06/mastered.html</link><author>noreply@blogger.com (Leif Wickland)</author><thr:total>2</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-8499998.post-4449056258957103458</guid><pubDate>Sun, 17 Apr 2011 07:02:00 +0000</pubDate><atom:updated>2011-04-17T01:11:11.591-06:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>cost</category><category domain='http://www.blogger.com/atom/ns#'>s3</category><category domain='http://www.blogger.com/atom/ns#'>rackspace</category><category domain='http://www.blogger.com/atom/ns#'>cloud files</category><title>The Cost of Small Files in the Cloud</title><description>I've been working with a friend on a little project that generates a mound of small files.  Specifically, we'd like to serve 12 million files of less than 4 KB with an average size of 500 bytes.  It's only 6 GB.
&lt;br/&gt;&lt;br/&gt;
I thought Amazon S3 might be a reasonable way to do it, so I did the math.  I'm not expecting the project to get a lot of usage, so I initially only cared about the cost of getting the files out there.  &lt;a href="http://aws.amazon.com/s3/pricing/"&gt;Amazon S3 charges&lt;/a&gt; $0.01 per 1000 PUTs, $0.14/GB/month for storage, and $0.10/GB for input bandwidth.  For one month that's 12M/1000 * 0.01 + .14 * 6  + .1 * 6 = &lt;a href="http://www.wolframalpha.com/input/?i=12000000%2F1000+*+0.01+%2B+%28.14+*+6%29+%2B+%28.1+*+6+%29"&gt;$121.44&lt;/a&gt;, of which $120 comes from the cost of PUTs alone.  That quickly dissuaded me from considering S3.
&lt;br/&gt;&lt;br/&gt;
Then I remembered that Rackspace has a cloud file storage product, too.  &lt;a href="http://www.rackspace.com/cloud/cloud_hosting_products/files/pricing/"&gt;Rackspace's Cloud Files pricing&lt;/a&gt; is based only on bytes stored and incoming and outgoing bandwidth.  My 6 GB would cost $0.15/GB/month to store and $0.08/GB to upload, for a total of &lt;a href="http://www.wolframalpha.com/input/?i=%286+*+.15%29+%2B+%286+*+.08%29"&gt;$1.38&lt;/a&gt;.  Now we're talking.
&lt;br/&gt;&lt;br/&gt;
I was a little dubious about the pricing, so I contacted Rackspace to double check my numbers.  The rep told me I was doing the math right and claimed that you only pay for reported file size, not size rounded up to the nearest block and not HTTP header overhead.
&lt;br/&gt;&lt;br/&gt;
The cost winner if you want to store a bunch of small files in the Cloud is clearly Rackspace.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8499998-4449056258957103458?l=leifw.wickland.net' alt='' /&gt;&lt;/div&gt;</description><link>http://leifw.wickland.net/2011/04/price-of-files-in-cloud.html</link><author>noreply@blogger.com (Leif Wickland)</author><thr:total>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-8499998.post-6529044453575310387</guid><pubDate>Sun, 17 Apr 2011 06:30:00 +0000</pubDate><atom:updated>2011-04-18T08:03:56.331-06:00</atom:updated><title>How HTML5 geolocation works in Firefox, Chrome, and Internet Explorer</title><description>HTML5 introduces (will introduce?, will have introduced once it's approved?) the &lt;a href="http://dev.w3.org/geo/api/spec-source.html"&gt;Geolocation API&lt;/a&gt;, which enables a web page to ask your browser to ask you if the page can be told &lt;a href="http://html5demos.com/geo"&gt;where on earth you are&lt;/a&gt;. &amp;nbsp;For example, when composing a tweet, Twitter includes an "Add Your Location" link that uses this new API.&lt;br /&gt;
&lt;br /&gt;
Of course, your web browser doesn't just know where you are; it has to ask something else. &amp;nbsp;On a device like your mobile phone which includes a GPS receiver, the operating system can tell it. &amp;nbsp;However, on a notebook without GPS, your browser's not so lucky. &amp;nbsp;&lt;i&gt;Enter the might power of Google.&lt;/i&gt;&amp;nbsp; In this circumstance both browsers fire off a request to http://google.com/lat/json. &amp;nbsp;If your computer has a WiFi device turned on at the time, both browsers send along the name, hardware ID, and signal strength of every WiFi base point that your little lappy can see. &amp;nbsp;When I was sitting at work, the data sent looked like this:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;{
    "version": "1.1.0",
    "request_address": true,
    "wifi_towers": [{
        "mac_address": "xx-xx-xx-xx-xx-01",
        "ssid": "XXXXXXXXXXXX",
        "signal_strength": -81
    }, {
        "mac_address": "xx-xx-xx-xx-xx-00",
        "ssid": "XXXXXXXX",
        "signal_strength": -83
    }, {
        "mac_address": "xx-xx-xx-xx-xx-02",
        "ssid": "XXXXXXXXXXX",
        "signal_strength": -83
    }, {
        "mac_address": "xx-xx-xx-xx-xx-30",
        "ssid": "XXXXXXXX",
        "signal_strength": -62
    }, {
        "mac_address": "xx-xx-xx-xx-xx-62",
        "ssid": "XXXXXXXXXXX",
        "signal_strength": -82
    }, {
        "mac_address": "xx-xx-xx-xx-xx-a0",
        "ssid": "XXXXXXXX",
        "signal_strength": -75
    }, {
        "mac_address": "xx-xx-xx-xx-xx-a1",
        "ssid": "XXXXXXXXXXXX",
        "signal_strength": -74
    }, {
        "mac_address": "xx-xx-xx-xx-xx-61",
        "ssid": "XXXXXXXXXXXX",
        "signal_strength": -81
    }, {
        "mac_address": "xx-xx-xx-xx-xx-a2",
        "ssid": "XXXXXXXXXXX",
        "signal_strength": -75
    }, {
        "mac_address": "xx-xx-xx-xx-xx-32",
        "ssid": "XXXXXXXXXXX",
        "signal_strength": -57
    }, {
        "mac_address": "xx-xx-xx-xx-xx-31",
        "ssid": "XXXXXXXXXXXX",
        "signal_strength": -65
    }, {
        "mac_address": "xx-xx-xx-xx-xx-58",
        "ssid": "XXXXXXXX",
        "signal_strength": -76
    }, {
        "mac_address": "xx-xx-xx-xx-xx-60",
        "ssid": "XXXXXXXX",
        "signal_strength": -75
    }]
}
&lt;/pre&gt;
Google then ships back coordinates for where they think you are based on that WiFi data.  The response also includes city, state, street address, and an estimate of accuracy.
&lt;br/&gt;&lt;br/&gt;
When I was at work, their guess of accuracy was spooky good.  Not only did the Big G put me in the right building, but they also correctly discerned that I was on the south side of that (not terribly large) building.
&lt;br/&gt;&lt;br/&gt;
I also gave it a go from home.  There the accuracy was a little less impressive, but still pretty good.  Google's guess was off by about 250 meters, but that's probably because I live in a relatively newly built up part of a subdivision.  Google put me on the side of the neighborhood that's been around for a few more years.
&lt;br/&gt;&lt;br/&gt;
If your WiFi adapter is turned off, you're not in range of any networks, or your PC doesn't have WiFi, then the request to google.com/lat/json sends an empty set for the WiFi data and Google appears to just use your IP address to determine where you are, returning a city-accurate location.  The returned accuracy was reported as 22 km when I tried it.
&lt;br/&gt;&lt;br/&gt;
Internet Explorer 9 uses a similar trick; when asked for geolocation, it sends a request to https://inference.location.live.net/inferenceservice/v21/Pox/GetLocationUsingFingerprint containing WiFi data.  IE's request doesn't include network name, interestingly.  Microsoft's API is much uglier, relying on XML written in that pedantic way that gives XML a bad name, filled with disgustingly repetitive xmlns junk.  In my very small sample size, Microsoft's data was much lower quality.  From home, my location was misjudged by about 5 km with a reported uncertainty of 16 km.  At work, Microsoft just gave up and said it didn't know where I was.  I wonder if MS just fell back on geo-IP locating for the location it provided when I was at home because when I removed all of the WiFi data from the request and resubmitted it, the returned location was identical.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8499998-6529044453575310387?l=leifw.wickland.net' alt='' /&gt;&lt;/div&gt;</description><link>http://leifw.wickland.net/2011/04/how-html5-geolocation-works-in-firefox.html</link><author>noreply@blogger.com (Leif Wickland)</author><thr:total>2</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-8499998.post-4965754946927705881</guid><pubDate>Wed, 06 Apr 2011 03:36:00 +0000</pubDate><atom:updated>2011-06-30T14:49:50.012-06:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>mongoDB</category><category domain='http://www.blogger.com/atom/ns#'>mapReduce</category><title>11 Buggy Disappointments in MongoDB</title><description>I've been exploring MongoDB primarily for its map-reduce functionality lately.  I've found a few shortcoming that I'm not crazy about.
&lt;br /&gt;
&lt;div&gt;
&lt;ol&gt;
&lt;li&gt;If you &lt;a href="http://www.mongodb.org/display/DOCS/Import+Export+Tools#ImportExportTools-mongodump"&gt;dump&lt;/a&gt; (i.e. export to BSON format) a document containing an array with undefined elements, then when you import that data, the undefined elements are lost, changing the indexes of the values.  For example, exporting a document that contained a member that was created like
&lt;br /&gt;&lt;span style="font-family: monospace;"&gt;var a = [];&lt;br /&gt;a[0] = "a";&lt;br /&gt;a[2] = "c";&lt;/span&gt;
&lt;br /&gt;when imported will result in an array like ["a", "c"], with "c" moved from spot 2 to 1.&lt;/li&gt;
&lt;li&gt;If you &lt;a href="http://www.mongodb.org/display/DOCS/Import+Export+Tools#ImportExportTools-mongoexport"&gt;export&lt;/a&gt; data from a sharded collection, only data from one of the shards is actually output.&lt;/li&gt;
&lt;li&gt;I've had strange, inconsistent problems where mapReduce would fail with no reasonable explanation after &lt;a href="http://www.mongodb.org/display/DOCS/Import+Export+Tools#ImportExportTools-mongoimport"&gt;importing&lt;/a&gt; a large amount (~10GB) of data into a sharded collection. &amp;nbsp;Bouncing the cluster's mongods has fixed the problems.&lt;/li&gt;
&lt;li&gt;Mongo's &lt;a href="http://www.mongodb.org/display/DOCS/Server-side+Code+Execution#Server-sideCodeExecution-Using%7B%7Bdb.eval%28%29%7D%7D"&gt;db.eval()&lt;/a&gt; is much more dangerous than the documentation lets on.  If you do something moderately dumb in there that uses a lot of memory, you can cause the server to run out of memory, which causes it to segfault and leaves the data store in a state that requires recovery.&lt;/li&gt;
&lt;li&gt;The JavaScript map and reduce function passed to &lt;a href="http://www.mongodb.org/display/DOCS/MapReduce#MapReduce-Overview"&gt;mapReduce&lt;/a&gt; don't pull in variables or functions from their scope as one would normally expect of JavaScript.  The mongo solution is the scope argument passed to mapReduce.  Unfortunately, scope can't be used to pass functions.  As far as I can tell, the Mongo approach is to add other function into the &lt;a href="http://www.mongodb.org/display/DOCS/Server-side+Code+Execution#Server-sideCodeExecution-Storingfunctionsserverside"&gt;db.system.js collection&lt;/a&gt;, which is a pretty poor solution because it hinders code maintenance.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;For reasons I can't explain, I've had mapReduce jobs fail a couple of time after running for hours and going through both the map and reduce phases entirely then reporting that a function defined in db.system.js was undefined.  If it was undefined, it should've been reported as undefined before it was called 50 million times. &amp;nbsp;The same mapReduce jobs ran successfully on smaller samples of data in&amp;nbsp;unsharded collections.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.mongodb.org/display/DOCS/MapReduce#MapReduce-Parallelism"&gt;Mongo's mapReduce is single threaded&lt;/a&gt;.  &lt;i&gt;shudder&lt;/i&gt;  No, really.  No matter how many mapReduce jobs you throw at it at once, the CP utilization will hover in the 100% range.  If you want Mongo to use more than one core for mapReduce, you need multiple shards on the same box, but in practice that's a rather ineffective approach; Mongo doesn't always shard when I want it to shard, even if I set the chunk size stupidly low.  &lt;/li&gt;
&lt;li&gt;If you do shard to try to get multiple cores running mapReduce, you may find that the primary eats all the memory, starving the secondary shard servers.&lt;/li&gt;
&lt;li&gt;The VM I was playing with Mongo in only had a 100 GB partition.  I ran quite a few different mapreduce jobs which output into different tables, eating up lots of disk space.  One of the mapreduce jobs hung.  I realized that the partition had less than 2 GB of free space left, so Mongo couldn't allocate another slab.  No message was returned to the client explaining this, unfortunately.&lt;/li&gt;
&lt;li&gt;I went around removing all the documents from collections and then dropping them, trying to free disk space.  For whatever reason, Mongo didn't actually free any disk space after I did that.  I tried bouncing the cluster to see if that would allow the servers to reclaim the freed space to no avail.  Although frustrating, that makes sense given that the &lt;a href="http://www.mongodb.org/display/DOCS/Excessive+Disk+Space#ExcessiveDiskSpace-DeletedSpace"&gt;Mongo docs say&lt;/a&gt;, "This [deleted] space is reused but never freed to the operating system."&lt;/li&gt;
&lt;li&gt;The mongo docs say if you want it to return the freed space to the operating system, you should &lt;a href="http://www.mongodb.org/display/DOCS/Excessive+Disk+Space"&gt;repair the DB&lt;/a&gt;.  So I tried &lt;pre&gt;db.repairDatabase()&lt;/pre&gt; Unfortunately, if your disk is full-ish, Mongo won't have space to repair.  When I tried, I got the following error.&lt;br&gt;
&lt;pre&gt;Cannot repair database &lt;i&gt;X&lt;/i&gt; having size: 21415067648 (bytes) because free disk space is: 887955456 (bytes)&lt;/pre&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;div&gt;
There's still plenty to like in Mongo, but at this point, I feel like Mongo's mapReduce functionality is better suited to running queries which are too big to fit in memory, rather than serious data crunching.  Perhaps my difficulties have been due to getting sharding involved with mapReduce. &amp;nbsp;It's also possible I've made a crucial mistake in configuring sharding, but I think I followed the &lt;a href="http://www.mongodb.org/display/DOCS/Configuring+Sharding"&gt;directions&lt;/a&gt; pretty closely.&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/8499998-4965754946927705881?l=leifw.wickland.net' alt='' /&gt;&lt;/div&gt;</description><link>http://leifw.wickland.net/2011/04/weird-buggy-and-disappointing-behavior.html</link><author>noreply@blogger.com (Leif Wickland)</author><thr:total>9</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-8499998.post-2754135321886596452</guid><pubDate>Tue, 05 Apr 2011 20:09:00 +0000</pubDate><atom:updated>2011-04-05T15:20:43.202-06:00</atom:updated><title>Comments in PHP source code for calling a user defined function</title><description>&lt;div&gt; A co-worker asked me if it was possible to get PHP 5.3 to search other namespaces when it failed to find a function in the global namespace, so we went off to the PHP source code to the place that the virtual machine calls user defined functions.  We found the following comments:&lt;/div&gt; &lt;ul&gt; &lt;li&gt; &lt;span style='font-family:monospace;'&gt; /* Never reached */&lt;/span&gt; &lt;/li&gt; &lt;li&gt; &lt;span style='font-family:monospace;'&gt; /* FIXME: output identifiers properly */&lt;/span&gt;&lt;/li&gt; &lt;li&gt; &lt;span style='font-family:monospace;'&gt; /* Not sure what should be done here if it's a static method */&lt;/span&gt; &lt;/li&gt; &lt;/ul&gt; &lt;div&gt; In turn my colleague quipped, PHP 5.3?  More like PHP 0.5. &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8499998-2754135321886596452?l=leifw.wickland.net' alt='' /&gt;&lt;/div&gt;</description><link>http://leifw.wickland.net/2011/04/comments-in-php-source-code-for-calling.html</link><author>noreply@blogger.com (Leif Wickland)</author><thr:total>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-8499998.post-2869888607771648534</guid><pubDate>Mon, 04 Apr 2011 23:04:00 +0000</pubDate><atom:updated>2011-04-04T17:05:34.525-06:00</atom:updated><title>Proud Moment</title><description>The help system on my wife's smartphone uses the product I worked on for a few years.  I never would've known it if somebody hadn't pointed it out to me.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8499998-2869888607771648534?l=leifw.wickland.net' alt='' /&gt;&lt;/div&gt;</description><link>http://leifw.wickland.net/2011/04/proud-moment.html</link><author>noreply@blogger.com (Leif Wickland)</author><thr:total>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-8499998.post-7182097785459922411</guid><pubDate>Wed, 23 Mar 2011 22:53:00 +0000</pubDate><atom:updated>2011-03-24T15:06:07.681-06:00</atom:updated><title>How Google Analytics Works</title><description>Google is &lt;a href="http://www.google.com/support/conversionuniversity/bin/request.py?hl=en&amp;contact_type=indexSplash&amp;rd=1"&gt;forthcoming with details of how analytics works&lt;/a&gt;, but they don't present it in a nerd friendly way.  The data is wrapped up inside of videos instead of dumped as text.  I may have been able learn this by watching the videos, but it was more fun figure it out by playing with it.
&lt;h3&gt;Summary of Google Analytics' Design&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;All user data is stored in cookies on the visited site.&lt;/li&gt;
&lt;li&gt;No cookies are set on any Google Analytics Domain.&lt;/li&gt;
&lt;li&gt;Each user has a unique ID on each domain they visit.&lt;/li&gt;
&lt;li&gt;User data is transmitted back to Google Analytics in the query string when requesting a 1x1 GIF.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;UML Sequence Diagram of Google Analytics' Design&lt;/h3&gt;
&lt;img src="http://1.bp.blogspot.com/-QPrnPYVzaxc/TYp8eae_qdI/AAAAAAAAGRY/bjxXIuWnGwE/s1600/cdraw.png" /&gt;
&lt;h3&gt;Analyzing the pieces of Google Analytics Data&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Definitions of each of the &lt;a href="http://www.godspeed23.com/analytics/2010/02/google-analytics-cookies/"&gt;&lt;i&gt;utm*&lt;/i&gt; cookies&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Descriptions of the pieces of data in &lt;a href="http://www.analyticsmarket.com/blog/__utmgif-data"&gt;query string for utm.gif&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8499998-7182097785459922411?l=leifw.wickland.net' alt='' /&gt;&lt;/div&gt;</description><link>http://leifw.wickland.net/2011/03/how-google-analytics-works.html</link><author>noreply@blogger.com (Leif Wickland)</author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-QPrnPYVzaxc/TYp8eae_qdI/AAAAAAAAGRY/bjxXIuWnGwE/s72-c/cdraw.png' height='72' width='72'/><thr:total>2</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-8499998.post-6897915986269479470</guid><pubDate>Mon, 21 Mar 2011 21:01:00 +0000</pubDate><atom:updated>2011-03-21T15:02:39.467-06:00</atom:updated><title>Weekend Hacking Failure: .NET parser for YAML in ANTLR</title><description>Useless information: I tried to write a decent .NET parser for YAML over the weekend.  I failed, but learned a few things

&lt;ol&gt;
&lt;li&gt;I didn't have a good handle on what YAML was.  For example, I didn't realize that whitespace was significant.&lt;/li&gt;
&lt;li&gt;YAML is a full superset of JSON.&lt;/li&gt;
&lt;li&gt;YAML defines all kinds of stuff to support strongly typed serialization that I didn't want and didn't need.&lt;/li&gt;
&lt;li&gt;The grammar presented in the YAML standard isn't particularly well suited for copying because it ends up with all sorts of useless rules that the lexer or parser doesn't like and you have to manually eliminate.&lt;/li&gt;
&lt;li&gt;One of the main YAML guys apparently tried to built a parser for YAML on top of ANTLR (which is what I was trying to use) a few years back.  It looks like he gave up fairly early on.&lt;/li&gt;
&lt;li&gt;I probably should've started by copying SnakeYaml, which is a pretty good Java implementation.&lt;/li&gt;
&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8499998-6897915986269479470?l=leifw.wickland.net' alt='' /&gt;&lt;/div&gt;</description><link>http://leifw.wickland.net/2011/03/weekend-hacking-failure-net-parser-for.html</link><author>noreply@blogger.com (Leif Wickland)</author><thr:total>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-8499998.post-5789924250327480005</guid><pubDate>Tue, 08 Mar 2011 21:33:00 +0000</pubDate><atom:updated>2011-03-08T15:55:39.954-07:00</atom:updated><title>What I learned about git today: reverting, ignoring, diffing, and vimming</title><description>I learned a few things about git today:
&lt;ol&gt;
&lt;li&gt;I wanted to see what I'd added to the index, but not committed.  There may well be a better way to do it, but here are the two commands I &lt;a href="http://stackoverflow.com/questions/2657935/checking-for-a-dirty-index-or-untracked-files-with-git/2659808#2659808"&gt;discovered&lt;/a&gt; and aliased:&lt;br&gt;
&lt;pre&gt;
    di = diff-index --color=auto --cached --patch --relative HEAD    # shows the actual differences
    dfi = diff-index --color=auto --cached --name-only --relative HEAD   # shows just the files which are changed
&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;I wanted to remove changes from index.  The Git Book has an excellent &lt;a href="http://book.git-scm.com/4_undoing_in_git_-_reset,_checkout_and_revert.html"&gt;page&lt;/a&gt; on all manner of undoing.  Specifically, I needed the "git reset" command to revert staged but uncommitted changes.
&lt;/li&gt;
&lt;li&gt;
Git kept telling listing files whose mode had been changes in the list of diffs.  While those are technically diffs, I didn't care.  I found the &lt;a href="http://stackoverflow.com/questions/1580596/how-do-i-make-git-ignore-mode-changes-chmod"&gt;solution&lt;/a&gt; on Stack Overflow.  "git config core.filemode false" changes the config with a repo to ignore file mode changes.
&lt;/li&gt;
&lt;li&gt;
I've long enjoyed seeing side-by-side diffs of pending CVS changes in vim.  I've been using the &lt;a href="http://www.vim.org/scripts/script.php?script_id=58"&gt;CVSMenu&lt;/a&gt; plugin for as long as I can remember.  Of course, it doesn't work with git, but there's an even cooler plugin for vim these days, &lt;a href="http://www.vim.org/scripts/script.php?script_id=90&amp;rating=life_changing"&gt;VCS Command&lt;/a&gt;, which gives you similar functionality for many version control systems, including git.  
&lt;/li&gt;
&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8499998-5789924250327480005?l=leifw.wickland.net' alt='' /&gt;&lt;/div&gt;</description><link>http://leifw.wickland.net/2011/03/what-i-learned-about-git-today.html</link><author>noreply@blogger.com (Leif Wickland)</author><thr:total>1</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-8499998.post-3566594846482971156</guid><pubDate>Thu, 03 Feb 2011 23:46:00 +0000</pubDate><atom:updated>2011-02-03T16:58:53.172-07:00</atom:updated><title>Creating a bare git repo and avoiding the no master branch problem</title><description>I was creating a bare git repo today that would serve as the pristine copy that all others would clone from.
&lt;p&gt;
I was doing something like:
&lt;ol&gt;
&lt;li&gt;umask 0000 # Because I wanted the pristine copy to be world writable&lt;/li&gt;
&lt;li&gt;git init --bare --shared=all ~/reponame.git&lt;/li&gt;
&lt;li&gt;cd somewhere&lt;/li&gt;
&lt;li&gt;git clone ~/reponame&lt;/li&gt;
&lt;li&gt;cd reponame&lt;/li&gt;
&lt;li&gt;touch foo&lt;/li&gt;
&lt;li&gt;git add foo&lt;/li&gt;
&lt;li&gt;git commit -m test foo&lt;/li&gt;
&lt;li&gt;git push&lt;/li&gt;
&lt;/ol&gt;
Unfortunately, my push attempt was rebuffed with the following error message:
&lt;pre&gt;
No refs in common and none specified; doing nothing.&lt;br&gt;
Perhaps you should specify a branch such as 'master'.&lt;br&gt;
fatal: The remote end hung up unexpectedly&lt;br&gt;
error: failed to push some refs to '/path/to/reponame.git&lt;br&gt;
&lt;/pre&gt;
What I had to do was at that last step was 
&lt;ol start="9"&gt;
&lt;li&gt;git push origin master&lt;/li&gt;
&lt;/ol&gt;
That created the master branch in the pristine repo.  Subsequent clones didn't have to go to that trouble.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8499998-3566594846482971156?l=leifw.wickland.net' alt='' /&gt;&lt;/div&gt;</description><link>http://leifw.wickland.net/2011/02/creating-bare-git-repo-and-avoiding-no.html</link><author>noreply@blogger.com (Leif Wickland)</author><thr:total>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-8499998.post-2537250531939301336</guid><pubDate>Fri, 14 Jan 2011 23:14:00 +0000</pubDate><atom:updated>2011-01-14T16:24:42.776-07:00</atom:updated><title>PHP Opcode Caching for CGI</title><description>I recently completed my master's degree in Computer Science at &lt;a href="http://montana.edu/"&gt;Montana State University&lt;/a&gt;.  As a keystone project for the degree, I wrote about the project I did at work to cache PHP PHP opcodes in a CGI environment.  If you're interested, you can read my long academic writeup, which is verbosely titled &lt;a href="http://www.cs.montana.edu/files/techreports/1011/Wickland.pdf"&gt;PHP ACCELERATION IN THE CLOUD: Caching PHP Virtual Machine Opcodes for Reuse in a Secure, Multi-User, Enterprise Programming Environment&lt;/a&gt; or for a slightly more accessible take on things, you can view my &lt;a href="https://docs.google.com/present/view?id=dc9spn43_164nfq77vgb"&gt;presentation on PHP opcode caching&lt;/a&gt;.
&lt;iframe src="https://docs.google.com/present/embed?id=dc9spn43_164nfq77vgb&amp;interval=5&amp;size=m" frameborder="0" width="555" height="451"&gt;&lt;/iframe&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8499998-2537250531939301336?l=leifw.wickland.net' alt='' /&gt;&lt;/div&gt;</description><link>http://leifw.wickland.net/2011/01/php-opcode-caching-for-cgi.html</link><author>noreply@blogger.com (Leif Wickland)</author><thr:total>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-8499998.post-2672133636516553743</guid><pubDate>Thu, 24 Jun 2010 23:15:00 +0000</pubDate><atom:updated>2010-06-24T17:41:43.146-06:00</atom:updated><title>What jobless recovery?</title><description>I'm headed home from &lt;a href="http://en.oreilly.com/velocity2010"&gt;the Velocity 2010 Conference&lt;/a&gt;, which was great again.  This was the jobs board at the conference:&lt;p&gt;
&lt;a href="http://picasaweb.google.com/lh/photo/zQV4xXxc14VoFxF5c6tlRA?feat=embedwebsite"&gt;&lt;img src="http://lh4.ggpht.com/_mnjY4i4rmCg/TCPmz5oxinI/AAAAAAAAGK0/J_YAL8SvJDU/s800/2010-06-24%2010.17.00.jpg" /&gt;&lt;/a&gt;&lt;p&gt;
It was overflowing.  More than one posting had been knocked off the board onto the floor.  &lt;p&gt;
In addition roughly 10 companies paid to have career booths at the conference.  At least in web tech, it appears companies are seriously hiring.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8499998-2672133636516553743?l=leifw.wickland.net' alt='' /&gt;&lt;/div&gt;</description><link>http://leifw.wickland.net/2010/06/what-jobless-recovery.html</link><author>noreply@blogger.com (Leif Wickland)</author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh4.ggpht.com/_mnjY4i4rmCg/TCPmz5oxinI/AAAAAAAAGK0/J_YAL8SvJDU/s72-c/2010-06-24%2010.17.00.jpg' height='72' width='72'/><thr:total>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-8499998.post-7575770229970669406</guid><pubDate>Wed, 05 May 2010 15:49:00 +0000</pubDate><atom:updated>2010-05-05T09:53:43.398-06:00</atom:updated><title>Equality is Supposed to be Transitive</title><description>Equality is one of those operators that you expect to be transitive.  In general, we expect that 
&lt;blockquote&gt;
&lt;i&gt;if&lt;/i&gt;&lt;br&gt;
a=b&lt;br&gt;
&lt;i&gt;and&lt;/i&gt;&lt;br&gt;
b=c&lt;br&gt;
&lt;i&gt;then&lt;/i&gt;&lt;br&gt;
a=c&lt;br&gt;
&lt;/blockquote&gt;
Sadly that's not always the case in PHP.
&lt;blockquote&gt;
(1 == true) =&gt; true&lt;br&gt;
(true == "true") =&gt; true&lt;br&gt;
(1 == "true") =&gt; false&lt;br&gt;
&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8499998-7575770229970669406?l=leifw.wickland.net' alt='' /&gt;&lt;/div&gt;</description><link>http://leifw.wickland.net/2010/05/equality-is-supposed-to-be-transitive.html</link><author>noreply@blogger.com (Leif Wickland)</author><thr:total>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-8499998.post-3604194254560371486</guid><pubDate>Sun, 28 Mar 2010 02:50:00 +0000</pubDate><atom:updated>2010-03-27T22:03:17.926-06:00</atom:updated><title>Quote o' the Day</title><description>&lt;blockquote&gt;
I’m convinced that we’re living in a global meta-culture badly damaged by future shock.
&lt;p&gt;
The Tea Partiers are a symptom of this. So are the Young-Earth Creationists and the Biblical literalists.
&lt;p&gt;
Complexity hurts, and many people can’t handle it, so they retreat into comfortingly comprehensible certainties.
&lt;/blockquote&gt;
&lt;p&gt;
--&lt;a href="http://firedoglake.com/2010/03/21/fdl-book-salon-welcomes-charlie-stross-the-trade-of-queens-book-six-of-the-merchant-princes/#comment-2106863"&gt;Charles Stross in a book salon&lt;/a&gt; about his recent &lt;a href="http://www.amazon.com/Trade-Queens-Book-Merchant-Princes/dp/0765316730"&gt;&lt;i&gt;Trade of Queens&lt;/i&gt;&lt;/a&gt;
&lt;p&gt;
I grew up with Biblical literalist and Young-Earth Creationist views.  I have strong sympathies with aspects of the Tea Partiers complaints.  However, I have to agree with Stross that comprehensible certainties often appear to be refuges from peevish perplexities.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8499998-3604194254560371486?l=leifw.wickland.net' alt='' /&gt;&lt;/div&gt;</description><link>http://leifw.wickland.net/2010/03/quote-o-day.html</link><author>noreply@blogger.com (Leif Wickland)</author><thr:total>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-8499998.post-2172083100598799582</guid><pubDate>Mon, 08 Mar 2010 21:10:00 +0000</pubDate><atom:updated>2010-03-08T14:10:00.238-07:00</atom:updated><title>PHP Internals Presentation</title><description>I'll be presenting this to MSU's Compilers class today.
&lt;iframe src="http://docs.google.com/present/embed?id=dc9spn43_102f6hcspg4&amp;interval=10&amp;size=l" frameborder="0" width="700" height="559"&gt;&lt;/iframe&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8499998-2172083100598799582?l=leifw.wickland.net' alt='' /&gt;&lt;/div&gt;</description><link>http://leifw.wickland.net/2010/03/php-internals-presentation.html</link><author>noreply@blogger.com (Leif Wickland)</author><thr:total>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-8499998.post-4352910814396339369</guid><pubDate>Mon, 14 Dec 2009 05:15:00 +0000</pubDate><atom:updated>2009-12-13T22:26:57.092-07:00</atom:updated><title>NPR Sunday Puzzle Plus</title><description>The &lt;a href="http://www.npr.org/templates/story/story.php?storyId=121382258"&gt;NPR Sunday Puzzle&lt;/a&gt; this week was a fun one to solve.  

&lt;blockquote&gt;
Name five two-digit numbers that are evenly spaced out — like 32, 34, 36, 38 and 40 — in which all 10 digits from 0 to 9 are used once each. What numbers are these?
&lt;/blockquote&gt;

I overheard it while trying to get back to sleep.  Drifting in and out of consciousness I figured it out in about 10 minutes.  For fun (seriously), I coded a solution to the problem.  It turns out there are 4 correct answers, all of which begin or end with a multiple of 10.
&lt;br&gt;&lt;br&gt;
Then I figured out the same thing for 5 four digit numbers in which the digits from 0 to 9 appear twice.  I found 618 solutions.  My favorites used 1111 as the increment,  three of which contained the solution to the first puzzle.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8499998-4352910814396339369?l=leifw.wickland.net' alt='' /&gt;&lt;/div&gt;</description><link>http://leifw.wickland.net/2009/12/npr-sunday-puzzle-plus.html</link><author>noreply@blogger.com (Leif Wickland)</author><thr:total>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-8499998.post-3724974835244195253</guid><pubDate>Sun, 06 Dec 2009 17:22:00 +0000</pubDate><atom:updated>2009-12-06T13:24:20.237-07:00</atom:updated><title>Chrome extensions for more compact, netbook friendly Gmail and Google Reader</title><description>Earlier I posted &lt;a href="http://leifw.wickland.net/2009/11/user-scripts-for-more-compact-netbook.html"&gt;user scripts for making Gmail and Google reader a more compact&lt;/a&gt;.  It appears that Google Chrome no longer likes user scripts, so I repackaged them as Chrome Extensions.  As before, let me clearly state that these are built on the hard work of others; I just tweaked them a bit to my taste.&lt;p&gt;&lt;a href="http://wickland.net/lwgrcm.crx"&gt;Leif Wickland Google Reader Clean and Mean&lt;/a&gt;&lt;p&gt;&lt;a href="http://wickland.net/lwgmar.crx"&gt;Leif Wickland Google Reader Ad Remover&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8499998-3724974835244195253?l=leifw.wickland.net' alt='' /&gt;&lt;/div&gt;</description><link>http://leifw.wickland.net/2009/12/chrome-extensions-for-more-compact.html</link><author>noreply@blogger.com (Leif Wickland)</author><thr:total>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-8499998.post-5996044167001134694</guid><pubDate>Sun, 29 Nov 2009 19:28:00 +0000</pubDate><atom:updated>2009-11-29T12:38:00.535-07:00</atom:updated><title>Quote o' the Day</title><description>&lt;blockquote&gt;
Google Wave was a program built to show younger people how older people feel when they attempt to use the internet.
&lt;/BLOCKQUOTE&gt;
-- &lt;a href="http://twitter.com/jeff_phillips/statuses/6038154206"&gt;jeff_phillips&lt;/a&gt;  (Although he &lt;a href="http://www.reddit.com/r/AskReddit/comments/a7rrh/seriously_what_do_i_do_with_google_wave_now_that/c0g8ttv"&gt;may not&lt;/a&gt; have been the originator.)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8499998-5996044167001134694?l=leifw.wickland.net' alt='' /&gt;&lt;/div&gt;</description><link>http://leifw.wickland.net/2009/11/quote-o-day.html</link><author>noreply@blogger.com (Leif Wickland)</author><thr:total>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-8499998.post-1837469723673054941</guid><pubDate>Wed, 18 Nov 2009 05:40:00 +0000</pubDate><atom:updated>2009-11-17T22:40:00.325-07:00</atom:updated><title>User Scripts for more compact, netbook friendly Gmail and Google Reader</title><description>My wife has a netbook that I occasionally swipe to browse the web, which usually consists of at least peeking at Gmail and Google Reader.  On the netbook's tiny screen, both feel like they could afford to have some of their cruft removed.  I went searching and found scripts that I could hack up into what I wanted.
&lt;br&gt;&lt;br&gt;
&lt;h3&gt;Gmail&lt;/h3&gt;
This just removes the right column when you view a conversation.  That means that you lose ads and Gmail's smart parsing of your email to offer to help you track packages and schedule events.
&lt;pre&gt;
 // borrowed from http://userscripts.org/scripts/show/43495&lt;br&gt;
 var css = "table[class='Bs nH iY'] tr td[class='Bu']:last-child {display:none !important;}";&lt;br&gt;
&lt;br&gt;
 if (typeof GM_addStyle != "undefined") {&lt;br&gt;
  GM_addStyle(css);&lt;br&gt;
 } else if (typeof addStyle != "undefined") {&lt;br&gt;
  addStyle(css);&lt;br&gt;
 } else {&lt;br&gt;
  var heads = document.getElementsByTagName("head");&lt;br&gt;
  if (heads.length &gt; 0) {&lt;br&gt;
   var node = document.createElement("style");&lt;br&gt;
   node.type = "text/css";&lt;br&gt;
   node.appendChild(document.createTextNode(css));&lt;br&gt;
   heads[0].appendChild(node); &lt;br&gt;
  }&lt;br&gt;
 }&lt;br&gt;
&lt;/pre&gt;
&lt;br&gt;&lt;br&gt;
&lt;h3&gt;Google Reader&lt;/h3&gt;
This is a bigger change.  It smashes together many elements at the top of the page above the item list, violating a host of aesthetic principals, making graphic designers everywhere weep.  It also reduces the whitespace inside the display of individual items.  Finally it removes the bar at the bottom of the item list.  I believe that my changes from the original were primarily around restoring a few things the original hid and fiddling with the styling.
&lt;pre&gt;
// From: Google Reader Compact &amp; Clean&lt;br&gt;
(function() {&lt;br&gt;
var css = "/* Hide all the elements that take up space */ #logo-container, #gbar, #global-info, .gbh, #lhn-add-subscription-section, #viewer-footer, #chrome-view-links, #viewer-refresh, #viewer-details-toggle, #chrome-header, #chrome-lhn-toggle, .scroll-tree .icon, .entry .entry-title .entry-title-go-to, #entries.list .collapsed .entry-main .entry-original { display: none !important; } /* move the main window up to the top to fill in leftover space */ #main, #settings-frame, #settings { top:0 !important; margin: 0 !important; } /* tighten up the vertical padding on header bars */ #viewer-top-controls, #chrome-header { padding: 2px 0 2px 5px !important; } /* right-justify the \"Loading...\" and other messages so they don't obscure other elements */ #loading-area, #message-area-outer { width: auto !important; left: auto !important; right: 0 !important; top: 26px !important; } /* right-align search bar and hide buttons until hovering */ #search { left: auto !important; right: 10px !important; top: 1px !important; width: 210px !important; height:23px !important; overflow: hidden !important; } #search:hover { width: 403px !important; height:323px !important; overflow: visible !important; } #search-restrict-button .goog-menu { left: auto !important; right: 0 !important; } #chrome.search-stream #viewer-search-parent { text-align: left !important; } /* shrink the navigation sidebar */ #nav, #nav * { max-width: 200px !important; } #chrome { margin-left: 200px !important; } .lhn-hidden #chrome { margin-left: 1px !important; } #entries .entry-body { max-width: none !important; } /* remove icons from navbar and tighten the left margin for folder/subscription entries */ .scroll-tree .expanded .toggle { background-position: 3px -58px !important; } .scroll-tree .collapsed .toggle { background-position: -20px -58px !important; } #lhn-subscriptions .scroll-tree li a { padding-left: 0 !important; } #lhn-subscriptions #sub-tree ul ul li a { padding-left: 10px !important; } #lhn-subscriptions .scroll-tree .toggle { width: 16px !important; } /* shrink titles, but add underlining for visual identification */ .entry /*.entry-title { font-size:100% !important; background-color: #FFFFFF !important;}*/ /*REMOVING UNDERLINE*/ /* tighten up spacing around entries */ /* expanded view */ #entries .entry { padding: 5px !important; margin: 0 !important; background-color: #FFFFFF !important; } #entries .card-content { padding: 2px !important; } #entries .card-common { padding: 0 !important; margin: 0 !important; border-width: 2px !important; } #entries .collapsed { padding: 0px !important; border: 0 !important; } /* list view */ #entries .collapsed .entry-date { margin: 0 2px 0 0 !important; } /*CHANGING BACKGROUND COLOR*/ #entries #current-entry .collapsed { background-color: #FCFCFC !important; } #entries.list .collapsed .entry-icons, #entries.list .collapsed .entry-main .entry-original { top: 1px !important; } #entries.list .collapsed .entry-secondary { top: 0px !important; margin-right: 7em !important; background-color: #FFFFFF !important;} #entries.list .collapsed { text-decoration: none !important; background-color: #FFFFFF !important;} #entries.list .collapsed .entry-source-title { top: 0px !important; background-color: #FFFFFF !important;} #entries.list .collapsed .entry-title { text-decoration: none !important; background-color: #FFFFFF !important;} /* make entries borders square for consistency with new design */ .entry .card, .card .card-bottom { -moz-border-radius: 0 !important; } /* Hide Like feature */ /*#entries .entry-author { display: none !important; }*/";&lt;br&gt;
if (typeof GM_addStyle != "undefined") {&lt;br&gt;
 GM_addStyle(css);&lt;br&gt;
} else if (typeof addStyle != "undefined") {&lt;br&gt;
 addStyle(css);&lt;br&gt;
} else {&lt;br&gt;
 var heads = document.getElementsByTagName("head");&lt;br&gt;
 if (heads.length &gt; 0) {&lt;br&gt;
  var node = document.createElement("style");&lt;br&gt;
  node.type = "text/css";&lt;br&gt;
  node.appendChild(document.createTextNode(css));&lt;br&gt;
  heads[0].appendChild(node); &lt;br&gt;
 }&lt;br&gt;
}&lt;br&gt;
})();&lt;br&gt;
&lt;/pre&gt;
&lt;br&gt;&lt;br&gt;I like both of these enough that I ended up using them on systems with decent sized monitors, too.  They're particularly handy for making my favorite Google apps fit getter when I'm trying to put two windows side-by-side on a widescreen monitor.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8499998-1837469723673054941?l=leifw.wickland.net' alt='' /&gt;&lt;/div&gt;</description><link>http://leifw.wickland.net/2009/11/user-scripts-for-more-compact-netbook.html</link><author>noreply@blogger.com (Leif Wickland)</author><thr:total>0</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-8499998.post-9199829335070957142</guid><pubDate>Sun, 15 Nov 2009 05:06:00 +0000</pubDate><atom:updated>2009-11-14T22:39:18.360-07:00</atom:updated><title>Google Wave</title><description>I've had a Google Wave account for a month or two and I've just now found some value in it.  All of the playing around I'd done to explore it really turned me off to the product.  It was too rough and very annoying to use.  Those negatives weren't offset by obvious utility that it offered over my existing channels (IM, email, phone, wiki, and blog).  &lt;br&gt;&lt;br&gt; However, twice at work recently I've found it to be the best tool for a job.  We're talking about a major new feature for our product that we really don't understand.  Wave has given us a nice place to dump ideas, meeting notes, and research as we flail to comprehend what we're getting ourselves into.  As new entries are added, team members will occasionally stop by the wave and comment on what's been added.  Wave's threading is handy for that.  At the same time, Wave allows you to edit entries written by others, thereafter attributing the block to both of you.  &lt;br&gt;&lt;br&gt; I see that as enormously advantageous over email which tends to branch into multiple threads.  Once an email chain has branched or reached adequate length, it's hard and time consuming to reconstruct a coherent view of the conversation.  &lt;br&gt;&lt;br&gt; I think wave is also more useful than a wiki in this context because it essentially merges a wiki page's content and its discussion page.  On Wikipedia that would be annoying, but for the purpose of our collaboration which doesn't need to produce a final document, but rather a documented, researched consensus, it's really nice to be able to get a quick overview or drill into the spiraling discussion on the same document.  &lt;br&gt;&lt;br&gt; I also found Wave to be the best channel when, while I was working from home, a coworker asked how to solve a sticky problem.  I needed to show her the rough code outline of my solution while talking on the phone.  Wave's continuously updating content allowed us to both edit and see what the other meant very quickly.  Short of some sort of fancy screen sharing or collaboration software that neither of us had installed or were signed up for (e.g., &lt;a href="https://bespin.mozilla.com/"&gt;Bespin&lt;/a&gt; or the reviled LiveMeeting) I don't have another channel in my toolbox that would've worked nearly as well.  &lt;br&gt;&lt;br&gt; The greatest shortcoming of Wave is that it lacks undo.  Yes, it has the fancy timeline, but that's mostly useless.  Firstly, loading the timeline takes forever for a moderately large document.  Secondly, when I fat finger something and delete most of my thread, I don't want to go to the timeline; I want to hit Ctrl-Z and see my prodigal content return.  &lt;br&gt;&lt;br&gt; So, yeah, I like Wave, but it's not going to be replacing any tool that I was particularly happy with anytime soon.  It's a specialized tool that I'll pull out occasionally.  &lt;br&gt;&lt;br&gt; I have a few invitations to give out.  Let me know if you'd like one.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8499998-9199829335070957142?l=leifw.wickland.net' alt='' /&gt;&lt;/div&gt;</description><link>http://leifw.wickland.net/2009/11/google-wave.html</link><author>noreply@blogger.com (Leif Wickland)</author><thr:total>1</thr:total></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-8499998.post-3988499534153627387</guid><pubDate>Wed, 11 Nov 2009 17:40:00 +0000</pubDate><atom:updated>2009-11-11T10:48:53.475-07:00</atom:updated><title>Puzzle solving with regular expressions.</title><description>The &lt;a href='http://www.npr.org/templates/story/story.php?storyId=120183101'&gt;puzzle this week&lt;/a&gt; from NPR's &lt;i&gt;Weekend Edition&lt;/i&gt; is&lt;br&gt;
&lt;blockquote&gt;If you write "WOW" in capital letters and hold up a mirror at the side of the word, you'll see "WOW" perfectly reflected in the mirror. Here's the puzzle: Think of a nationality and write it in capital letters. If you remove one stroke from the first letter, and one stroke from the last letter, and hold up a mirror at the side, the name of the nationality will be perfectly reflected in the mirror. What nationality is it?&lt;/blockquote&gt;
&lt;br&gt;&lt;br&gt;
The steps to my solution were:
&lt;ol&gt;
&lt;li&gt;Grab a &lt;a href="http://en.wikipedia.org/wiki/Lists_of_people_by_nationality"&gt;list of nationalities&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Delete all entries which consisted of multiple words.&lt;/li&gt;
&lt;li&gt;Make the remaining words singular and all upper case letters.&lt;/li&gt;
&lt;li&gt;Search for items which matched the regular expression /^.[AHIMOTUVWXYZ]+.$/&lt;/li&gt;
&lt;li&gt;Pick the obvious answer out of the six matches.&lt;/li&gt;
&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8499998-3988499534153627387?l=leifw.wickland.net' alt='' /&gt;&lt;/div&gt;</description><link>http://leifw.wickland.net/2009/11/puzzle-solving-with-regular-expressions.html</link><author>noreply@blogger.com (Leif Wickland)</author><thr:total>1</thr:total></item></channel></rss>
