<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0"><channel><title>ryan.sh</title><link>http://ryan.sh/</link><description></description><lastBuildDate>Mon, 02 Jun 2014 00:00:00 -0400</lastBuildDate><item><title>Cocktail: The Heart</title><link>http://ryan.sh/2014/06/02/cocktail-the-heart/</link><description>&lt;p&gt;The &lt;a href="http://www.flatironlounge.com"&gt;Flatiron Lounge&lt;/a&gt; is my favorite cocktail bar in &lt;span class="caps"&gt;NYC&lt;/span&gt;. I&amp;#8217;ve long been captivated by the multi-step flavor of &lt;em&gt;The Heart it Races&lt;/em&gt; by &lt;a href="https://twitter.com/mixtressnyc"&gt;Julie Reiner&lt;/a&gt; which is no longer on the menu but known to the mixologists there. The real magic in this drink is the muddled coffee beans, which follow the rest of the flavors&amp;nbsp;chronologically. &lt;/p&gt;
&lt;p&gt;This drink is so superbly blended (and a Flatiron visit so fun) that I never had much luck identifying the components (other than coffee). But tonight, searching for ways to use Campari, I ran across a &lt;a href="http://kaldiscoffee.com/blogs/news/tagged/coffee-cocktail"&gt;variation&lt;/a&gt; on the classic Rye/Vermouth/Campari &lt;a href="http://www.nytimes.com/2014/01/29/dining/the-boulevardier-is-back-on-the-menu.html"&gt;Boulivardier&lt;/a&gt; (itself a variation on the crisp Negroni made with Gin/Vermouth/Campari) that gave me a&amp;nbsp;hunch:&lt;/p&gt;
&lt;p&gt;Swapping the gin for whiskey opens the drink up to blending with smoky flavors. Just add coffee beans and, voilà! It tastes like &lt;em&gt;The Heart it Races&lt;/em&gt;! Here&amp;#8217;s how to make my version, &lt;em&gt;The Heart&lt;/em&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img alt="The Heart" src="http://ryan.sh/2014/06/02/cocktail-the-heart/the-heart.jpg" /&gt;&lt;/p&gt;
&lt;h1&gt;The&amp;nbsp;Heart&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;2 oz. &lt;a href="http://widowjane.com/products/"&gt;Widow Jane&lt;/a&gt; 7-year straight&amp;nbsp;bourbon&lt;/li&gt;
&lt;li&gt;1/2 oz. Sweet&amp;nbsp;vermouth&lt;/li&gt;
&lt;li&gt;1/2 oz.&amp;nbsp;Campari&lt;/li&gt;
&lt;li&gt;3 freshly roasted espresso&amp;nbsp;beans&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Fill a mixing glass half-full of ice. Crush the espresso beans with a mortar and pestle and add to glass. Add bourbon, vermouth and Campari and stir for 30 seconds. Strain through a fine sieve into chilled cocktail glass. Garnish with a lemon&amp;nbsp;twist.&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Ryan Witt</dc:creator><pubDate>Mon, 02 Jun 2014 00:00:00 -0400</pubDate><guid isPermaLink="false">tag:ryan.sh,2014-06-02:2014/06/02/cocktail-the-heart/</guid><category>cocktail</category></item><item><title>More Turkey Burger</title><link>http://ryan.sh/2014/02/05/more-turkey-burger/</link><description>&lt;p&gt;&lt;img alt="" src="http://ryan.sh/2014/02/05/more-turkey-burger/turkey.jpg" /&gt;&lt;/p&gt;
&lt;p&gt;Haven&amp;#8217;t done one of these in a&amp;nbsp;while.&lt;/p&gt;
&lt;p&gt;Turkey burgers made with diced onion and Gouda. Topped with Gouda, sautéed crimini mushrooms, onions and baby spinach on&amp;nbsp;brioche.&lt;/p&gt;
&lt;p&gt;People liked it. Including me.&amp;nbsp;Mmm.&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Ryan Witt</dc:creator><pubDate>Wed, 05 Feb 2014 20:59:00 -0500</pubDate><guid isPermaLink="false">tag:ryan.sh,2014-02-05:2014/02/05/more-turkey-burger/</guid><category>food</category></item><item><title>Let’s get ready to rumble</title><link>http://ryan.sh/2013/11/26/lets-get-ready-to-rumble/</link><description>&lt;p&gt;If there&amp;#8217;s one thing I like about Apple besides aluminum, glass and parting with my money, it&amp;#8217;s their attitude toward people who use&amp;nbsp;computers.&lt;/p&gt;
&lt;p&gt;Not that people who use computers (or people in general) are all that deserving or likable or easy to deal with. This story captures some of what I&amp;nbsp;mean.&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Ryan Witt</dc:creator><pubDate>Tue, 26 Nov 2013 00:00:00 -0500</pubDate><guid isPermaLink="false">tag:ryan.sh,2013-11-26:2013/11/26/lets-get-ready-to-rumble/</guid></item><item><title>Mobile is eating the world</title><link>http://ryan.sh/2013/05/25/mobile-is-eating-the-world/</link><description>&lt;blockquote&gt;
&lt;p&gt;I’ll be presenting these slides (or something pretty close to them) on 29 May at &lt;span class="caps"&gt;BEA&lt;/span&gt; in New York. They give a pretty good overview of where the industry sits&amp;nbsp;today.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I recently discovered Benedict Evans and subscribed to his &lt;a href="http://ben-evans.com/newsletter/"&gt;excellent mobile newsletter&lt;/a&gt;. Slides from his above presentation have been cherry-picked by the tech press over the last few days, but I&amp;#8217;d like to draw attention to this&amp;nbsp;one:&lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="https://image.slidesharecdn.com/201305bea-130517184340-phpapp01/95/slide-6-638.jpg?1369044063" /&gt;&lt;/p&gt;
&lt;p&gt;Fantastic storytelling with data. Very&amp;nbsp;Tufte.&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Ryan Witt</dc:creator><pubDate>Sat, 25 May 2013 00:00:00 -0400</pubDate><guid isPermaLink="false">tag:ryan.sh,2013-05-25:2013/05/25/mobile-is-eating-the-world/</guid></item><item><title>Regular expression tester</title><link>http://ryan.sh/2013/05/15/regular-expression-tester/</link><description>&lt;div style="margin: 15px 0; padding:5%; background-color:#f5f5f5"&gt;

&lt;table id="regex-2" class="table table-border"&gt;
    &lt;thead&gt;
        &lt;th&gt;
            Regular Expression:
            &lt;input
                style="border:none; padding:1ex; width:90%; font-size:16px;"
                id="exp1-2"
                value="ab"
                spellcheck="false"
            &gt;&lt;/input&gt;
        &lt;/th&gt;
        &lt;th&gt;
            Text:
            &lt;input
                style="border:none; padding:1ex; width:90%; font-size:16px;"
                id="exp2-2"
                value="aaabbb"
                spellcheck="false"
            &gt;&lt;/input&gt;
        &lt;/th&gt;
    &lt;/thead&gt;
    &lt;tbody&gt;
    &lt;/tbody&gt;
&lt;/table&gt;

&lt;div id="out" style="font-size:64px; color: red; text-align:center; line-height: 1;"&gt;aaabbb&lt;/div&gt;

&lt;script src="http://code.jquery.com/jquery-1.9.1.min.js"&gt;&lt;/script&gt;
&lt;script&gt;
var jqRX = $.noConflict();
jqRX('#exp1-2, #exp2-2').keydown(function(e) {e.stopPropagation();});
jqRX('#exp1-2, #exp2-2').keyup(function(e) {
    jqRX('#out').text(jqRX('#exp2-2').val()).html(
        jqRX('#out').text().replace(
            RegExp(jqRX('#exp1-2').val()),
            function(m) {return "&lt;span style=\"color:green\"&gt;"+m+"&lt;/span&gt;"}
        )
    );
    return false;
})
jqRX(document).ready(function(){jqRX('#exp1-2').trigger('keyup')});
&lt;/script&gt;

