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

<channel>
	<title>A Noah Arc &#187; Uncategorized</title>
	<atom:link href="http://anoaharc.com/category/uncategorized/feed/" rel="self" type="application/rss+xml" />
	<link>http://anoaharc.com</link>
	<description>The blog of Noah Austen Ready-Campbell</description>
	<lastBuildDate>Wed, 28 Jul 2010 04:57:03 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>From Nuisance to Siege</title>
		<link>http://anoaharc.com/from-nuisance-to-siege/</link>
		<comments>http://anoaharc.com/from-nuisance-to-siege/#comments</comments>
		<pubDate>Wed, 28 Jul 2010 04:57:03 +0000</pubDate>
		<dc:creator>Noah</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://anoaharc.com/?p=344</guid>
		<description><![CDATA[I have often joked that if I won the lottery, the only thing I&#8217;d spend money on was an accountant to handle the paperwork. Though I may be a bit anomalous (in how much I hate wasting money and in how much I hate paperwork), relief from nuisance is incredibly valuable to many people. Just [...]]]></description>
			<content:encoded><![CDATA[<p>I have often joked that if I won the lottery, the only thing I&#8217;d spend money on was an accountant to handle the paperwork. Though I may be a bit anomalous (in how much I hate wasting money <em>and</em> in how much I hate paperwork), relief from nuisance is incredibly valuable to many people. Just look at Apple&#8217;s <a href="http://www.youtube.com/watch?v=FL7yD-0pqZg">Luddite-approved</a> products.<sup class='footnote'><a href='#fn-344-1' id='fnref-344-1'>1</a></sup></p>
<p>However, as much as we might hate nuisances, they seem to love us. There are plane tickets to buy, and broken electronics to return, and utility bills to pay, and none of these is likely to go away any time soon.<sup class='footnote'><a href='#fn-344-2' id='fnref-344-2'>2</a></sup> The only question, then, is how we deal with them.</p>
<h3>Shifting My Perspective</h3>
<p>For me, the key to digging myself out from such piles of BS is changing my perspective. Instead of thinking of a boring task (with indefinite length &#8212; which makes it so much worse) as a nuisance, I&#8217;ve started to think of it as a siege. The task is the enemy, driven into its last stronghold, and whoever gives up first loses. Clearly, that can&#8217;t be me.  I might be outing myself as a middle-school <a href="http://en.wikipedia.org/wiki/Dungeons_%26_Dragons">D&#038;D</a> nerd, but, in the right time and place, this can be practiced to great effect.</p>
<p>An illustrative example is provided by my experience paying taxes this spring. By mid-March or so, I had filled out all my tax information on TaxSlayer. I was just about ready to &#8220;e-file&#8221; my return, when I noticed that the program had failed to take the educational tax credit. This seemed odd to me, as I should have been eligible, but I spent several hours reading through the IRS literature just to make sure. Everything I read only confirmed my belief, but the program was resolute.</p>
<p>Down 15 bucks and more than a little peeved, I brought out the battering ram and gave TurboTax a try instead. Pleasantly surprised<sup class='footnote'><a href='#fn-344-3' id='fnref-344-3'>3</a></sup> by the new interface (thanks <a href="http://venturebeat.com/2010/02/18/mint-intuit-aaron-patzer/">Aaron Patzer</a>?), I proceeded to re-enter all my information. Naturally, TurboTax said I owed even more. Setting my jaw, I called in the trebuchets and decided to just do the whole thing by hand. I typed, printed and mailed my return, and for a moment, it looked like the battle was won.</p>
<p>Then, in June, I got a letter from the IRS saying that I owed them a couple thousand dollars. And that I was being charged interest on the amount, and that a penalty would follow. Piqued, shaken, but resolute, I gave them a call. I explained my position, listed the exact worksheets and publications I was referencing, and held my breath. The arrows whistled over the city walls. After about 20 minutes of hold &#8212; punctuated by a couple of brusque requests for table and page numbers &#8212; the woman I spoke with had to admit defeat. Apparently, I had interpreted the tax code correctly, and it was their error. The gates burst open, and the nuisance was vanquished.</p>
<h3>Taxes and Beyond</h3>
<p>I have attempted to apply this same indefatigable attitude to all parts of my life. Following up with people via email, making sure paperwork is processed in a speedy fashion &#8212; it seems to be useful everywhere. I&#8217;m not doing chores, I&#8217;m sieging a fortress, and I&#8217;ll be damned if I give up. Each step I take in a slow-moving bureaucratic process is a step toward victory. Rather than feeling impatience or dread, I&#8217;m possessed by a strange sort of maniacal glee (well, sometimes anyway). Clearly, this can be taken too far &#8212; it is important to always be polite, and not to be seen as too pushy. And for some things, it&#8217;s just not worth it. The rest of the time, though, I think it&#8217;s good to <a href="http://freakonomics.blogs.nytimes.com/2010/02/11/irs-combat/">enjoy</a> the fight.
<div class='footnotes'>
<div class='footnotedivider'></div>
<ol>
<li id='fn-344-1'>And that is certainly not an argument against them, from a business perspective. After all, most people in this world aren&#8217;t tech geeks. <span class='footnotereverse'><a href='#fnref-344-1'>&#8617;</a></span></li>
<li id='fn-344-2'>Personal assistants can mitigate this for the lucky few, and companies like <a href="http://www.reardencommerce.com/products/">Rearden Commerce</a> and <a href="http://siri.com/">Siri</a> (now part of Apple, interestingly) can also relieve some of the pain. However, a true automated solution is probably <a href="http://en.wikipedia.org/wiki/AI-complete">AI-complete</a>. <span class='footnotereverse'><a href='#fnref-344-2'>&#8617;</a></span></li>
<li id='fn-344-3'>I had avoided Intuit ever since I first paid taxes in high school, after coming away with a taste in my mouth, that, as my dad says, made Microsoft look good. <span class='footnotereverse'><a href='#fnref-344-3'>&#8617;</a></span></li>
</ol>
</div>
]]></content:encoded>
			<wfw:commentRss>http://anoaharc.com/from-nuisance-to-siege/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Unofficial Philly D Android App</title>
		<link>http://anoaharc.com/the-unofficial-philly-d-android-app/</link>
		<comments>http://anoaharc.com/the-unofficial-philly-d-android-app/#comments</comments>
		<pubDate>Sat, 17 Jul 2010 03:36:57 +0000</pubDate>
		<dc:creator>Noah</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://anoaharc.com/?p=315</guid>
		<description><![CDATA[Well, I just finished up my first Android app. I wanted to do something that would be easy enough to act as a starter project, but still actually be useful &#8212; to me and to others. So I decided to build an unofficial app for Philip Defranco.1 Although that&#8217;s not as creative as a wholly [...]]]></description>
			<content:encoded><![CDATA[<p>Well, I just finished up my first <a href="http://www.androlib.com/android.application.com-anoaharc-pdapp-jwjwz.aspx">Android app</a>.  I wanted to do something that would be easy enough to act as a starter project, but still actually be useful &#8212; to me and to others.  So I decided to build an unofficial app for <a href="http://www.youtube.com/user/sxephil">Philip Defranco</a>.<sup class='footnote'><a href='#fn-315-1' id='fnref-315-1'>1</a></sup>  Although that&#8217;s not as creative as a wholly original app, I think it allowed me to ride Philly D&#8217;s coattails a bit and actually get some traction.  After a few days, it&#8217;s been downloaded 189 times.  That&#8217;s no <a href="http://en.wikipedia.org/wiki/Tap_Tap_Revenge">Tap Tap Revenge</a>, but at least it&#8217;s something I can mention without getting too embarrassed.  And I really love knowing that there are people out there benefiting (just a tad!) from my work.</p>
<p>Now, for number two&#8230;
<div class='footnotes'>
<div class='footnotedivider'></div>
<ol>
<li id='fn-315-1'>He&#8217;s had an iPhone app for a few months, but apparently his Android developer is dragging his feet. <span class='footnotereverse'><a href='#fnref-315-1'>&#8617;</a></span></li>
</ol>
</div>
]]></content:encoded>
			<wfw:commentRss>http://anoaharc.com/the-unofficial-philly-d-android-app/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A Handy Firefox Hack (Or Several?)</title>
		<link>http://anoaharc.com/a-handy-firefox-hack-or-several/</link>
		<comments>http://anoaharc.com/a-handy-firefox-hack-or-several/#comments</comments>
		<pubDate>Fri, 09 Jul 2010 20:34:45 +0000</pubDate>
		<dc:creator>Noah</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://anoaharc.com/?p=301</guid>
		<description><![CDATA[When I&#8217;m browsing a website, sometimes I find myself needing to search for a specific topic on the site. Some sites have their own search boxes, but, in my experience, such homegrown site searches tend to be disappointing. (They can, however, often be improved using a Google Site Search.) Historically, I&#8217;ve typically resorted to opening [...]]]></description>
			<content:encoded><![CDATA[<p>When I&#8217;m browsing a website, sometimes I find myself needing to search for a specific topic on the site.  Some sites have their own search boxes, but, in my experience, such homegrown site searches tend to be disappointing.  (They can, however, often be improved using a <a href="http://www.google.com/sitesearch/">Google Site Search</a>.)</p>
<p>Historically, I&#8217;ve typically resorted to opening a new tab and typing &#8220;g site:www.example.com query&#8221;.  The &#8216;g&#8217; triggers my Firefox <a href="http://www.mozilla.org/docs/end-user/keywords.html">custom keyword</a> search for Google, and the <a href="http://www.brianwhite.org/2007/04/27/google-site-operator-an-ode-to-thee/">&#8216;site&#8217; operator</a> confines a search to specific domain.  Clearly, with a long domain, this can result in a lot of typing, so it&#8217;s always something I do reluctantly.<sup class='footnote'><a href='#fn-301-1' id='fnref-301-1'>1</a></sup></p>
<p>My first solution was just to beef up my custom keyword arsenal a bit, and map &#8216;gs&#8217; to a Google search preloaded with the &#8216;site&#8217; operator.  This was better, but, again, most of my searches are targeted to the site I&#8217;m currently browsing.  Typing the domain again, especially when it was already in the address bar, was a far cry from ideal.  Unfortunately, the custom keyword syntax is pretty basic, and I couldn&#8217;t seem to find a way to grab that domain information.</p>
<p>Luckily, I hit upon the idea of using a JavaScript <a href="http://code.google.com/p/browsersec/wiki/Part1#Pseudo_URL_schemes">pseudo-URL</a>.  This would let me map a Firefox custom keyword search to a JavaScript snippet, and thereby pretty much do anything I wanted!</p>
<p>The snippet I used is:</p>
<pre class="code">
javascript: var host = document.location.href; if (host.indexOf("http://") == 0) {host = host.substr(7);} else if (host.indexOf("https://") == 0) {host = host.substr(8);}; if (host.indexOf("/") != 0) {host = host.substr(0, host.indexOf("/"));}; document.location = "https://www.google.com/search?hl=en&#038;q=site:"+host+" "+"%s";
</pre>
<p>I just mapped it to &#8216;gsl&#8217; for Google Site Local.  It is wonderful.
<div class='footnotes'>
<div class='footnotedivider'></div>
<ol>
<li id='fn-301-1'>I have the typical developer&#8217;s <a href="http://www.roesler-ac.de/wolfram/acro/all.htm">hatred of unnecessary typing</a>, to the point where much of my computer use can be characterized as an endless tug-of-war, where only the strongest urges actually make it out of my finger tips.  Mousing &#8212; or worse, the dreaded transition from keyboard to mouse &#8212; I can&#8217;t even talk about. <span class='footnotereverse'><a href='#fnref-301-1'>&#8617;</a></span></li>
</ol>
</div>
]]></content:encoded>
			<wfw:commentRss>http://anoaharc.com/a-handy-firefox-hack-or-several/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Another Take On Rockefeller</title>
		<link>http://anoaharc.com/another-take-on-rockefeller/</link>
		<comments>http://anoaharc.com/another-take-on-rockefeller/#comments</comments>
		<pubDate>Sat, 08 May 2010 05:24:00 +0000</pubDate>
		<dc:creator>Noah</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://anoaharc.com/?p=286</guid>
		<description><![CDATA[When consolidation occurs in these markets, we need to pay attention. These are the words of Commerce Committee Chairman John D. Rockefeller, on the proposed acquisition of NBC Universal by Comcast. He is the great grandson of the original John D. I guess after a few generations, an apple can cover quite some distance. And [...]]]></description>
			<content:encoded><![CDATA[<blockquote><p>
When consolidation occurs in these markets, we need to pay attention.
</p></blockquote>
<p>These are the <a href="http://www.usatoday.com/life/television/news/2010-03-11-comcast-NBC_N.htm">words</a> of Commerce Committee Chairman <a href="http://en.wikipedia.org/wiki/Jay_Rockefeller">John D. Rockefeller</a>, on the proposed acquisition of NBC Universal by Comcast.  He is the great grandson of the original John D.  I guess after a few generations, an apple can cover quite some distance.</p>
<p>And another interesting twist &#8212; NBC Universal is headquartered in <a href="http://en.wikipedia.org/wiki/Rockefeller_Plaza">Rockefeller Plaza</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://anoaharc.com/another-take-on-rockefeller/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Perspectival Cleft</title>
		<link>http://anoaharc.com/the-perspectival-cleft/</link>
		<comments>http://anoaharc.com/the-perspectival-cleft/#comments</comments>
		<pubDate>Sun, 27 Dec 2009 17:05:47 +0000</pubDate>
		<dc:creator>Noah</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://anoaharc.com/?p=249</guid>
		<description><![CDATA[I love debate. For me, the line between a good conversation and an LD is thin, and mostly relates to time limits. Obviously, this love can be something of a challenge, socially speaking &#8212; though I do like to think that, as I&#8217;ve grown older, I&#8217;ve gradually developed a facility for &#8220;shooting the shit&#8221; or [...]]]></description>
			<content:encoded><![CDATA[<p>I love debate.  For me, the line between a good conversation and an <a href="http://en.wikipedia.org/wiki/Lincoln_Douglas">LD</a> is thin, and mostly relates to time limits.  Obviously, this love can be something of a challenge, socially speaking &#8212; though I do like to think that, as I&#8217;ve grown older, I&#8217;ve gradually developed a facility for &#8220;shooting the shit&#8221; or &#8220;small talk&#8221;, or whatever it is you call everything that&#8217;s not debate.</p>
<p>In general, other people seem to dislike debate-style conversations for two reasons: they don&#8217;t like the oppositional flavor of the discussion, or<sup class='footnote'><a href='#fn-249-1' id='fnref-249-1'>1</a></sup> they don&#8217;t see the point.  I&#8217;m a competitive person, so I actually enjoy the first reason &#8212; as long as ad hominem attacks and other fallacies are left out of it.  However, both the engineer and the artist in me are very sensitive to the second reason.</p>
<blockquote><p>
Perfection is achieved, not when there is nothing more to add, but when there is nothing left to take away.</p>
<p><a href="http://en.wikipedia.org/wiki/Antoine_de_Saint-Exupery">Antoine de Saint Exupéry</a>
</p></blockquote>
<p>As people say, you&#8217;re never going to convince someone who believes X of the merits of ~X, and that is doubly true within a single conversation.  So why waste your breath?</p>
<p>In two words: perspectival cleft.  This is a term that has been kicking around my head for a while now, and something akin to its meaning may have already been coined.  But what I&#8217;m talking about is simple: the place where two reasonable people&#8217;s opinions diverge.<sup class='footnote'><a href='#fn-249-2' id='fnref-249-2'>2</a></sup>  The place, in other words, where the disagreement is born.</p>
<p>The awareness of such a cleft can dramatically change the tenor of the conversation.  Rather than attempting to force two people&#8217;s opinions to be parallel, you can simply work to uncover the exact location of the perspectival cleft.  And once you do uncover it, it&#8217;s really a marvel.  It&#8217;s sort of like finding a book that says one thing to one person, and something totally different to the other.  Moreover, there naturally are reasons for the cleft itself.  Identifying the cleft is a concrete step toward resolving them, and thereby the overarching disagreement.  These consequences make the discovery of the cleft a practical goal &#8212; in addition to an amusing diversion &#8212; and thus one whose achievement is deeply satisfying.
<div class='footnotes'>
<div class='footnotedivider'></div>
<ol>
<li id='fn-249-1'>The word &#8220;or&#8221; is intrinsically inclusive, rendering the phrase &#8220;and/or&#8221; redundant.  I vote to introduce <a href="http://en.wikipedia.org/wiki/Xor">&#8220;xor&#8221;</a> into the common lexicon for the rare cases we actually demand exclusivity. <span class='footnotereverse'><a href='#fnref-249-1'>&#8617;</a></span></li>
<li id='fn-249-2'>This naturally assumes that they had converged to begin with, but I believe this is a fair assumption &#8212; most sane adults from the modern era actually have very similar fundamental beliefs about the world.  This is true practically (people concede the utility of tools, for example), as well as morally (people concede the immorality of slavery). <span class='footnotereverse'><a href='#fnref-249-2'>&#8617;</a></span></li>
</ol>
</div>
]]></content:encoded>
			<wfw:commentRss>http://anoaharc.com/the-perspectival-cleft/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Bayes</title>
		<link>http://anoaharc.com/bayes/</link>
		<comments>http://anoaharc.com/bayes/#comments</comments>
		<pubDate>Wed, 04 Nov 2009 06:58:24 +0000</pubDate>
		<dc:creator>Noah</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://anoaharc.com/?p=238</guid>
		<description><![CDATA[I am studying Bayes&#8216; theorem in school right now, probably for the third or fourth time. Nevertheless, like many aspects of mathematics, (and everything I suppose) I think I learn it just a little bit differently and better each time. The big realization for me on this occasion is that the theorem is succinctly and [...]]]></description>
			<content:encoded><![CDATA[<p>I am studying <a href="http://en.wikipedia.org/wiki/Thomas_Bayes">Bayes</a>&#8216; <a href="http://en.wikipedia.org/wiki/Bayes_rule">theorem</a> in school right now, probably for the third or fourth time.</p>
<div class="wp-caption aligncenter" style="width: 219px"><img alt="Bayes formula" src="http://upload.wikimedia.org/math/6/b/c/6bce478cdca0db60def5bf6059404c90.png" title="Bayes formula" width="209" height="48" /><p class="wp-caption-text">Bayes&#39; formula, courtesy of Wikipedia</p></div>
<p>Nevertheless, like many aspects of mathematics, (and everything I suppose) I think I learn it just a little bit differently and better each time.</p>
<p>The big realization for me on this occasion is that the theorem is succinctly and practically encapsulated by <a href="http://en.wikipedia.org/wiki/Carl_sagan">Carl Sagan</a>&#8216;s famous epigram:</p>
<blockquote><p>
Extraordinary claims require extraordinary evidence.
</p></blockquote>
<p>Basically, we can assume that P(B|A) is high.  B is the observed phenomenon, and A is the explanation, so it wouldn&#8217;t make much sense to talk about them together if A didn&#8217;t do a good job explaining why B occurs.</p>
<p>Then, it&#8217;s just a matter of the ratio between P(A) and P(B).  If A is a wild, crazy, and new explanation, that it better have some wild crazy and new data to back it up.  That will help keep P(A) / P(B) close to 1, and thus P(A|B) close to 1, meaning that A is a good theory.</p>
<p>Now obviously I&#8217;m not the first person to think this up (in fact, <a href="http://www.skepticalinvestigations.org/anomalistics/practices.htm">neither was Sagan</a>).  But it really clicked for me, and it&#8217;s fun to share when that happens.</p>
]]></content:encoded>
			<wfw:commentRss>http://anoaharc.com/bayes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>On John D. Rockefeller</title>
		<link>http://anoaharc.com/on-john-d-rockefeller/</link>
		<comments>http://anoaharc.com/on-john-d-rockefeller/#comments</comments>
		<pubDate>Wed, 30 Sep 2009 04:54:31 +0000</pubDate>
		<dc:creator>Noah</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://anoaharc.com/?p=211</guid>
		<description><![CDATA[I am reading Titan: The Life of John D. Rockefeller, Sr. right now, and it is truly a great book. It is a biography of Rockefeller (of course), but it is the most engaging, novelistic biography I&#8217;ve ever read. Ron Chernow did a wonderful job. If you want more reason to pick it up (or [...]]]></description>
			<content:encoded><![CDATA[<p>I am reading <a href="http://www.amazon.com/Titan-Life-John-Rockefeller-Sr/dp/1400077303/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1254276496&amp;sr=8-1"><i>Titan: The Life of John D. Rockefeller, Sr.</i></a> right now, and it is truly a great book.  It is a biography of <a href="http://en.wikipedia.org/wiki/John_D._Rockefeller">Rockefeller</a> (of course), but it is the most engaging, novelistic biography I&#8217;ve ever read.  <a href="http://en.wikipedia.org/wiki/Ron_Chernow">Ron Chernow</a> did a wonderful job.  If you want more reason to pick it up (or if you just want the nuggets), here are some of my favorite parts so far.</p>
<h3>Quotes and Anecdotes</h3>
<p>Rockefeller&#8217;s father decided to stop paying tuition for his high school with only a few months to go before graduation, and he was forced to drop out and find his first real job.  He knew he wanted a position in the commodities trading industry &#8212; rather than as a laborer or in another trade &#8212; so he decided to simply apply to every commodities trading house in Cleveland, where he was living at the time.</p>
<blockquote><p>
Each morning, [Rockefeller] left his boardinghouse at eight o&#8217;clock, clothed in a dark suit with a high collar and black tie, to make his round of appointed firms.  This grimly determined trek went on each day &#8212; six days a week for six consecutive weeks &#8212; until late in the afternoon. . . . Because he approached his job hunt devoid of any doubt or self-pity, [Rockefeller] could stare down all discouragement.  &#8220;I was working every day at my business &#8212; the business of looking for work.  I put in my full time at this every day.&#8221;
</p></blockquote>
<p>Rockefeller was dogged but also clever.  In order to capture the profits of the coopers who made barrels for his oil, he decided to begin making barrels himself.</p>
<blockquote><p>
Other Cleveland coopers bought and shipped green timber to their shops, whereas Rockefeller had the oak sawed in the woods then dried in kilns, reducing its weight and slicing transportation costs in half.
</p></blockquote>
<p>This cleverness could also be used in the service of inefficiency, as shown when a competing firm attempted to build a pipeline from Oil Creek, in northwest Pennsylvania, to Williamsport, in the center of the state.</p>
<blockquote><p>
Standard Oil . . . embarked on a real-estate spree of monumental proportions, buying up strips of land or &#8220;dead lines&#8221; that ran in a straight line from the northern to the southern border of Pennsylvania, to block the [competing pipeline's] advance.  Overnight, bewildered farmers became rich by selling parcels for extravagant sums to Standard oil agents who invaded their sleepy towns.
</p></blockquote>
<p>And, most unfortunately, he could be outright unethical, purchasing stakes in several newspapers in order to ensure favorable coverage and habitually bribing politicians (though, in his defense, this was common during the period).  One one occasion he outdid himself, though.</p>
<blockquote><p>
Standard Oil regarded [certain legislation] with such apprehension that Henry Flagler<sup class='footnote'><a href='#fn-211-1' id='fnref-211-1'>1</a></sup> returned from Florida, where he was recuperating from poor health, to spearhead the lobbying campaign.  To foster the impression of a popular groundswell against the bill, he hired lawyers to [come to the legislature and] pose as incensed farmers and landowners in favor of the status quo.
</p></blockquote>
<p>These quotes are all from the first couple hundred pages of <i>Titan</i>, which deal with the building of the Standard Oil empire.  The rest of the book is focused more on his philanthropy and later years<sup class='footnote'><a href='#fn-211-2' id='fnref-211-2'>2</a></sup>, and so aren&#8217;t as interesting to me<sup class='footnote'><a href='#fn-211-3' id='fnref-211-3'>3</a></sup>.  But anyway, try just the first third or so, and don&#8217;t be put off by its length!</p>
<h3>Additional Musings</h3>
<p>One of the clearest messages in Chernow&#8217;s book is that Rockefeller lived two lives.  His business dealings, especially in the early years, were obviously cutthroat and unchristian<sup class='footnote'><a href='#fn-211-4' id='fnref-211-4'>4</a></sup>, but, as a private, devoutly Baptist citizen, I believe he honestly was unable to see that.  The boundary between his two worlds was so high and thick that he wasn&#8217;t even gripped by denial &#8212; he simply failed to see the contradictions.  Although one might be concerned by this lack of objective introspection, I think it was an important contributor to Rockefeller&#8217;s success, enabling him to fortify himself with Christian self-righteousness, but at the same time to fight his competitors with a broad array of weapons.  His example serves as a good reminder that extraordinary people are also abnormal &#8212; and that the traits are very often interlinked.</p>
<p>Another strong, and perhaps obvious, message is that though he was smart and incredibly tenacious, Rockefeller was also lucky.  He started Standard Oil when its chief product was kerosene, then used primarily for illumination.  Automobiles, electrical generation, and plastics were all many years away when he chose his industry.  Though Rockefeller certainly would have been notable if these other products had never been developed &#8212; and, in fact, he already was in the 1880s, when they by and large hadn&#8217;t been &#8212; his legacy could not have developed to nearly the same stature.  The role of luck is an important factor to keep in mind, both when praising success and criticizing failure, and one that is perhaps <a href="http://www.ted.com/talks/alain_de_botton_a_kinder_gentler_philosophy_of_success.html">too often overlooked today</a>.
<div class='footnotes'>
<div class='footnotedivider'></div>
<ol>
<li id='fn-211-1'>Flagler was one of Rockefeller&#8217;s oldest and closest business partners. <span class='footnotereverse'><a href='#fnref-211-1'>&#8617;</a></span></li>
<li id='fn-211-2'>The last forty years of his life Rockefeller was retired. <span class='footnotereverse'><a href='#fnref-211-2'>&#8617;</a></span></li>
<li id='fn-211-3'>Yet. <span class='footnotereverse'><a href='#fnref-211-3'>&#8617;</a></span></li>
<li id='fn-211-4'>And effective. <span class='footnotereverse'><a href='#fnref-211-4'>&#8617;</a></span></li>
</ol>
</div>
]]></content:encoded>
			<wfw:commentRss>http://anoaharc.com/on-john-d-rockefeller/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>How To Use Google Spreadsheets With Google App Engine, Part 3</title>
		<link>http://anoaharc.com/how-to-use-google-spreadsheets-with-google-app-engine-part-3/</link>
		<comments>http://anoaharc.com/how-to-use-google-spreadsheets-with-google-app-engine-part-3/#comments</comments>
		<pubDate>Fri, 18 Sep 2009 04:40:35 +0000</pubDate>
		<dc:creator>Noah</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://anoaharc.com/?p=172</guid>
		<description><![CDATA[Sorry for the long delay (first post, second post)! I just started school again (senior year!), so the last few weeks have been packing, finding an apartment, moving in, choosing classes, actually going to class, et cetera et cetera. Anyway, the following examples are really just pretty wrappers for functionality included in the raw Spreadsheets [...]]]></description>
			<content:encoded><![CDATA[<p>Sorry for the long delay (<a href="http://anoaharc.com/2009/08/how-to-use-google-spreadsheets-with-google-app-engine-part-1/">first post</a>, <a href="http://anoaharc.com/2009/09/how-to-use-google-spreadsheets-with-google-app-engine-part-2/">second post</a>)!  I just started school again (senior year!), so the last few weeks have been packing, finding an apartment, moving in, choosing classes, actually <i>going</i> to class, et cetera et cetera.</p>
<p>Anyway, the following examples are really just pretty wrappers for functionality included in the raw <a href="http://code.google.com/apis/spreadsheets/docs/3.0/reference.html">Spreadsheets API</a>, but they&#8217;ll give you something concrete to work from.  They are pretty much just copy-pasted from my code, but I had to reformat them a bit for the blog.  As always, take a good, hard look before using them in your system.</p>
<h3>Blazing Batch Modifications</h3>
<p>The biggest change from the <a href="/2009/09/how-to-use-google-spreadsheets-with-google-app-engine-part-2/">last post</a> is the ability to cache modification orders and execute them in batches.  This obviously is handy for conserving bandwidth, CPU cycles, and even time, and is included in the actual <a href="http://code.google.com/apis/spreadsheets/docs/3.0/reference.html#CellFeed">Spreadsheets API</a>.</p>
<pre class="code">
def setCells(cellDict):
    wsID = '<b>yourWorksheetID</b>'
    destURL = 'http://spreadsheets.google.com/feeds/cells/'+wsID+'/1/private/full/batch'
    postStr = '<feed xmlns="http://www.w3.org/2005/Atom" xmlns:batch="http://schemas.google.com/gdata/batch" xmlns:gs="http://schemas.google.com/spreadsheets/2006">'
    for (rowNum, colNum), content in cellDict.items():
        postStr += '<entry><batch:operation type="update"/><id>http://spreadsheets.google.com/feeds/cells/'+\
            wsID+'/1/private/full/R'+str(rowNum)+'C'+str(colNum)+'</id>'
        postStr += '<gs:cell row="'+str(rowNum)+'" col="'+str(colNum)+\
            '" inputValue="'+str(content)+'"/></entry>'
    postStr += '</feed>'
    urlfetch.fetch(url=destURL, method=urlfetch.POST, payload=postStr, \
        headers={'Content-Type' : 'application/atom+xml', 'GData-Version' : '3.0', \
         'Authorization' : 'AuthSub token="<b>yourAuthSubToken</b>"', 'If-Match' : '*'})
</pre>
<p>Be sure to make <code><b>cellDict</b></code> a dictionary object of the form <code>(rowNum, colNum) -> content</code>, that is, a tuple going to some string-cast-able content.  And make sure to change <code><b>yourWorkSheetID</b></code> and <code><b>yourAuthSubToken</b></code>.</p>
<h3>Blissful Batch Reads</h3>
<p>It would be awfully asymmetrical (and impractical) to leave out batch reads, so here is some sample code to that end.  Again, this code only wraps the Spreadsheets API&#8217;s own batch read functionality.</p>
<pre class="code">
def getCells(minRow, maxRow, minCol, maxCol):
    wsID = '<b>yourWorksheetID</b>'
    destURL = 'http://spreadsheets.google.com/feeds/cells/'+ \
        wsID+'/1/private/full?min-row='+str(minRow)+'&#038;max-row='+ \
        str(maxRow)+'&#038;min-col='+str(minCol)+'&#038;max-col='+str(maxCol)
    retStr = urlfetch.fetch(url=destURL, method=urlfetch.GET, \
        headers={'Content-Type' : 'application/atom+xml', \
        'GData-Version' : '3.0', 'Authorization' : \
        'AuthSub token="<b>yourAuthSubToken</b>"', 'If-Match' : '*'}).content
    gsOccurrences = re.findall(r"<gs:cell.*?>", retStr)
    retDict = {}
    for occ in gsOccurrences:
        row = int(re.findall(r"(?<=row=').*?(?=')", occ)[0])
        col = int(re.findall(r"(?<=col=').*?(?=')", occ)[0])
        content = re.findall(r"(?<=inputValue=').*?(?=')", occ)[0]
        retDict[(row, col)] = content
    return retDict
</pre>
<p>This will return a dictionary of the same format used as input in the <code>setCells</code> function.  Again make sure to change <code><b>yourWorkSheetID</b></code> and <code><b>yourAuthSubToken</b></code>.</p>
<h3>Final Thoughts</h3>
<p>I've now been using the above code in production for about three weeks, and it really works well.  Whenever I want an update on <a href="http://www.searchekko.com">SearchEkko</a> I can just check a fast-loading, real-time-updating Google Spreadsheet -- much handier than the default App Engine administrative interface.  Hope it helps you out!</p>
]]></content:encoded>
			<wfw:commentRss>http://anoaharc.com/how-to-use-google-spreadsheets-with-google-app-engine-part-3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How To Use Google Spreadsheets With Google App Engine, Part 2</title>
		<link>http://anoaharc.com/how-to-use-google-spreadsheets-with-google-app-engine-part-2/</link>
		<comments>http://anoaharc.com/how-to-use-google-spreadsheets-with-google-app-engine-part-2/#comments</comments>
		<pubDate>Tue, 01 Sep 2009 06:15:53 +0000</pubDate>
		<dc:creator>Noah</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://anoaharc.com/?p=123</guid>
		<description><![CDATA[This post is a continuation of this one. Last time I finished with acquiring your AuthSub session token, and now I&#8217;ll show you how to use it to manipulate your spreadsheet. Reading Your Spreadsheet It&#8217;s really easy to read one of your spreadsheet&#8217;s cells, especially with RESTClient. You just need to know your spreadsheet&#8217;s ID, [...]]]></description>
			<content:encoded><![CDATA[<p>This post is a continuation of <a href="http://anoaharc.com/2009/08/how-to-use-google-spreadsheets-with-google-app-engine-part-1/">this one</a>.  Last time I finished with acquiring your AuthSub session token, and now I&#8217;ll show you how to use it to manipulate your spreadsheet.</p>
<h3>Reading Your Spreadsheet</h3>
<p>It&#8217;s really easy to read one of your spreadsheet&#8217;s cells, especially with <a href="https://addons.mozilla.org/en-US/firefox/addon/9780">RESTClient</a>.  You just need to know your spreadsheet&#8217;s ID, which is the <code><b>key</b></code> value <a href="http://anoaharc.com/2009/08/how-to-use-google-spreadsheets-with-google-app-engine-part-1/#setup">I mentioned earlier</a>.  Simply send a GET request to</p>
<pre class="code">

http://spreadsheets.google.com/feeds/cells/<b>key</b>/1/private/full/<b>cell</b>
</pre>
<p>With headers:</p>
<pre class="code">
Authorization: AuthSub token="<b>yourSessionAuthToken</b>"
GData-Version: 3.0
</pre>
<p>Replace <code><b>key</b></code> with your spreadsheet&#8217;s key, and <code><b>cell</b></code> with a string in the format &#8220;RXCY&#8221;, with X and Y being positive integers (row and column numbers).</p>
<p>Note that the section <code>/1/</code> indicates that you&#8217;re reading the first worksheet in the spreadsheet, i.e. &#8220;Sheet1&#8243;.  If you&#8217;d like to work with &#8220;Sheet2&#8243;, well, you can figure that out.  <code>GData-Version</code> simply specifies which version of the API protocol you&#8217;re using.</p>
<p>Anyway, the server will return a bunch of XML &#8212; just look for <code>inputValue='example cell value'</code> and you&#8217;re good to go.</p>
<h3>Modifying Your Spreadsheet</h3>
<p>In order to modify the spreadsheet, you&#8217;ll send a PUT request to the same URL:</p>
<pre class="code">

http://spreadsheets.google.com/feeds/cells/<b>key</b>/1/private/full/<b>cell</b>
</pre>
<p>The body of the request should be:</p>
<pre class="code">
&lt;entry xmlns="http://www.w3.org/2005/Atom" xmlns:gs="http://schemas.google.com/spreadsheets/2006"&gt;
  &lt;link rel="edit" type="application/atom+xml" href="http://spreadsheets.google.com/feeds/cells/<b>key</b>/1/private/full/<b>cell</b>"/&gt;
  &lt;gs:cell row="<b>X</b>" col="<b>Y</b>" inputValue="<b>whatever</b>"/&gt;
&lt;/entry&gt;
</pre>
<p>Replace <code><b>key</b></code> and <code><b>cell</b></code> as before, and <code><b>X</b></code>, <code><b>Y</b></code>, and <code><b>whatever</b></code> self-explanatorily.</p>
<p>Finally, the headers of the request must be:</p>
<pre class="code">
Content-Type: application/atom+xml
Authorization: AuthSub token="<b>yourSessionAuthToken</b>"
GData-Version: 3.0
If-Match: *
</pre>
<p>That is all pretty easy except the <code>If-Match</code>.  The asterisk value for that header tells the spreadsheet to update even if there has been another recent write to that cell (destroying thread safety).  If you want to be more punctilious, look <a href="http://code.google.com/apis/spreadsheets/docs/3.0/developers_guide_protocol.html#UpdatingTables">here</a>.</p>
<h3>Complaints And Possible Expansions<a name="weaknesses"></a></h3>
<p>If all went well, you can now programmatically read and write a Google Spreadsheet.  I&#8217;ll add some slightly more sophisticated sample code in the next post, but for now, here are a couple weaknesses I&#8217;ve found.</p>
<p>First, the spreadsheet mostly updates values in real-time, but occasionally (seemingly after a long time-out) requires a page refresh to update.  Yeah, pretty minor.  The other problem is more serious, though.  Sometimes (presumably when traffic is high) App Engine&#8217;s <a href="http://code.google.com/appengine/docs/python/urlfetch/">urlfetch</a> throws errors because the Spreadsheets server takes too long to respond to a request.  This means that some updates aren&#8217;t recorded.  Could be a problem if you&#8217;re <i>really</i> counting on statistics, but, as mentioned, then you should be trying something else.  However, there are also opportunities for expansions that could alleviate both these issues.</p>
<p>The best expansion/optimization I can think of would be to use App Engine&#8217;s <a href="http://code.google.com/appengine/docs/python/memcache/">Memcache API</a>.  You could buffer spreadsheet updates, and rollback whenever the Spreadsheets server timed out.  And you could also send the buffered requests in batches (more on that in the sample code), minimizing traffic.  My itch got scratched before this point, but if you do get something like this working, <a href="http://anoaharc.com/about">let me know</a> and I&#8217;ll use it happily!  The other expansion would be to use <a href="http://code.google.com/apis/spreadsheets/docs/3.0/developers_guide_protocol.html#TableFeeds">tables</a> instead of cell-level access.  This seems to be the preferred method of quasi-database Google Spreadsheets usage, but it seemed like unnecessary hassle to me.  If you get serious, though, it could be something to look into.</p>
]]></content:encoded>
			<wfw:commentRss>http://anoaharc.com/how-to-use-google-spreadsheets-with-google-app-engine-part-2/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>How To Use Google Spreadsheets With Google App Engine, Part 1</title>
		<link>http://anoaharc.com/how-to-use-google-spreadsheets-with-google-app-engine-part-1/</link>
		<comments>http://anoaharc.com/how-to-use-google-spreadsheets-with-google-app-engine-part-1/#comments</comments>
		<pubDate>Mon, 31 Aug 2009 07:53:47 +0000</pubDate>
		<dc:creator>Noah</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://anoaharc.com/?p=76</guid>
		<description><![CDATA[There have been some discussions about this already, notably a QCon presentation, but a redundant tutorial or two never hurt a soul. This is for the Python version of App Engine, but it shouldn&#8217;t be much different for Java. Why? App Engine datastore writes are really expensive, and prohibitively so for something like custom statistics. [...]]]></description>
			<content:encoded><![CDATA[<p>There have been some discussions about this already, notably a <a href="http://qconsf.com/sf2008/presentation/Google+App+Engine+and+the+Google+Data+APIs">QCon presentation</a>, but a redundant tutorial or two never hurt a soul.  This is for the Python version of App Engine, but it shouldn&#8217;t be much different for Java.</p>
<h3>Why?</h3>
<p>App Engine datastore writes are <i>really</i> expensive, and prohibitively so for something like custom statistics.  For example, in an early version of <a href="http://www.searchekko.com">SearchEkko</a>, where I read and wrote to an &#8220;Admin&#8221; <a href="http://code.google.com/appengine/docs/python/datastore/modelclass.html">Model object</a> on most operations, it was costing over $6.20 CPM to serve SearchEkko <a href="http://www.searchekko.com/search?query=tesla">search results pages</a>!  This when the marginal cost of web-delivered content is <a href="http://www.techdirt.com/articles/20061025/014811.shtml">supposed to be zero</a>.  Obviously, App Engine wasn&#8217;t designed with this kind of usage in mind, but it was equally clear that I needed some type of custom statistics dashboard (how many displays, how many installs, etc).  So I started poking around.</p>
<h3>The Requirements (And Can-Do-Withouts)</h3>
<p>To summarize, I needed some type of database solution that:</p>
<ul>
<li>Offered cheap (as in resources) read and write access</li>
<li>Was cheap (as in money)</li>
<li>Was easily accessible from App Engine (so probably REST)</li>
<li>Tolerated frequent accesses and responded relatively quickly</li>
</ul>
<p>Since all I needed was a way to track statistics, I could forego a lot of typical database niceties, like:</p>
<ul>
<li>Transactions and thread safety</li>
<li>Guaranteed data integrity</li>
<li>Bullet-proof security</li>
</ul>
<p>Google Spreadsheets was what I eventually found, and so far it&#8217;s met my needs <a href="http://anoaharc.com/2009/09/how-to-use-google-spreadsheets-with-google-app-engine-part-2/#weaknesses">almost</a> to a T.</p>
<p><b>Note:</b> if you&#8217;re looking for something to use with real, critical data, look elsewhere.  This is definitely a little hacky, and certainly isn&#8217;t perfect, but it&#8217;s a relatively easy way to track things you don&#8217;t care <i>that</i> much about in App Engine.</p>
<h3>Setting Up Your Spreadsheet<a name="setup"></a></h3>
<p>Just go into Google Documents and create a new spreadsheet.  The URL will be something like</p>
<pre class="code">

http://spreadsheets.google.com/ccc?<b>key</b>=bNadyGyiH2Ma6Cx54NmiL2e__4g&#038;hl=en
</pre>
<p>Note the value of the <code><b>key</b></code> argument &#8212; you&#8217;ll have to use it later.</p>
<p>When you&#8217;re accessing your spreadsheet from App Engine, it&#8217;s easiest to just set specific cells to the values you want.  This means you can lay out the spreadsheet pretty intuitively.  In my SearchEkko statistics spreadsheet, I simply made the first row labels for each column, with the corresponding data falling below each label, exactly as you&#8217;d set up a standard spreadsheet.</p>
<h3>Accessing Your Spreadsheet</h3>
<p>In order to access your spreadsheet you have to use the <a href="http://code.google.com/apis/spreadsheets/">Google Spreadsheets API</a>.  There is a <a href="http://code.google.com/apis/spreadsheets/docs/1.0/developers_guide_python.html">Python</a> library you can use, but it&#8217;s apparently outdated now.  Plus, for something pretty easy like this, I&#8217;d rather just use the base protocol, and that way I&#8217;ll be more likely to know what&#8217;s going on when something breaks.</p>
<p>In any case, you need to authenticate in order access your private spreadsheet data from App Engine.  The best way to do that for our purposes is by using <a href="http://code.google.com/apis/accounts/docs/AuthSub.html">AuthSub</a>.  AuthSub is similar to <a href="http://oauth.net/">OAuth</a>, but isn&#8217;t an open standard, and is a bit better-suited to Google-specific tasks.  More to the point, it&#8217;s what I used, so it&#8217;s what you&#8217;re learning.</p>
<p>One of the easiest ways to play around with AuthSub is by downloading <a href="https://addons.mozilla.org/en-US/firefox/addon/9780">RESTClient</a>, an addon for Firefox.  Play around with it to learn how to submit <a href="http://en.wikipedia.org/wiki/HTTP_GET#Request_methods">HTTP POST and GET requests</a> to specific URLs, and with modified headers, or use another tool of your choice.</p>
<p>The next steps are also documented <a href="http://code.google.com/apis/spreadsheets/docs/3.0/developers_guide_protocol.html#Authenticating">here</a>, but I&#8217;ve tried to simplify and streamline them for your coding pleasure.</p>
<ol>
<li>Direct your browser to:</li>
<pre class="code">

https://www.google.com/accounts/AuthSubRequest?scope=http%3A%2F%2Fspreadsheets.google.com%2Ffeeds%2F&#038;session=1&#038;secure=0&#038;next=http%3A%2F%2F<b>www.example.com</b>
</pre>
<p>Naturally swap <code><b>www.example.com</b></code> with your own site.  Grant access, and note the URL that it sends you to.  Copy the the <code><b>token</b></code> parameter.  That&#8217;s your single-use AuthSub token.</p>
<p><b>Note:</b> This should work fine as-is if your site is hosted on App Engine, but if it&#8217;s not (ignoring for the moment why you&#8217;re reading this), there may be some additional steps here.</li>
<li>Send a GET request (in RESTClient terms) to the URL</li>
<pre class="code">

https://www.google.com/accounts/AuthSubSessionToken
</pre>
<p>Use headers:</p>
<pre class="code">
Content-Type: application/x-www-form-urlencoded
Authorization: AuthSub token=<b>"yourAuthToken"</b>
</pre>
<p>Obviously replace <code><b>"yourAuthToken"</b></code> with the single-use token you received, but keep the quotes.  You should get back a 200 OK status code, and the body will include your <i>session token</i>.  Though some documentation shows this value having an expiration, it really is usable indefinitely.  (You can revoke any tokens your Google Account has given out <a href="https://www.google.com/accounts/IssuedAuthSubTokens">here</a>).
</ol>
<p>Alright, now you have your indefinite-use AuthSub session token, and you&#8217;re one giant step closer to mingling Google Spreadsheets and App Engine.</p>
]]></content:encoded>
			<wfw:commentRss>http://anoaharc.com/how-to-use-google-spreadsheets-with-google-app-engine-part-1/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