&lt;/div&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Ryan Witt</dc:creator><pubDate>Wed, 15 May 2013 00:00:00 -0400</pubDate><guid isPermaLink="false">tag:ryan.sh,2013-05-15:2013/05/15/regular-expression-tester/</guid></item><item><title>Hierarchy of caches</title><link>http://ryan.sh/2013/05/13/hierarchy-of-caches/</link><description>&lt;p&gt;Computers are a &lt;strong&gt;hierarchy of caches&lt;/strong&gt; that are &lt;strong&gt;fast in the average case&lt;/strong&gt;.
I&amp;#8217;m fond saying this, because it pretty much explains all of the decisions made in the last 60 years of computer&amp;nbsp;science.&lt;/p&gt;
&lt;p&gt;If you&amp;#8217;re a computer, there are quite a few choices for how to store things you&amp;#8217;re working on beyond
hard drives and memory that most often get talked about. The fastest are &lt;strong&gt;registers&lt;/strong&gt;, the hundered-or-so little number
pockets embedded right in the same circuts that do the adding subtracting, multiplying and dividing.
Unfortunately, they hold a mere &lt;strong&gt;thimblefull&lt;/strong&gt; of&amp;nbsp;data.&lt;/p&gt;
&lt;p&gt;Enter the &lt;strong&gt;L1 cache&lt;/strong&gt;, which holds a &lt;strong&gt;coffee cup&lt;/strong&gt; worth of data. This is still on the chip, and
pretty close to the registers, but a bit slower. L1 has some even bigger, even slower cousins called
the &lt;strong&gt;L2/L3 cache&lt;/strong&gt;, who live on the chip (often taking up half of it) and hold &lt;strong&gt;a large trash can&lt;/strong&gt;
worth of&amp;nbsp;data. &lt;/p&gt;
&lt;p&gt;Now we&amp;#8217;re getting somewhere! But we&amp;#8217;ve also run out of chip. Sillicon is expensive, and those
registers and cache take up a lot of space. Time to bring out the &lt;strong&gt;main memory&lt;/strong&gt; which holds a few
&lt;strong&gt;railway tankers&lt;/strong&gt; of data by squeezing it into a smaller&amp;nbsp;area.&lt;/p&gt;
&lt;p&gt;But what about our boatloads of photos, and videos we stash on the &lt;strong&gt;hard disk&lt;/strong&gt;? Keeping up the analogy, this
amount of data is comparable to the daily oil output of the &lt;strong&gt;Arctic National Wildlive Refuge&lt;/strong&gt; (&lt;a href="http://en.wikipedia.org/wiki/Arctic_National_Wildlife_Refuge"&gt;&lt;span class="caps"&gt;ANWR&lt;/span&gt;&lt;/a&gt;).
For more data than that, we&amp;#8217;ve got to go &lt;a href="http://www.youtube.com/watch?v=mjtqoQE_ezA"&gt;to the cloud&lt;/a&gt;, which is really
just a bunch of disks over &lt;strong&gt;a network&lt;/strong&gt; that can store as much data as &lt;strong&gt;&lt;span class="caps"&gt;US&lt;/span&gt; diesel consumption in one year&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;All this extra space comes a cost. Cache, memory and disks are increasingly further away from where
the calculation is taking place, so it takes increasingly long trips to get&amp;nbsp;there.&lt;/p&gt;
&lt;p&gt;A trip to the registers? That&amp;#8217;s like going to the &lt;strong&gt;coffee shop downstairs&lt;/strong&gt;. I wouldn&amp;#8217;t think twice, and
neither would an electron. L1 cache is a bit further, like heading to that tasty take out place &lt;strong&gt;down
the street&lt;/strong&gt;. But to get to the L2/L3 cache, I&amp;#8217;d want to hop on the &lt;strong&gt;subway for a few stops&lt;/strong&gt; (New Yorkers
are impatient, if you hadn&amp;#8217;t&amp;nbsp;heard).&lt;/p&gt;
&lt;p&gt;Now, getting to the main memory is like me heading from &lt;strong&gt;&lt;span class="caps"&gt;NYC&lt;/span&gt; to Westchester&lt;/strong&gt; on the Metro-North, 
perhaps a little over an hour. This is not a trip I&amp;#8217;d take on a whim. But now we&amp;#8217;ve got a really
big jump from memory and disk drives. The fastest drive you can get, a fancy new &lt;span class="caps"&gt;SSD&lt;/span&gt;, is like taking
the &lt;strong&gt;bus to Boston&lt;/strong&gt; (4 hours or so), but that&amp;#8217;s only reading from the drive, writing is like &lt;strong&gt;going to California&lt;/strong&gt;!
It gets even worse with disk drives that actually have spinny discs in them. This leg of the journey is
like &lt;strong&gt;going to China&lt;/strong&gt; for the very fastest drives, and flying a &lt;strong&gt;quarter of the way to the moon&lt;/strong&gt; for the slow&amp;nbsp;ones!&lt;/p&gt;
&lt;p&gt;It&amp;#8217;s easy to get caught up in the jargon of megabytes and gigabytes and loose perspective on the vast
numbers involved. I made a chart to help&lt;sup id="fnref:1"&gt;&lt;a class="footnote-ref" href="#fn:1" rel="footnote"&gt;1&lt;/a&gt;&lt;/sup&gt;:&lt;/p&gt;
&lt;div style="text-align:center"&gt;
&lt;img src="http://ryan.sh/2013/05/13/hierarchy-of-caches/orders-of-magnitude-anthro.png" class="img-rounded" style="width:85%; margin: 15px 0; padding:5%; background-color:#f5f5f5"&gt;
&lt;/div&gt;

&lt;p&gt;It fascinates me that each rung on the ladder is one &lt;strong&gt;order of magnitude&lt;/strong&gt; bigger (nerd speak for 10 times bigger)
than the previous, in both directions. I don&amp;#8217;t think this is a coincidence. Here&amp;#8217;s are the rough&amp;nbsp;numbers:&lt;/p&gt;
&lt;div style="text-align:center"&gt;
&lt;img src="http://ryan.sh/2013/05/13/hierarchy-of-caches/orders-of-magnitude.png" class="img-rounded" style="width:80%; margin: 15px 0; padding:5%; background-color:#f5f5f5"&gt;
&lt;/div&gt;

&lt;p&gt;Why are size and latency so close to linear? My best theory is we&amp;#8217;ve spend &lt;strong&gt;equal amounts of
time and money&lt;/strong&gt; making each part fast. Leaving a gap is either too expensive if you use the small fast
thing or too slow if you use the large thing (maybe &lt;a href="http://hypercritical.co"&gt;Siracusa&lt;/a&gt; or &lt;a href="http://anandtech.com"&gt;Anand&lt;/a&gt;
have a better&amp;nbsp;theory).&lt;/p&gt;
&lt;p&gt;The reason this chart is so important, is our &lt;strong&gt;hierarchy of caches&lt;/strong&gt; that says that you pay a lot of
latency to access data that&amp;#8217;s already in a fast cache. Much of the history of algorithms and data structures
are a &lt;strong&gt;series of clever tricks&lt;/strong&gt;&lt;sup id="fnref:2"&gt;&lt;a class="footnote-ref" href="#fn:2" rel="footnote"&gt;2&lt;/a&gt;&lt;/sup&gt; to keep the data that you&amp;#8217;re working on in the lower left side of the&amp;nbsp;chart. &lt;/p&gt;
&lt;p&gt;The term &lt;em&gt;d&amp;#8217;art&lt;/em&gt; for this is &lt;strong&gt;data locality&lt;/strong&gt;.&lt;/p&gt;
&lt;div class="footnote"&gt;
&lt;hr /&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;I made the charts for &lt;a href="http://cs4h.com"&gt;&lt;span class="caps"&gt;CS&lt;/span&gt; for Hackers&lt;/a&gt; at &lt;a href="http://generalassemb.ly"&gt;General Assembly&lt;/a&gt;, so they&amp;#8217;re licensed &lt;a href="http://creativecommons.org/licenses/by-nc-sa/3.0/us/"&gt;cc-by-nc-sa&lt;/a&gt;.&amp;#160;&lt;a class="footnote-backref" href="#fnref:1" rev="footnote" title="Jump back to footnote 1 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id="fn:2"&gt;
&lt;p&gt;Next time we&amp;#8217;ll talk more about why computers are &lt;strong&gt;fast in the average case&lt;/strong&gt;.&amp;#160;&lt;a class="footnote-backref" href="#fnref:2" rev="footnote" title="Jump back to footnote 2 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Ryan Witt</dc:creator><pubDate>Mon, 13 May 2013 00:00:00 -0400</pubDate><guid isPermaLink="false">tag:ryan.sh,2013-05-13:2013/05/13/hierarchy-of-caches/</guid></item><item><title>Thanks for leading the way, Steve</title><link>http://ryan.sh/2011/10/06/thanks-for-leading-the-way-steve/</link><description>&lt;p&gt;&lt;img alt="" src="http://ryan.sh/2011/10/06/thanks-for-leading-the-way-steve/steve.png" /&gt;&lt;/p&gt;
&lt;p&gt;Thanks for leading the way,&amp;nbsp;Steve.&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Ryan Witt</dc:creator><pubDate>Thu, 06 Oct 2011 17:48:35 -0400</pubDate><guid isPermaLink="false">tag:ryan.sh,2011-10-06:2011/10/06/thanks-for-leading-the-way-steve/</guid></item><item><title>Binary Adder</title><link>http://ryan.sh/2011/08/11/bit-input-5-bit-output-binary-adder-i-built-in/</link><description>&lt;p&gt;&lt;img alt="" src="http://ryan.sh/2011/08/11/bit-input-5-bit-output-binary-adder-i-built-in/adder.jpg" /&gt;&lt;/p&gt;
&lt;p&gt;4-bit input, 5-bit output binary adder I built in high school. Logic gates are formed from ~70 television transistors using my own direct implementation of boolean&amp;nbsp;logic.&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Ryan Witt</dc:creator><pubDate>Thu, 11 Aug 2011 14:11:33 -0400</pubDate><guid isPermaLink="false">tag:ryan.sh,2011-08-11:2011/08/11/bit-input-5-bit-output-binary-adder-i-built-in/</guid></item><item><title>Colbert’s Stephensed Soup</title><link>http://ryan.sh/2011/07/22/colberts-stephensed-soup-washington-square-park/</link><description>&lt;p&gt;&lt;img alt="" src="http://ryan.sh/2011/07/22/colberts-stephensed-soup-washington-square-park/soup.png" /&gt;&lt;/p&gt;
&lt;p&gt;Colbert&amp;#8217;s Stephensed Soup (Washington Square&amp;nbsp;Park)&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Ryan Witt</dc:creator><pubDate>Fri, 22 Jul 2011 18:13:44 -0400</pubDate><guid isPermaLink="false">tag:ryan.sh,2011-07-22:2011/07/22/colberts-stephensed-soup-washington-square-park/</guid></item><item><title>Spock, rationality and reasons for Truth</title><link>http://ryan.sh/2010/08/04/spock-rationality-and-reasons-for-truth/</link><description>&lt;blockquote&gt;
&lt;p&gt;Spock’s emotional state is always set to “calm”, even when wildly inappropriate.  He often gives many significant digits for probabilities that are grossly uncalibrated.  (E.g:  “Captain, if you steer the Enterprise directly into that black hole, our probability of surviving is only 2.234%”  Yet nine times out of ten the Enterprise is not destroyed.  What kind of tragic fool gives four significant digits for a figure that is off by two orders of magnitude?)  Yet this popular image is how many people conceive of the duty to be “rational” - small wonder that they do not embrace it&amp;nbsp;wholeheartedly.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Just a sample of the amazing facility for instance possessed by Eliezer Yudkowski, a self-taught &lt;span class="caps"&gt;AI&lt;/span&gt; researcher and guy behind &lt;a href="http://www.fanfiction.net/s/5782108/1/Harry_Potter_and_the_Methods_of_Rationality"&gt;Harry Potter and the Methods of Rationality&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;ve been slowly working my way through his writing over the past few months and can&amp;#8217;t recommend him&amp;nbsp;enough.&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Ryan Witt</dc:creator><pubDate>Wed, 04 Aug 2010 20:56:02 -0400</pubDate><guid isPermaLink="false">tag:ryan.sh,2010-08-04:2010/08/04/spock-rationality-and-reasons-for-truth/</guid><category>philosophy</category><category>rationality</category><category>link</category></item><item><title>Which loads faster?</title><link>http://ryan.sh/2010/07/07/announcing-whichloadsfaster/</link><description>&lt;p&gt;I&amp;#8217;m pleased as punch to announce &lt;a href="http://whichloadsfaster.com/"&gt;whichloadsfaster.com&lt;/a&gt;, an &lt;a href="http://github.com/ryanwitt/whichloadsfaster/"&gt;open-source&lt;/a&gt; web performance tool where pages compete head-to-head in your browser to see who&amp;#8217;s&amp;nbsp;fastest!&lt;/p&gt;
&lt;p&gt;&lt;a href="http://whichloadsfaster.com"&gt;
&lt;img title="Which loads faster?" src="http://farm5.static.flickr.com/4097/4770008437_2318faf48e.jpg"&gt;
&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;It started as an off-hand remark by my buddy, Ricardo: &amp;#8220;You should make a tool that can load two web pages side by side so you can see which one loads faster.&amp;#8221; I backpedaled a little at first, the way an overworked programmer does when someone suggests sticking another iron in the fire: &amp;#8220;Um, I don&amp;#8217;t know if that would really work out without writing a browser plugin.&amp;#8221; This, of course, meant something more like, &amp;#8220;Dude, I&amp;#8217;m lazy, and that sounds like a lot of work just to make another toy for our sales and marketing&amp;nbsp;guys.&amp;#8221;&lt;/p&gt;
&lt;p&gt;Ricardo had me though, it &lt;em&gt;would&lt;/em&gt; be cool to load two pages side-by-side and see the differences in real time. Dan, one of the aforementioned sales and marketing guys, was grinning next to us, enthused in an infectious way we hadn&amp;#8217;t seen nearly enough of since the arrival of his newborn. &amp;#8220;Ok guys,&amp;#8221; I entreated, &amp;#8220;maybe we can do it with iframes. I&amp;#8217;ve been having a lot of fun with &lt;a href="http://jquery.com/"&gt;jQuery&lt;/a&gt; lately, so let me play around with it and see what I come up&amp;nbsp;with.&amp;#8221;&lt;/p&gt;
&lt;p&gt;&lt;a href="http://whichloadsfaster.com/?l=google.com&amp;r=duckduckgo.com"&gt;
&lt;img title="Have you ever used duckduckgo?" src="http://farm5.static.flickr.com/4142/4770771630_b8cc3c511f.jpg" /&gt;
&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;It &lt;em&gt;was&lt;/em&gt; a lot of fun to see two pages race against each other! Performance testing can be rather bland&amp;#8212;staring at waterfalls, repeating tests&amp;#8212;but watching a competition seems to be one of those things that humans are hard-wired to enjoy, and it tickled me like Elmo to think that I could take something I&amp;#8217;m &lt;a href="http://doeswebperformancematter.com/"&gt;passionate&lt;/a&gt; about&amp;#8212;web performance&amp;#8212;and make it a bit more&amp;nbsp;appealing!&lt;/p&gt;
&lt;p&gt;Don&amp;#8217;t get me wrong, there are many &lt;a href="http://www.webpagetest.org/forums/showthread.php?tid=12"&gt;good tools&lt;/a&gt; for web performance testing (notably, the open source &lt;a href="http://webpagetest.org"&gt;webpagetest.org&lt;/a&gt; and &lt;a href="http://showslow.com"&gt;showslow.com&lt;/a&gt;, which I will be working to integrate), but there are a few areas where I think whichloadsfaster adds some wicked weapons to the web performance&amp;nbsp;warchest:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Competition. Since it&amp;#8217;s easy to pit pages against each other, it becomes natural to check the performance of your most (and least) favorite sites, adding to the argument that &lt;a href="http://www.stevesouders.com/blog/2010/05/07/wpo-web-performance-optimization/"&gt;speed is a competitive advantage&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Testing in real time, while you watch. This has a big impact factor because a &amp;#8220;real&amp;#8221; test holds your&amp;nbsp;attention.&lt;/li&gt;
&lt;li&gt;Support for many browsers (&lt;span class="caps"&gt;IE&lt;/span&gt; 8/7/6, Firefox 3.0+, Chrome, Safari, most of mobile WebKit). Because of the detailed and invasive nature of performance testing, most performance tools are browser-specific. We make the tradeoff of collecting fewer events for the convenience of running the tool in every browser with no&amp;nbsp;install.&lt;/li&gt;
&lt;li&gt;Finally, there is a sharing link that developers can send out to run on their friends&amp;#8217; browsers. This feature is something I hope to develop further by adding a beacon &lt;span class="caps"&gt;API&lt;/span&gt; to automatically retrieve the results (see&amp;nbsp;below).&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;a href="http://whichloadsfaster.com/?l=google.com&amp;r=bing.com"&gt;
&lt;img title="Bing is often faster for me on Firefox" src="http://farm5.static.flickr.com/4115/4772157060_ea6eaa134c.jpg"/&gt;
&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Moving forward, I would like to improve whichloadsfaster in three major&amp;nbsp;areas:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Automation of test results. The &lt;a href="http://github.com/ryanwitt/whichloadsfaster/issues#issue/3"&gt;plan&lt;/a&gt; is to make a beacon &lt;span class="caps"&gt;API&lt;/span&gt; and a couple of example servers to collect the data (php, rails, django). This way, developers can just send out the link and sit back and see their performance results roll in across different locations and browsers. Fully automated testing would be as simple as causing a remote test machine to load the &lt;span class="caps"&gt;URL&lt;/span&gt; you want with your desired browser. This could be done with &lt;a href="http://seleniumhq.org/"&gt;selenium&lt;/a&gt; or a similar library, or possibly even built into whichloadsfaster (have to work around caching&amp;nbsp;issues).&lt;/li&gt;
&lt;li&gt;User perception testing. Since we&amp;#8217;re right in front of the user, we can ask them which page &lt;em&gt;appeared&lt;/em&gt; to load faster and get a better handle on that ephemeral but most important metric, &lt;a href="http://assets.en.oreilly.com/1/event/44/Building%20Performance%20Into%20the%20New%20Yahoo_%20Homepage%20Presentation.pdf"&gt;time to first interaction&lt;/a&gt;. I&amp;#8217;m &lt;a href="http://github.com/ryanwitt/whichloadsfaster/issues#issue/2"&gt;really excited&lt;/a&gt; about this&amp;nbsp;one! &lt;/li&gt;
&lt;li&gt;Integration with other tools. I plan to add a link to compare your pages on webpagetest.org using the video film strip feature, and also to test the individual pages in the waterfall tool. Since this project is about spreading the web performance gospel, I&amp;#8217;m open to linking to any useful performance&amp;nbsp;tool.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;A call for&amp;nbsp;help&lt;/h2&gt;
&lt;p&gt;The one problem that really bugs me is that whichloadsfaster &lt;a href="http://whichloadsfaster.com/?l=nytimes.com&amp;amp;r=myspace.com"&gt;doesn&amp;#8217;t play well&lt;/a&gt; with sites that try to break out of the iframe. This includes major sites that users want to compare, like myspace, twitter and nytimes.com. It&amp;#8217;s a terrible user experience to type in one of these and watch it unexpectedly take over the screen. I&amp;#8217;m completely sympathetic with using &lt;a href="http://seclab.stanford.edu/websec/framebusting/"&gt;framebusting&lt;/a&gt; to avoid clickjacking attacks, but I truly think this project is a legitimate reason to frame a site, and I want to create an excellent user experience (I mean, have you noticed the keyboard&amp;nbsp;shortcuts?). &lt;/p&gt;
&lt;p&gt;I&amp;#8217;ve successfully tested a framebuster-buster that prevents sites from breaking out, but one of the side effects is that it also prevents outgoing links. In the end, the users should at least know what is going on and why the site can&amp;#8217;t be compared. I&amp;#8217;ll continue to work on this, but if you or a developer you know has expertise in this area, I would love suggestions and advice via &lt;a href="mailto:onecreativenerd@gmail.com"&gt;email&lt;/a&gt; or the &lt;a href="http://github.com/ryanwitt/whichloadsfaster/issues#issue/1"&gt;github issue&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Thanks for your &lt;a href="http://groups.google.com/group/whichloadsfaster/"&gt;feedback&lt;/a&gt; and &lt;a href="http://github.com/ryanwitt/whichloadsfaster/"&gt;involvement&lt;/a&gt;. Here&amp;#8217;s to making the web &lt;em&gt;just work&lt;/em&gt; for everybody on the&amp;nbsp;planet!&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Ryan Witt</dc:creator><pubDate>Wed, 07 Jul 2010 14:58:00 -0400</pubDate><guid isPermaLink="false">tag:ryan.sh,2010-07-07:2010/07/07/announcing-whichloadsfaster/</guid><category>code</category></item><item><title>Flying Leaf</title><link>http://ryan.sh/2010/07/04/flying-leaf/</link><description>&lt;p&gt;&lt;img alt="" src="http://ryan.sh/2010/07/04/flying-leaf/flying-leaf.jpg" /&gt;&lt;/p&gt;
&lt;p&gt;On our walk today we met a flying leaf dancing in the wind, always one inch from the&amp;nbsp;ground.&lt;/p&gt;
&lt;p&gt;Of all the altitudes it could have occupied, it seemed to have choosen one inch, where it bobbed and twirled for our amusement at the end of an invisible spider&amp;nbsp;silk.&lt;/p&gt;
&lt;p&gt;That I find the actions of the leaf profound, that its pirouettes dazzle me despite my mind&amp;#8217;s prediction of the presence of the silk and despite the unsurprising confirmation when I strain my eyes to see it against a darkened patch beyond, that I both awe and understand&amp;#8212;that is the great joy of being&amp;nbsp;human.&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Ryan Witt</dc:creator><pubDate>Sun, 04 Jul 2010 16:00:17 -0400</pubDate><guid isPermaLink="false">tag:ryan.sh,2010-07-04:2010/07/04/flying-leaf/</guid><category>photo</category><category>poetry</category></item><item><title>Homemade iPad Case</title><link>http://ryan.sh/2010/05/12/homemade-ipad-case/</link><description>&lt;p&gt;A few days ago I popped into the &lt;a href="http://www.apple.com/retail/pasadena/"&gt;Pasadena Apple Store&lt;/a&gt; to look at iPad cases. I had &lt;em&gt;thought&lt;/em&gt; that my requirements were fairly simple: a landscape slipcase with easy iPad insertion/removal that can itself be easily moved in and out of my bag. Everything at the store, however, seemed bulky, expensive and&amp;nbsp;inelegant. &lt;/p&gt;
&lt;p&gt;His spidey sense tingling at my obvious indecision (or perhaps just tickled by his curly beard), an impetuously precocious Apple employee approached. His admonition, however, was not one I expected: &amp;#8220;now, nobody from &lt;em&gt;Apple&lt;/em&gt; is telling you this, but if I were you, I&amp;#8217;d &lt;a href="http://www.etsy.com/search_results.php?search_query=ipad+case&amp;amp;search_type=handmade&amp;amp;ref=auto"&gt;go to etsy&lt;/a&gt; and buy a handmade case instead.&amp;#8221; Cue my white liberal guilt.&lt;sup&gt;&lt;a name="homemade-ipad-case-fn1-a" href="#homemade-ipad-case-fn1"&gt;1&lt;/a&gt;&lt;/sup&gt; Being thus rendered unable to feel good about buying yet another petroleum-derived consumer product made by underpaid workers in the third world, I decided to make my own&amp;nbsp;case.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.flickr.com/photos/twocreativenerds/4592663957/" title="finished product"&gt;&lt;img src="http://farm5.static.flickr.com/4008/4592663957_cd2886ba35.jpg" width="500" height="375" alt="finished product" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;To be fair, the case is made from &lt;a href="http://www.flickr.com/photos/twocreativenerds/4593525930/in/set-72157623902162655/"&gt;vegetarian leather&lt;/a&gt;, which is still petroleum-derived&lt;sup&gt;&lt;a name="homemade-ipad-case-fn2-a" href="#homemade-ipad-case-fn2"&gt;2&lt;/a&gt;&lt;/sup&gt;, but I rescued the material from a doomed college project &lt;sup&gt;&lt;a name="homemade-ipad-case-fn3-a" href="#homemade-ipad-case-fn3"&gt;3&lt;/a&gt;&lt;/sup&gt; so I think it technically constitutes&amp;nbsp;recycling.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.flickr.com/photos/twocreativenerds/4593285468/" title="soft and fuzzy inside!"&gt;&lt;img src="http://farm4.static.flickr.com/3381/4593285468_1835cf3bd5.jpg" width="500" height="375" alt="soft and fuzzy inside!" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The inside of the case is made from &lt;a href="http://www.flickr.com/photos/twocreativenerds/4593527354/in/set-72157623902162655/"&gt;car headliner fabric&lt;/a&gt;. You know, the kind that you used to get yelled at for picking off the roof of your parents&amp;#8217; Plymouth Volare? No? Was that just&amp;nbsp;me?&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.flickr.com/photos/twocreativenerds/4593526630/" title="two pieces of fabric"&gt;&lt;img src="http://farm5.static.flickr.com/4027/4593526630_88136eb63e.jpg" width="500" height="375" alt="two pieces of fabric" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The entire case is made from two pieces of fabric, folded onto itself in various ways. All edges had to be folded over twice because the veggie leather is backed with fuzzy white stuff which doesn&amp;#8217;t look good when it&amp;#8217;s exposed. The exact dimensions are a closely guarded secret &lt;sup&gt;&lt;a name="homemade-ipad-case-fn4-a" href="#homemade-ipad-case-fn4"&gt;4&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.flickr.com/photos/twocreativenerds/4592908187/" title="sewing seams"&gt;&lt;img src="http://farm2.static.flickr.com/1402/4592908187_a0b56a5463.jpg" width="500" height="375" alt="sewing seams" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Seams were sewn on a &lt;a href="http://blog.sew-classic.com/2009/03/14/classic-singer-301-301a-vintage-sewing-machine-review.aspx"&gt;Singer 301a&lt;/a&gt; that belonged to my late grandmother. I&amp;#8217;m afraid I have a long way to go in learning how to &lt;a href="http://static.onecreativeblog.com/files/singer-301-manual.pdf"&gt;use it properly&lt;/a&gt;, but I hope my attempt would have made her&amp;nbsp;proud.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.flickr.com/photos/twocreativenerds/4593528546/" title="scotch tape ftw"&gt;&lt;img src="http://farm2.static.flickr.com/1100/4593528546_d7bd1d415b.jpg" width="375" height="500" alt="IMG_3183" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Using scotch tape along the seams really helped the machine glide along without bunching the material. The tape can be removed afterward by carefully pulling perpendicular to the seam, otherwise you end up with a bunch of small tape pieces that must be pulled out from under the thread by&amp;nbsp;hand.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.flickr.com/photos/twocreativenerds/4598552485/" title="train buddy"&gt;&lt;img src="http://farm5.static.flickr.com/4051/4598552485_dbd787d332.jpg" width="500" height="375" alt="train buddy" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The finished case works nicely for propping the iPad up while typing on the&amp;nbsp;train. &lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.flickr.com/photos/twocreativenerds/4592664573/" title="ample posterior"&gt;&lt;img src="http://farm4.static.flickr.com/3551/4592664573_2e27c8a3b7.jpg" width="500" height="375" alt="ample posterior" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I enjoyed this project &lt;em&gt;immensely&lt;/em&gt;. It was a real kick to make something I&amp;#8217;ve never attempted before from materials that were lying around. Hope you enjoyed it&amp;nbsp;too!&lt;/p&gt;
&lt;p&gt;More pictures and comments can be found at this project&amp;#8217;s &lt;a href="http://www.flickr.com/photos/twocreativenerds/sets/72157623902162655/"&gt;flickr set &amp;rarr;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Oh, and to my bearded muse in the bright turquoise t-shirt, if you&amp;#8217;re reading this and still haven&amp;#8217;t made up your mind about your own case, I&amp;#8217;ll totally make you one of&amp;nbsp;these.&lt;/p&gt;
&lt;div class="footnotes"&gt;
&lt;table&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a name="homemade-ipad-case-fn1"&gt;&lt;/a&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/td&gt;
&lt;td&gt;While I am white, I&amp;#8217;m not as &lt;i&gt;that&lt;/i&gt; liberal and harbor virtually no guilt. &lt;a href="#homemade-ipad-case-fn1-a"&gt; &amp;#8617;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a name="homemade-ipad-case-fn2"&gt;&lt;/a&gt;&lt;sup&gt;2&lt;/sup&gt;&lt;/td&gt;
&lt;td&gt;Which means it&amp;#8217;s made from animals that died naturally a long time ago, rather than recently by human hands. &lt;a href="#homemade-ipad-case-fn2-a"&gt; &amp;#8617;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a name="homemade-ipad-case-fn3"&gt;&lt;/a&gt;&lt;sup&gt;3&lt;/sup&gt;
&lt;td&gt;I was trying to make a folding poker table with a nice felt surface and leather border. Then someone stole all the wood pieces I had cut along with the brass hardware. Sad face. &lt;a href="#homemade-ipad-case-fn3-a"&gt; &amp;#8617;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a name="homemade-ipad-case-fn4"&gt;&lt;/a&gt;&lt;sup&gt;4&lt;/sup&gt;
&lt;td&gt;Meaning they were pulled directly from my posterior region and I might not be able to reproduce them if I wanted to. &lt;a href="#homemade-ipad-case-fn4-a"&gt; &amp;#8617;&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/div&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Ryan Witt</dc:creator><pubDate>Wed, 12 May 2010 00:11:21 -0400</pubDate><guid isPermaLink="false">tag:ryan.sh,2010-05-12:2010/05/12/homemade-ipad-case/</guid><category>article</category></item><item><title>Homemade turkey burgers with spinach, mushrooms and brie</title><link>http://ryan.sh/2010/05/07/homemade-turkey-burgers-with-spinach-mushroom-and-brie/</link><description>&lt;p&gt;&lt;img alt="" src="http://ryan.sh/2010/05/07/homemade-turkey-burgers-with-spinach-mushroom-and-brie/turkey-burgers.jpg" /&gt;&lt;/p&gt;
&lt;p&gt;Homemade turkey burgers with spinach, mushrooms and&amp;nbsp;brie.&lt;/p&gt;
&lt;p&gt;To make the patties, I used a 1lb package Trader Joe&amp;#8217;s ground turkey, 1/4 cup diced garlic, 1/4 cup diced white onion, 1/4 cup soft brie, and maybe a couple teaspoons of salt. I mixed all the ingredients together by hand, formed them into 4 patties and floured the outside to keep them from sticking to each other on the&amp;nbsp;plate.&lt;/p&gt;
&lt;p&gt;When the patties were almost done, I divided the remaining brie among them and let it melt slightly on top. Try to keep the brie from spilling over the edge of the patties! The mushrooms were sautéd separately in olive oil and laid atop the&amp;nbsp;brie.&lt;/p&gt;
&lt;p&gt;What would I do differently next time? Probably Worcestershire sauce &lt;em&gt;in&lt;/em&gt; the&amp;nbsp;patties.&lt;/p&gt;
&lt;p&gt;As it was, they were very&amp;nbsp;good.&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Ryan Witt</dc:creator><pubDate>Fri, 07 May 2010 21:00:48 -0400</pubDate><guid isPermaLink="false">tag:ryan.sh,2010-05-07:2010/05/07/homemade-turkey-burgers-with-spinach-mushroom-and-brie/</guid><category>photo</category><category>food</category></item><item><title>MacGyver’ed iBook Repair</title><link>http://ryan.sh/2010/05/05/macgyver-ibook-repair/</link><description>&lt;p&gt;&lt;img alt="" src="http://ryan.sh/2010/05/05/macgyver-ibook-repair/ibook-repair.jpg" /&gt;&lt;/p&gt;
&lt;p&gt;MacGyver&amp;#8217;ed rig for epoxying the power button connector back onto my friend&amp;#8217;s iBook G4 on which I was &lt;em&gt;trying&lt;/em&gt; to simply replace the hard&amp;nbsp;drive.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;span class="caps"&gt;UPDATE&lt;/span&gt;:&lt;/em&gt; It worked! I managed to press the contacts to the board hard enough during curing that they still had conductivity after the epoxy&amp;nbsp;cured! &lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="http://ryan.sh/2010/05/05/macgyver-ibook-repair/ibook-repair-2.jpg" /&gt;&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Ryan Witt</dc:creator><pubDate>Wed, 05 May 2010 03:13:00 -0400</pubDate><guid isPermaLink="false">tag:ryan.sh,2010-05-05:2010/05/05/macgyver-ibook-repair/</guid><category>photo</category></item><item><title>Steam Cars</title><link>http://ryan.sh/2010/05/02/steam-cars/</link><description>&lt;p&gt;A couple Saturdays ago, &lt;a href="http://twitter.com/kriskowal"&gt;@kriskowal&lt;/a&gt; and I found ourselves at a meeting of the Southern California chapter of the &lt;a href="http://www.steamautomobile.com/lcc/index.htm"&gt;Steam Automobile Club of America&lt;/a&gt; of which Kris&amp;#8217;s father is president. It&amp;#8217;s been a long while since I&amp;#8217;ve seen these steam cars in action. Getting to ride on these gentle and majestic contraptions was a real&amp;nbsp;treat:&lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="http://farm3.static.flickr.com/2791/4521104369_68f75c62cd_d.jpg" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="http://farm5.static.flickr.com/4069/4521739960_d89a427b46_d.jpg" /&gt;&lt;/p&gt;
&lt;p&gt;Kris&amp;#8217;s father brought the &lt;em&gt;Dampf &amp;#8216;Bil&lt;/em&gt;, a wood-burning, steam powered go-kart of&amp;nbsp;sorts:&lt;/p&gt;
&lt;p&gt;&lt;img alt="Dampf 'Bil" src="http://farm5.static.flickr.com/4056/4520967851_1d74ddda00_d.jpg" /&gt;&lt;/p&gt;
&lt;p&gt;Kris explains more about how it&amp;nbsp;works:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;It&amp;#8217;s a really simple car, a model of the minimal steam powered automobile, built on the chassis of a wood trash-cart.  The steam generator is a Dixon Boilerworks &amp;#8220;fire tube&amp;#8221; boiler; it burns wood under a five gallon reservoir with tubes that allow the heated air to exchange with the water.  It operates between 40 and 75 &lt;span class="caps"&gt;PSI&lt;/span&gt;.  The steam drives two 5&amp;#8221; tall double-acting steam engines, offset by 90 degrees, attached directly to the rear-right wheel with a bike chain (no derailleur).  The boiler is fed by a highly ineffective hydraulic landing gear pump from a 2 gallon antifreeze container repurposed for water.  The boiler also has a garden hose attachment which we use to fill the boiler when cold, and to &amp;#8220;blow down&amp;#8221;: use the boiler&amp;#8217;s remaining pressure to empty the&amp;nbsp;boiler.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Look at it go! (that&amp;#8217;s me&amp;nbsp;riding.)&lt;/p&gt;
&lt;p&gt;&lt;embed height="507" src="http://video.google.com/googleplayer.swf?videoUrl=http%3A%2F%2Fv6.nonxt6.googlevideo.com%2Fvideoplayback%3Fid%3D71b008b26d93d7b9%26itag%3D5%26begin%3D0%26len%3D2147483647%26app%3Dpicasa%26et%3DINVALID%26el%3DINVALID%26ip%3D0.0.0.0%26ipbits%3D0%26expire%3D2848073554%26sparams%3Did%252Citag%252Cip%252Cipbits%252Cexpire%26signature%3D2DE2F8D6F1DDF2475294261C3E762F609D30AFB.62768AC1BB7752D899976AD35526FD24B97E5A89%26key%3Dck1&amp;amp;hl=en&amp;amp;messagesUrl=http%3A%2F%2Fvideo.google.com%2FFlashUiStrings.xlb%3Fframe%3Dflashstrings%26hl%3Den&amp;amp;speedcontrol=0" type="application/futuresplash" width="500" flashvars="fs=true&amp;amp;playerMode=normal" allowfullscreen="true" allowscriptaccess="always" bgcolor="#fff" quality="best" salign="TL" scale="noScale" swliveconnect="true" wmode="opaque" style="width: 500px; height: 396px; "&gt;&lt;/p&gt;
&lt;p&gt;The only problem is that one tends to get covered in soot while driving it (that&amp;#8217;s&amp;nbsp;Kris):&lt;/p&gt;
&lt;p&gt;&lt;img alt="Kris covered in soot" src="http://farm5.static.flickr.com/4061/4520968797_e10a8f8b4a_d.jpg" /&gt;&lt;/p&gt;
&lt;p&gt;As you can see, fun was had by all.&amp;nbsp;:)&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Ryan Witt</dc:creator><pubDate>Sun, 02 May 2010 19:26:00 -0400</pubDate><guid isPermaLink="false">tag:ryan.sh,2010-05-02:2010/05/02/steam-cars/</guid><category>article</category></item><item><title>Caprese Burger Trifecta</title><link>http://ryan.sh/2010/04/15/caprese-burger-trifecta/</link><description>&lt;p&gt;&lt;img alt="" src="http://ryan.sh/2010/04/15/caprese-burger-trifecta/caprese-burger.jpg" /&gt;&lt;/p&gt;
&lt;p&gt;Caprese burgers, mashed red potatoes and green&amp;nbsp;beans!&lt;/p&gt;
&lt;p&gt;The burgers patties are made from about 2 lbs. of 90/10 lean ground beef, plus 1/4 large white onion (I might use red or sweet next time), 2 cloves of garlic, 4 oz. of mozzarella cheese (all diced) and a couple teaspoons of&amp;nbsp;salt.&lt;/p&gt;
&lt;p&gt;Atop the patties are slabs of soft mozzarella cheese (the kind you make &lt;a href="http://en.wikipedia.org/wiki/Insalata_Caprese"&gt;caprese&lt;/a&gt; with) topped with balsamic vinegar while grilling. On top of that are slices of red bell pepper pressed into the cheese (totally cheated on the caprese here, they should be tomatoes) and basil&amp;nbsp;leaves.&lt;/p&gt;
&lt;p&gt;12 California Red potatoes (from a large bag at Costco) make up the potato salad, along with 1 stick of butter, 1/2 a cup half and half and salt&amp;#8212;decadent, I know, but very tasty. We&amp;#8217;ve been doing mashed potatoes in the pressure cooker. It&amp;#8217;s faster at cooking the potatoes, and for added bonus, the steam relief valve popping cues you to turn the stove off (helpful for the&amp;nbsp;multitasking-challenged).&lt;/p&gt;
&lt;p&gt;I don&amp;#8217;t normally have the energy to make three dishes on a weeknight, but tonight I felt up to the multitasking challenge. The results were happily&amp;nbsp;nominated.&lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="http://ryan.sh/2010/04/15/caprese-burger-trifecta/caprese-burger-2.jpg" /&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;&lt;span class="caps"&gt;UPDATE&lt;/span&gt;:&lt;/b&gt; I made some more caprese burgers last night with the addition of ~1/4 cup balsamic vinegar to the patties. I &lt;i&gt;highly&lt;/i&gt; recommend&amp;nbsp;it!&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Ryan Witt</dc:creator><pubDate>Thu, 15 Apr 2010 02:30:00 -0400</pubDate><guid isPermaLink="false">tag:ryan.sh,2010-04-15:2010/04/15/caprese-burger-trifecta/</guid><category>food</category><category>photo</category></item><item><title>MMM… Gyros</title><link>http://ryan.sh/2010/04/08/mmm-gyros/</link><description>&lt;p&gt;&lt;img alt="" src="http://ryan.sh/2010/04/08/mmm-gyros/gyros.jpg" /&gt;&lt;/p&gt;
&lt;p&gt;In case you were wondering where all the leftover Easter lamb went: Gyros! Well, my take on them&amp;nbsp;anyway.&lt;/p&gt;
&lt;p&gt;I started with a good amount of minced garlic and chopped red onions sauteed in olive oil, then added the sliced lamb and cubed roma tomatoes (on the vine, from Costco), added some flake salt and ground peppercorns over the pan. The bread is nothing special, just from Trader Joe&amp;#8217;s, but the green stuff is &lt;a href="http://www.npr.org/templates/story/story.php?storyId=1370492"&gt;mâche or &amp;#8220;lamb&amp;#8217;s lettuce&amp;#8221;&lt;/a&gt; (also from &lt;span class="caps"&gt;TJ&lt;/span&gt;&amp;#8217;s) and is quite tasty, like a light, nutty spinach. Topping off the ensemble is some Greek&amp;nbsp;yogurt.&lt;/p&gt;
&lt;p&gt;They turned out quite&amp;nbsp;well.&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Ryan Witt</dc:creator><pubDate>Thu, 08 Apr 2010 13:33:18 -0400</pubDate><guid isPermaLink="false">tag:ryan.sh,2010-04-08:2010/04/08/mmm-gyros/</guid><category>food</category><category>photo</category></item><item><title>Easter Dinner</title><link>http://ryan.sh/2010/04/08/easter-dinner/</link><description>&lt;p&gt;Lamb by yours truly. Potatoes by @ErikDreyer and Diana. Salad by @jasonyo and &lt;span class="caps"&gt;SJ&lt;/span&gt;. Asparagus by steam&amp;nbsp;pot.&lt;/p&gt;
&lt;p&gt;&lt;img alt="" src="http://ryan.sh/2010/04/08/easter-dinner/easter-dinner.jpg" /&gt;&lt;/p&gt;
&lt;p&gt;The salad contained spinach, pears, medium-boiled eggs and from-scratch candied walnuts! It was quite a hit. The potatoes had tons of garlic, and complimented the lamb very&amp;nbsp;nicely.&lt;/p&gt;
&lt;p&gt;The lamb is from an &lt;a href="http://www.epicurious.com/recipes/food/views/Grilled-Leg-of-Lamb-with-Rosemary-Garlic-and-Mustard-358196"&gt;epicurious recipie&lt;/a&gt; that I followed pretty closely. We started with two lamb legs from Costco totaling about 8 pounds of meat after trimming the excess fat. I tucked substantially more garlic into the meat than recommended&amp;#8212;approximately 8 cloves cut into about 32 slices&amp;#8212;and let the prepared meat marinate&amp;nbsp;overnight.&lt;/p&gt;
&lt;p&gt;Cooking was done on the propane grill, and turned out to be the biggest disappointment of the meal (at least to me) because although the flavor was great, the smaller pieces of lamb were overcooked. I had the thermometer in one of the larger pieces and cut the heat when the middle of the largest one reached 145&amp;deg;F. In hindsight, I should have measured each piece and pulled it from the heat when it reached 130&amp;deg;F, as recommended by the recipe. Oh well, one of the main reasons to write this down is so I can remember what I did wrong. Aren&amp;#8217;t you glad we live in a world where we can google our past&amp;nbsp;misteaks?&lt;/p&gt;
&lt;p&gt;&amp;#8230;&lt;/p&gt;
&lt;p&gt;You may have noticed the topic of my site inching insidiously toward food. To tell you the truth, I&amp;#8217;m just as surprised as you are. I mean, I&amp;#8217;m supposed to be writing about programming, poetry and bad puns, but I end up taking pictures of dinner&amp;nbsp;instead. &lt;/p&gt;
&lt;p&gt;Well, them&amp;#8217;s tough beans (fava maybe? Haven&amp;#8217;t attempted those yet). The &lt;a href="/tagged/food"&gt;food posts&lt;/a&gt; will likely continue as I have no plans to imperil my excellent relationship with eaten things anytime&amp;nbsp;soon.&lt;/p&gt;
&lt;p&gt;Stay tuned for a large flickr set of food-themed photos! Also expect some posts about my new &lt;a href="http://onecreativeblog.com/post/492168809/espresso-machine-is-here"&gt;espresso machine&lt;/a&gt; as I continue my relentless pursuit of the &lt;a href="http://coffeegeek.com/opinions/coffeeatthemoment/11-12-2002"&gt;god shot&lt;/a&gt;.&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Ryan Witt</dc:creator><pubDate>Thu, 08 Apr 2010 01:01:00 -0400</pubDate><guid isPermaLink="false">tag:ryan.sh,2010-04-08:2010/04/08/easter-dinner/</guid><category>food</category><category>espresso</category></item><item><title>Mile High Pizza</title><link>http://ryan.sh/2010/04/06/mile-high-pizza/</link><description>&lt;p&gt;&lt;img alt="" src="http://ryan.sh/2010/04/06/mile-high-pizza/pizza.jpg" /&gt;&lt;/p&gt;
&lt;p&gt;Pizza according to my wife&amp;#8217;s philosophy: &amp;#8220;if u c sauce under toppingz, ur doin it rong!&amp;#8221; Apologies to Lynne Rossetto&amp;nbsp;Kasper.&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Ryan Witt</dc:creator><pubDate>Tue, 06 Apr 2010 21:00:42 -0400</pubDate><guid isPermaLink="false">tag:ryan.sh,2010-04-06:2010/04/06/mile-high-pizza/</guid><category>photo</category><category>food</category></item><item><title>Espresso Machine</title><link>http://ryan.sh/2010/04/02/espresso-machine-is-here/</link><description>&lt;p&gt;&lt;img alt="" src="http://ryan.sh/2010/04/02/espresso-machine-is-here/espresso-machine.jpg" /&gt;&lt;/p&gt;
&lt;p&gt;The espresso machine is back from the shop! I fully expect the productivity @fastsoft to double in the next few&amp;nbsp;days.&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Ryan Witt</dc:creator><pubDate>Fri, 02 Apr 2010 21:00:00 -0400</pubDate><guid isPermaLink="false">tag:ryan.sh,2010-04-02:2010/04/02/espresso-machine-is-here/</guid><category>photo</category><category>espresso</category></item><item><title>If You Think You Need Some Lovin’</title><link>http://ryan.sh/2010/03/14/pomplamoose/</link><description>&lt;p&gt;Pomplamoose is a band containing Nataly Dawn and Jack Conte. I think I have a crush on&amp;nbsp;them.&lt;/p&gt;
&lt;iframe width="500" height="281"  id="youtube_iframe" src="https://www.youtube.com/embed/z9KMgg7T_sg?feature=oembed&amp;amp;enablejsapi=1&amp;amp;origin=http://safe.txmblr.com&amp;amp;wmode=opaque" frameborder="0" allowfullscreen&gt;&lt;/iframe&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Ryan Witt</dc:creator><pubDate>Sun, 14 Mar 2010 17:27:00 -0400</pubDate><guid isPermaLink="false">tag:ryan.sh,2010-03-14:2010/03/14/pomplamoose/</guid></item><item><title>Vim Tips and Tricks</title><link>http://ryan.sh/2010/02/16/fastsoft-vim-speedup/</link><description>&lt;p&gt;The FastSoft engineers often give presentations to bring each-other up to date on technical issues. These presentations are appropriately called &amp;#8220;speedups&amp;#8221; (get it? fastsoft? speedups? har har). This speedup, given by &lt;a href="https://twitter.com/kriskowal"&gt;@kriskowal&lt;/a&gt;, is a tricks and tips discussion on his favorite editor,&amp;nbsp;vim.&lt;/p&gt;
&lt;p&gt;&lt;span class="dquo"&gt;&amp;#8220;&lt;/span&gt;Slides&amp;#8221; for this&amp;nbsp;presentation:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;^w hjkl move to windows

^w HJKL move windows

^w +- horizontal resize
^w = even splits
^w10&amp;amp;lt;&amp;amp;gt; vertical resize

O
I  ia  A
o

gg
0     ^      $
G

{
}

:!

   /----------------------\
   |:e :e# :vs :sp ^w hjkl|
   |:e :e# :vs :sp ^w hjkl|
   |:e :e# :vs :sp ^w hjkl|
   |:e :e# :vs :sp ^w hjkl|
   \----------------------/

:n :N

Vv^V o
&amp;amp;gt;&amp;amp;gt; &amp;amp;lt;&amp;amp;lt;
=
:set et sw ts
:!expand unexpand
gq
:set ve=all
comment/uncomment
:set incsearch n N
:noh
:set tw

highlight OverLength ctermbg=red ctermfg=white guibg=red guifg=white
match OverLength &amp;#39;\%78v.*&amp;#39;

:set modeline
:set wrap lbr number
/ n .
&lt;/pre&gt;&lt;/div&gt;


&lt;iframe src="https://player.vimeo.com/video/9474607?title=0&amp;byline=0&amp;portrait=0" width="500" height="281" frameborder="0" title="FastSoft Vim Tips and Tricks Discussion" webkitallowfullscreen mozallowfullscreen allowfullscreen&gt;&lt;/iframe&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Ryan Witt</dc:creator><pubDate>Tue, 16 Feb 2010 12:28:00 -0500</pubDate><guid isPermaLink="false">tag:ryan.sh,2010-02-16:2010/02/16/fastsoft-vim-speedup/</guid><category>discussion</category><category>fastsoft</category><category>speedup</category><category>vim</category><category>code</category></item><item><title>Funny Tree</title><link>http://ryan.sh/2010/02/13/awesome-tree-says-happy-new-year/</link><description>&lt;p&gt;&lt;img alt="" src="http://ryan.sh/2010/02/13/awesome-tree-says-happy-new-year/tree.jpg" /&gt;&lt;/p&gt;
&lt;p&gt;Awesome tree says: happy new&amp;nbsp;year!&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Ryan Witt</dc:creator><pubDate>Sat, 13 Feb 2010 19:54:00 -0500</pubDate><guid isPermaLink="false">tag:ryan.sh,2010-02-13:2010/02/13/awesome-tree-says-happy-new-year/</guid><category>photo</category></item><item><title>Sicilian Eggplant Pasta</title><link>http://ryan.sh/2010/02/12/sicilian-eggplant-pasta/</link><description>&lt;p&gt;&lt;img alt="" src="http://ryan.sh/2010/02/12/sicilian-eggplant-pasta/eggplant-pasta.jpg" /&gt;&lt;/p&gt;
&lt;p&gt;Yummy Sicilian Eggplant Pasta that we nominated last night. &lt;a href="http://www.epicurious.com/recipes/food/views/Sicilian-Pasta-with-Eggplant-101551"&gt;Yet another tasty recipe&lt;/a&gt; from&amp;nbsp;Epicurious!&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Ryan Witt</dc:creator><pubDate>Fri, 12 Feb 2010 13:18:00 -0500</pubDate><guid isPermaLink="false">tag:ryan.sh,2010-02-12:2010/02/12/sicilian-eggplant-pasta/</guid><category>food</category></item><item><title>Buttermilk Skillet Cornbread</title><link>http://ryan.sh/2010/01/24/buttermilk-skillet-cornbread/</link><description>&lt;p&gt;&lt;img alt="" src="http://ryan.sh/2010/01/24/buttermilk-skillet-cornbread/cornbread.jpg" /&gt;&lt;/p&gt;
&lt;p&gt;My first batch of buttermilk skillet&amp;nbsp;cornbread!&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Ryan Witt</dc:creator><pubDate>Sun, 24 Jan 2010 20:49:00 -0500</pubDate><guid isPermaLink="false">tag:ryan.sh,2010-01-24:2010/01/24/buttermilk-skillet-cornbread/</guid><category>food</category></item><item><title>First Real Meal at the New Flat</title><link>http://ryan.sh/2009/10/04/first-real-meal/</link><description>&lt;p&gt;&lt;img alt="" src="http://ryan.sh/2009/10/04/first-real-meal/first-meal.jpg" /&gt;&lt;/p&gt;
&lt;p&gt;Jasmine rice with organic creamy tomato sauce, crushed black pepper, crimini mushrooms and fresh&amp;nbsp;basil.&lt;/p&gt;
&lt;p&gt;Now, doesn&amp;#8217;t that sound better than &amp;#8220;something we made with the leftover&amp;nbsp;rice&amp;#8221;?&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Ryan Witt</dc:creator><pubDate>Sun, 04 Oct 2009 17:40:00 -0400</pubDate><guid isPermaLink="false">tag:ryan.sh,2009-10-04:2009/10/04/first-real-meal/</guid><category>food</category></item><item><title>LA Central Library Rotunda</title><link>http://ryan.sh/2009/07/25/la-central-library-rotunda/</link><description>&lt;p&gt;&lt;img alt="" src="http://ryan.sh/2009/07/25/la-central-library-rotunda/library-rotunda.jpg" /&gt;&lt;/p&gt;
&lt;p&gt;If you&amp;#8217;ve never been to the &lt;span class="caps"&gt;LA&lt;/span&gt; Central Library, you should! This is the Lodwrik M. Cook&amp;nbsp;Rotunda.&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Ryan Witt</dc:creator><pubDate>Sat, 25 Jul 2009 15:54:00 -0400</pubDate><guid isPermaLink="false">tag:ryan.sh,2009-07-25:2009/07/25/la-central-library-rotunda/</guid><category>photo</category><category>los angeles</category></item><item><title>Hacked Sign</title><link>http://ryan.sh/2009/06/12/hacked-departure-sign-at-union-station/</link><description>&lt;p&gt;&lt;img alt="" src="http://ryan.sh/2009/06/12/hacked-departure-sign-at-union-station/hacked-sign.jpg" /&gt;&lt;/p&gt;
&lt;p&gt;Hacked departure sign at union&amp;nbsp;station&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Ryan Witt</dc:creator><pubDate>Fri, 12 Jun 2009 02:52:00 -0400</pubDate><guid isPermaLink="false">tag:ryan.sh,2009-06-12:2009/06/12/hacked-departure-sign-at-union-station/</guid><category>funny</category><category>hack</category><category>photo</category></item><item><title>Wedding Tasting</title><link>http://ryan.sh/2009/05/23/heres-our-take-home-wedding-tasting-supposedly/</link><description>&lt;p&gt;&lt;img alt="" src="http://ryan.sh/2009/05/23/heres-our-take-home-wedding-tasting-supposedly/wedding-tasting.jpg" /&gt;&lt;/p&gt;
&lt;p&gt;Here&amp;#8217;s our take-home wedding tasting, supposedly for 2 people, but it fed 7 with&amp;nbsp;leftovers!&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Ryan Witt</dc:creator><pubDate>Sat, 23 May 2009 13:40:00 -0400</pubDate><guid isPermaLink="false">tag:ryan.sh,2009-05-23:2009/05/23/heres-our-take-home-wedding-tasting-supposedly/</guid><category>photo</category><category>food</category></item><item><title>Big Red Button</title><link>http://ryan.sh/2009/02/02/big-red-button/</link><description>&lt;p&gt;&lt;img alt="" src="http://ryan.sh/2009/02/02/big-red-button/big-red-button.jpg" /&gt;&lt;/p&gt;
&lt;p&gt;Hmm&amp;#8230; there is a big red button on my desk. Wonder what it&amp;nbsp;does?&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Ryan Witt</dc:creator><pubDate>Mon, 02 Feb 2009 16:13:00 -0500</pubDate><guid isPermaLink="false">tag:ryan.sh,2009-02-02:2009/02/02/big-red-button/</guid><category>funny</category><category>photo</category></item><item><title>Sméagol</title><link>http://ryan.sh/2009/02/01/smeagol/</link><description>&lt;p&gt;&lt;img alt="" src="http://ryan.sh/2009/02/01/smeagol/smegol.jpg" /&gt;&lt;/p&gt;
&lt;p&gt;The new iPhoto face recognition feature is a little &lt;strong&gt;too&lt;/strong&gt; good.&amp;nbsp;:)&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Ryan Witt</dc:creator><pubDate>Sun, 01 Feb 2009 20:13:00 -0500</pubDate><guid isPermaLink="false">tag:ryan.sh,2009-02-01:2009/02/01/smeagol/</guid><category>photo</category></item><item><title>The Cylon Among Us</title><link>http://ryan.sh/2008/11/28/the-cylon-among-us/</link><description>&lt;p&gt;In a shocking confirmation that all this has happened before, and will happen again, Earth scientists have discovered hitherto unnoticed monuments from the ancient Cylon race, hiding in plain sight in the Los Angeles freeway&amp;nbsp;system.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Cylon Monument" src="http://ryan.sh/2008/11/28/the-cylon-among-us/cylon1.jpg" /&gt;&lt;/p&gt;
&lt;p&gt;The monuments are all located in Garden Grove, &lt;a href="http://maps.google.com/maps?f=q&amp;amp;hl=en&amp;amp;geocode=&amp;amp;sll=34.145892,-118.132351&amp;amp;sspn=0.363696,0.696259&amp;amp;g=Pasadena,+CA&amp;amp;ie=UTF8&amp;amp;ll=33.775723,-117.852402&amp;amp;spn=0.091321,0.174065&amp;amp;z=13&amp;amp;layer=c&amp;amp;cbll=33.775623,-117.853332&amp;amp;panoid=muIChTlsmlaqs-r2-kaS4w&amp;amp;cbp=12,204.153831032658,,0,8.063065525549987"&gt;along California State Route 22&lt;/a&gt;, and appear to have been integrated into the freeway&amp;#8217;s sound wall. Mysteriously, no-one, not even Garden Grove residents, seem to have noticed the monuments until now. Construction plans for the sound wall show openings for the monuments, but make no explicit mention of them. Neither Caltrans nor the &lt;abbr title="Orange County Transportation Authority"&gt;&lt;span class="caps"&gt;OCTA&lt;/span&gt;&lt;/abbr&gt; would comment on the construction&amp;nbsp;plans.&lt;/p&gt;
&lt;p&gt;&lt;img alt="They just built the freeway walls around them..." src="http://ryan.sh/2008/11/28/the-cylon-among-us/cylon2.jpg" /&gt;&lt;/p&gt;
&lt;p&gt;Resident Nicki Clyne, a flight mechanic and a regular on the 22, is credited with first noticing the structures. &amp;#8220;It&amp;#8217;s strange to drive past something every day and never see it. When my daughter was born, I was really distracted, but as she got older, I began to notice things that I used to miss. Discovering that something so close was of Cylon origin really threw me for a&amp;nbsp;loop.&amp;#8221;&lt;/p&gt;
&lt;p&gt;&lt;img alt="A look LaForge would be proud of" src="http://ryan.sh/2008/11/28/the-cylon-among-us/cylon_closeup.jpg" /&gt;&lt;/p&gt;
&lt;p&gt;We approached several experts in the field of speculative Cylon anthropology who independently verified that the monuments are indeed of Cylon construction. &amp;#8220;It was the eye mosaic that pushed the monument origin into the realm of statistical certainty&amp;#8221;, said Dr. James Callis, Senior Fellow at the Forensic [cylon] Research Advancement Centre (&lt;span class="caps"&gt;FRAC&lt;/span&gt;). &amp;#8220;Throughout our conception of Cylon history, the &amp;#8216;scanning eye&amp;#8217; has been an iconic design centerpiece for the more mechanical models. Through the process of elimination, we&amp;#8217;ve concluded that the only explanation is that the monuments must have been erected by the ancient&amp;nbsp;Cylon.&amp;#8221;&lt;/p&gt;
&lt;p&gt;&lt;img alt="Will we ever know why they're here?" src="http://ryan.sh/2008/11/28/the-cylon-among-us/cylon3.jpg" /&gt;&lt;/p&gt;
&lt;p&gt;Researchers from &lt;span class="caps"&gt;FRAC&lt;/span&gt; have put forward the theory that the placement of the monuments influenced the 22 freeway&amp;#8217;s route from the very beginning. Caltrans and &lt;span class="caps"&gt;OCTA&lt;/span&gt; refused to comment on this theory, but city officials have welcomed the new additions as part of the rich cultural heritage of Garden Grove, and are in the process of planning a 3 day festival to commemorate the&amp;nbsp;discovery.&lt;/p&gt;
&lt;p&gt;Photo Credit: Vi&amp;nbsp;Tran&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Ryan Witt</dc:creator><pubDate>Fri, 28 Nov 2008 04:42:44 -0500</pubDate><guid isPermaLink="false">tag:ryan.sh,2008-11-28:2008/11/28/the-cylon-among-us/</guid></item><item><title>Django Login Required Middleware</title><link>http://ryan.sh/2008/11/10/django-login-required-middleware/</link><description>&lt;p&gt;I&amp;#8217;ve been doing a lot programming in the &lt;a href="http://djangoproject.com"&gt;Django web framework&lt;/a&gt; lately and thought this code snippet that forces a user to login to your site before viewing any pages might come in handy. If you&amp;#8217;re already a djangoperson, &lt;a href="#code"&gt;skip ahead to the code&lt;/a&gt;, otherwise, I&amp;#8217;ll give a bit of&amp;nbsp;background.&lt;/p&gt;
&lt;p&gt;In Django, your code that responds to each incoming request is organized into functions called &lt;em&gt;views&lt;/em&gt; which take your &lt;span class="caps"&gt;HTTP&lt;/span&gt; request and turn it into a page that the user can view. It&amp;#8217;s a common practice in Django to augment your views using a python construct called a &lt;a href="http://askawizard.blogspot.com/2008/09/decorators-python-saga-part-2_28.html"&gt;decorator&lt;/a&gt;. This allows you add additional functionality without having to write a bunch of code. For example, Django provides a decorator called &lt;code&gt;login_required&lt;/code&gt; that takes one of your views and prevents a user from seeing it unless they are logged&amp;nbsp;in:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="nd"&gt;@login_required&lt;/span&gt;      &lt;span class="c1"&gt;# This is the decorator! One line... simple.&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;my_view&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# Do something here to turn the request into an HTML page.&lt;/span&gt;
    &lt;span class="c1"&gt;# ...&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Sometimes it&amp;#8217;s a real pain to use the &lt;code&gt;login_required&lt;/code&gt; decorator all over the views of your complicated site. What if you forget to add it to view that contains sensitive information? Fortunately, Django allows you to write &lt;em&gt;middleware&lt;/em&gt; that gets access to each request so you can add functionality that can be applied to your whole site. My middleware simply intercepts each request and redirects users to the site login page if they haven&amp;#8217;t logged in. It also allows you to give of exceptions (in the form of regular expressions), i.e. pages that can be viewed without logging&amp;nbsp;in:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.http&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;HttpResponseRedirect&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.conf&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;settings&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;re&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nb"&gt;compile&lt;/span&gt;

&lt;span class="n"&gt;EXEMPT_URLS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;compile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;settings&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LOGIN_URL&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;lstrip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;/&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;))]&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;hasattr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;settings&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;LOGIN_EXEMPT_URLS&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;EXEMPT_URLS&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;compile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;expr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;expr&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;settings&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LOGIN_EXEMPT_URLS&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;LoginRequiredMiddleware&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="sd"&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;span class="sd"&gt;    Middleware that requires a user to be authenticated to view any page other&lt;/span&gt;
&lt;span class="sd"&gt;    than LOGIN_URL. Exemptions to this requirement can optionally be specified&lt;/span&gt;
&lt;span class="sd"&gt;    in settings via a list of regular expressions in LOGIN_EXEMPT_URLS (which&lt;/span&gt;
&lt;span class="sd"&gt;    you can copy from your urls.py).&lt;/span&gt;

&lt;span class="sd"&gt;    Requires authentication middleware and template context processors to be&lt;/span&gt;
&lt;span class="sd"&gt;    loaded. You&amp;#39;ll get an error if they aren&amp;#39;t.&lt;/span&gt;
&lt;span class="sd"&gt;    &amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;process_request&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="nb"&gt;hasattr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;user&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;The Login Required middleware&lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="s2"&gt; requires authentication middleware to be installed. Edit your&lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="s2"&gt; MIDDLEWARE_CLASSES setting to insert&lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="s2"&gt; &amp;#39;django.contrib.auth.middlware.AuthenticationMiddleware&amp;#39;. If that doesn&amp;#39;t&lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="s2"&gt; work, ensure your TEMPLATE_CONTEXT_PROCESSORS setting includes&lt;/span&gt;&lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="s2"&gt; &amp;#39;django.core.context_processors.auth&amp;#39;.&amp;quot;&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;is_authenticated&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
            &lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path_info&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;lstrip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;/&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="nb"&gt;any&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;EXEMPT_URLS&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;HttpResponseRedirect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;settings&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LOGIN_URL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;Example:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;span class="c1"&gt;# settings.py&lt;/span&gt;

&lt;span class="n"&gt;LOGIN_URL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;/login/&amp;#39;&lt;/span&gt;

&lt;span class="n"&gt;LOGIN_EXEMPT_URLS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
 &lt;span class="s1"&gt;r&amp;#39;^about\.html$&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="s1"&gt;r&amp;#39;^legal/&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;# allow any URL under /legal/*&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;MIDDLEWARE_CLASSES&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="c1"&gt;# ...&lt;/span&gt;
    &lt;span class="s1"&gt;&amp;#39;python.path.to.LoginRequiredMiddleware&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;


&lt;p&gt;While writing this, I found similar solutions by &lt;a href="http://davyd.livejournal.com/262859.html"&gt;davyd&lt;/a&gt; and a &lt;a href="http://groups.google.com/group/django-users/browse_thread/thread/48da19a450ac7869/6762fcc0a46a1d04?lnk=gst&amp;amp;q=login+required+middleware#6762fcc0a46a1d04"&gt;discussion&lt;/a&gt; on the django-users list, but neither had the flexibility of using regular&amp;nbsp;expressions.&lt;/p&gt;
&lt;p&gt;Please let me know if this was useful to you, or if you find any&amp;nbsp;problems!&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Ryan Witt</dc:creator><pubDate>Mon, 10 Nov 2008 19:58:00 -0500</pubDate><guid isPermaLink="false">tag:ryan.sh,2008-11-10:2008/11/10/django-login-required-middleware/</guid><category>django</category><category>github</category><category>python</category><category>code</category></item></channel></rss>