<?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/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Brian Rue's Blog</title>
	<atom:link href="http://brianrue.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://brianrue.wordpress.com</link>
	<description>starting up and scaling out.</description>
	<lastBuildDate>Sat, 11 May 2013 06:21:55 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='brianrue.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://0.gravatar.com/blavatar/2530948fd5af8e03246c78d627efc0b5?s=96&#038;d=http%3A%2F%2Fs2.wp.com%2Fi%2Fbuttonw-com.png</url>
		<title>Brian Rue's Blog</title>
		<link>http://brianrue.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://brianrue.wordpress.com/osd.xml" title="Brian Rue&#039;s Blog" />
	<atom:link rel='hub' href='http://brianrue.wordpress.com/?pushpress=hub'/>
		<item>
		<title>The &#8220;Do it the Hard Way&#8221; Trap</title>
		<link>http://brianrue.wordpress.com/2013/03/06/the-do-it-the-hard-way-trap/</link>
		<comments>http://brianrue.wordpress.com/2013/03/06/the-do-it-the-hard-way-trap/#comments</comments>
		<pubDate>Wed, 06 Mar 2013 08:29:50 +0000</pubDate>
		<dc:creator>Brian Rue</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[startups]]></category>
		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://brianrue.wordpress.com/?p=103</guid>
		<description><![CDATA[I&#8217;ve recently noticed that I&#8217;ve been intentionally doing more things the hard way. The allure is this: the hard way feels like it ought to produce the best results. If you&#8217;re uniquely talented or qualified to do whatever it is you&#8217;re doing the &#8220;hard&#8221; or &#8220;best&#8221; or &#8220;right&#8221; way, it should follow that doing so [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=brianrue.wordpress.com&#038;blog=2434272&#038;post=103&#038;subd=brianrue&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>I&#8217;ve recently noticed that I&#8217;ve been intentionally doing more things the hard way.</p>
<p>The allure is this: the hard way feels like it ought to produce the best results. If you&#8217;re uniquely talented or qualified to do whatever it is you&#8217;re doing the &#8220;hard&#8221; or &#8220;best&#8221; or &#8220;right&#8221; way, it should follow that doing so will give you a competitive advantage. You&#8217;ll have the best product, and no one else will be able to replicate it.</p>
<p>This of course is a fallacy. Why? Because the relationship between raw effort and results is not linear, or even strongly correlated. It&#8217;s often decreasing returns past a threshold, and only effort in the direction of the goal counts (the <a href="http://en.wikipedia.org/wiki/Dot_product">dot product</a> of effort and goals).</p>
<p>The Hard Way is a tempting trap. We&#8217;ve been conditioned toward it in school, having been warded for going &#8221;above and beyond&#8221; to get the A+. Brute force doesn&#8217;t require much creativity, but it&#8217;s still Hard. It can feel like a sure-fire way to build the best product or get the most customers. That customers will recognize your greatness, and competitors won&#8217;t be able to replicate you, because you did it The Hard Way. But customers don&#8217;t care how hard it was to build your product; they care how well it solves their problems. And smart competitors will find easier and more effective ways to compete.</p>
<p>Building a custom datastore for your web app? Maybe you should use something off the shelf instead.</p>
<p>Trying to win by making your design or marketing copy or user interface &#8220;perfect&#8221;? Consider whether &#8220;pretty good&#8221; is good enough. (This is what I&#8217;ve been catching myself doing lately.)</p>
<p>Doing things The Easy Way requires constant reflection about how well your effort is aligned with what you&#8217;re trying to accomplish, and being ruthless about cutting out work that isn&#8217;t pulling its weight. Are you getting a good return on your effort? What can you get by without doing? Can you be more focused? Every time I stop to ask these questions, I&#8217;m glad I did.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/brianrue.wordpress.com/103/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/brianrue.wordpress.com/103/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=brianrue.wordpress.com&#038;blog=2434272&#038;post=103&#038;subd=brianrue&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://brianrue.wordpress.com/2013/03/06/the-do-it-the-hard-way-trap/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/88a92f42715fd0f4b281aff5380827e4?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">brianrue</media:title>
		</media:content>
	</item>
		<item>
		<title>How to stream the World Series live if you&#8217;re in the US</title>
		<link>http://brianrue.wordpress.com/2012/10/25/how-to-stream-the-world-series-live-if-youre-in-the-us/</link>
		<comments>http://brianrue.wordpress.com/2012/10/25/how-to-stream-the-world-series-live-if-youre-in-the-us/#comments</comments>
		<pubDate>Thu, 25 Oct 2012 18:19:05 +0000</pubDate>
		<dc:creator>Brian Rue</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://brianrue.wordpress.com/2012/10/25/how-to-stream-the-world-series-live-if-youre-in-the-us/</guid>
		<description><![CDATA[MLB.tv has a legit, HD, live stream of the World Series&#8230; but it&#8217;s blacked out in the US and Canada. Here&#8217;s what I did to be able to watch the game from the comfort of my desk at work. Things to note: This is not free; it&#8217;ll cost you around $30 to watch the rest of [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=brianrue.wordpress.com&#038;blog=2434272&#038;post=99&#038;subd=brianrue&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>MLB.tv has a legit, HD, live stream of the World Series&#8230; but it&#8217;s blacked out in the US and Canada. Here&#8217;s what I did to be able to watch the game from the comfort of my desk at work.</p>
<p>Things to note:</p>
<ul>
<li>This is <em>not</em> free; it&#8217;ll cost you around $30 to watch the rest of the world series.</li>
<li>The following guide is somewhat technical (though doesn&#8217;t require any programming), and is Mac-specific.</li>
<li>Do this at your own risk; I bear no responsibility whatsoever for following the instructions below.</li>
</ul>
<p><strong>Part 1: Get a Linode server in the UK</strong></p>
<p><em>I may have left out a few minor steps here &#8212; if you get stuck, ask for help in the comments.</em></p>
<p>a. Sign up for an account at <a href="http://www.linode.com">http://www.linode.com</a> . Choose the smallest server size &#8211; the $19.99/month one is fine.</p>
<p><a href="http://brianrue.files.wordpress.com/2012/10/screen-shot-2012-10-25-at-10-52-30-am.png"><img id="i-90" class="size-full wp-image" alt="Image" src="http://brianrue.files.wordpress.com/2012/10/screen-shot-2012-10-25-at-10-52-30-am.png?w=409" /></a></p>
<p>It&#8217;s $19.99 for a whole month, but Linode will reimburse you for unused full days when you cancel. So just make sure to cancel it when you&#8217;re done with it after the world series.</p>
<p>b. Choose &#8220;London&#8221; as the location</p>
<p>c. Go to the Dashboard for your new Linode, and click &#8220;boot&#8221;. Choose &#8220;Ubuntu 12.04 LTS&#8221; as the operating system. Use the defaults for disk and swap size.</p>
<p>d. Wait for it to finish booting &#8211; will take a few minutes. You&#8217;ll know it&#8217;s done when you see this on the top right:</p>
<p><a href="http://brianrue.files.wordpress.com/2012/10/screen-shot-2012-10-25-at-10-51-41-am.png"><img id="i-89" class="size-full wp-image" alt="Image" src="http://brianrue.files.wordpress.com/2012/10/screen-shot-2012-10-25-at-10-51-41-am.png?w=183" /></a></p>
<p>f. Click to the Remote Access tab. Next to where it says &#8220;SSH Access&#8221;, note the IP address.</p>
<p><a href="http://brianrue.files.wordpress.com/2012/10/screen-shot-2012-10-25-at-10-57-54-am.png"><img id="i-91" class="size-full wp-image" alt="Image" src="http://brianrue.files.wordpress.com/2012/10/screen-shot-2012-10-25-at-10-57-54-am.png?w=357" /></a></p>
<p>g. Open a Terminal window. (Press command-space to open Spotlight, then type Terminal, then select the Terminal app and press enter.)</p>
<p><a href="http://brianrue.files.wordpress.com/2012/10/screen-shot-2012-10-25-at-11-09-38-am.png"><img id="i-94" class="size-full wp-image" alt="Image" src="http://brianrue.files.wordpress.com/2012/10/screen-shot-2012-10-25-at-11-09-38-am.png?w=410" /></a></p>
<p>h. Type the following command (using your IP address from step (f) instead of 100.101.102.103.104) and press enter:</p>
<p>ssh -C -D 8080 root@100.101.102.103</p>
<p>You&#8217;ll be prompted for the root password you created when setting up your linode. Enter it now.</p>
<p>i. You now have an SSH tunnel set up that will let you proxy your Mac&#8217;s internet traffic through your London-based Linode. Don&#8217;t close this window. You can minimize it if you want. If your connection gets disrupted, you may need to run the above command again to log back in.</p>
<p><strong>Part 2: Tunnel your internet traffic through your new Linode</strong></p>
<p>a. Open up System Preferences (command-space to open Spotlight, type System Preferences, choose the System Preferences App, press enter)</p>
<p><a href="http://brianrue.files.wordpress.com/2012/10/screen-shot-2012-10-25-at-11-09-13-am.png"><img id="i-93" class="size-full wp-image" alt="Image" src="http://brianrue.files.wordpress.com/2012/10/screen-shot-2012-10-25-at-11-09-13-am.png?w=409" /></a></p>
<p>b. Click &#8220;Advanced&#8230;&#8221;</p>
<p><a href="http://brianrue.files.wordpress.com/2012/10/screen-shot-2012-10-25-at-11-08-55-am.png"><img id="i-92" class="size-full wp-image" alt="Image" src="http://brianrue.files.wordpress.com/2012/10/screen-shot-2012-10-25-at-11-08-55-am.png?w=136" /></a></p>
<p>c. Click Proxies</p>
<p><a href="http://brianrue.files.wordpress.com/2012/10/screen-shot-2012-10-25-at-11-10-19-am.png"><img id="i-95" class="size-full wp-image" alt="Image" src="http://brianrue.files.wordpress.com/2012/10/screen-shot-2012-10-25-at-11-10-19-am.png?w=547" /></a></p>
<p> </p>
<p>d. Check the box next to &#8220;SOCKS Proxy&#8221; (make sure it&#8217;s the only box checked). Enter &#8220;localhost&#8221; for the proxy server name, and 8080 for the port number.</p>
<p><a href="http://brianrue.files.wordpress.com/2012/10/screen-shot-2012-10-25-at-11-11-20-am.png"><img id="i-96" class="size-full wp-image" alt="Image" src="http://brianrue.files.wordpress.com/2012/10/screen-shot-2012-10-25-at-11-11-20-am.png?w=539" /></a> </p>
<p>e. Press OK, then Apply.</p>
<p><a href="http://brianrue.files.wordpress.com/2012/10/screen-shot-2012-10-25-at-11-12-25-am.png"><img id="i-97" class="size-full wp-image" alt="Image" src="http://brianrue.files.wordpress.com/2012/10/screen-shot-2012-10-25-at-11-12-25-am.png?w=293" /></a></p>
<p>f. You&#8217;re now tunneling your HTTP traffic through your linode. To confirm that it worked, go to <a href="http://www.whatismyip.com">http://www.whatismyip.com</a> and confirm that it shows that your IP address is your Linode&#8217;s IP address.</p>
<p><strong>Part 3: Sign up for MLB.tv</strong></p>
<p>a. Go <a href="http://mlb.mlb.com/mlb/subscriptions/index.jsp">here</a> and sign up. It&#8217;s $24.99 for the rest of the postseason.</p>
<p>b. Once you log in, you&#8217;ll see a page like this:</p>
<p><a href="http://brianrue.files.wordpress.com/2012/10/screen-shot-2012-10-25-at-11-15-30-am.png"><img id="i-98" class="size-full wp-image" alt="Image" src="http://brianrue.files.wordpress.com/2012/10/screen-shot-2012-10-25-at-11-15-30-am.png?w=962" /></a></p>
<p>c. At game time, press &#8220;Watch&#8221;. It&#8217;ll pop up the MLB.tv player. If all is well, the player will load and the stream will be live!</p>
<p>If you get a message about blackout restrictions, it probably means that something in step 2 didn&#8217;t go right. Make sure that your ip address according to whatismyip.com is your Linode ip, and try again.</p>
<p>Good luck and go Giants!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/brianrue.wordpress.com/99/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/brianrue.wordpress.com/99/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=brianrue.wordpress.com&#038;blog=2434272&#038;post=99&#038;subd=brianrue&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://brianrue.wordpress.com/2012/10/25/how-to-stream-the-world-series-live-if-youre-in-the-us/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/88a92f42715fd0f4b281aff5380827e4?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">brianrue</media:title>
		</media:content>

		<media:content url="http://brianrue.files.wordpress.com/2012/10/screen-shot-2012-10-25-at-10-52-30-am.png?w=409" medium="image">
			<media:title type="html">Image</media:title>
		</media:content>

		<media:content url="http://brianrue.files.wordpress.com/2012/10/screen-shot-2012-10-25-at-10-51-41-am.png?w=183" medium="image">
			<media:title type="html">Image</media:title>
		</media:content>

		<media:content url="http://brianrue.files.wordpress.com/2012/10/screen-shot-2012-10-25-at-10-57-54-am.png?w=357" medium="image">
			<media:title type="html">Image</media:title>
		</media:content>

		<media:content url="http://brianrue.files.wordpress.com/2012/10/screen-shot-2012-10-25-at-11-09-38-am.png?w=410" medium="image">
			<media:title type="html">Image</media:title>
		</media:content>

		<media:content url="http://brianrue.files.wordpress.com/2012/10/screen-shot-2012-10-25-at-11-09-13-am.png?w=409" medium="image">
			<media:title type="html">Image</media:title>
		</media:content>

		<media:content url="http://brianrue.files.wordpress.com/2012/10/screen-shot-2012-10-25-at-11-08-55-am.png?w=136" medium="image">
			<media:title type="html">Image</media:title>
		</media:content>

		<media:content url="http://brianrue.files.wordpress.com/2012/10/screen-shot-2012-10-25-at-11-10-19-am.png?w=547" medium="image">
			<media:title type="html">Image</media:title>
		</media:content>

		<media:content url="http://brianrue.files.wordpress.com/2012/10/screen-shot-2012-10-25-at-11-11-20-am.png?w=539" medium="image">
			<media:title type="html">Image</media:title>
		</media:content>

		<media:content url="http://brianrue.files.wordpress.com/2012/10/screen-shot-2012-10-25-at-11-12-25-am.png?w=293" medium="image">
			<media:title type="html">Image</media:title>
		</media:content>

		<media:content url="http://brianrue.files.wordpress.com/2012/10/screen-shot-2012-10-25-at-11-15-30-am.png?w=962" medium="image">
			<media:title type="html">Image</media:title>
		</media:content>
	</item>
		<item>
		<title>What Adobe&#8217;s new pricing for Flash means for social game developers</title>
		<link>http://brianrue.wordpress.com/2012/03/28/what-adobes-new-pricing-for-flash-means-for-social-game-developers/</link>
		<comments>http://brianrue.wordpress.com/2012/03/28/what-adobes-new-pricing-for-flash-means-for-social-game-developers/#comments</comments>
		<pubDate>Wed, 28 Mar 2012 19:14:24 +0000</pubDate>
		<dc:creator>Brian Rue</dc:creator>
				<category><![CDATA[Products]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://brianrue.wordpress.com/?p=84</guid>
		<description><![CDATA[My jaw dropped this morning when I read the news: Adobe will begin charging a 9% revenue share on revenue above $50k for using some &#8220;premium features&#8221; in Flash Player. The new pricing goes into effect for apps launched after August 1st that use both of the following features: ApplicationDomain.domainMemory Stage3D.request3DContext, when using hardware acceleration These [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=brianrue.wordpress.com&#038;blog=2434272&#038;post=84&#038;subd=brianrue&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>My jaw dropped this morning when I read the news: Adobe will <a href="http://www.adobe.com/devnet/flashplayer/articles/premium-features.html">begin charging a 9% revenue share</a> on revenue above $50k for using some &#8220;premium features&#8221; in Flash Player. The new pricing goes into effect for apps launched after August 1st that use both of the following features:</p>
<ul>
<li>ApplicationDomain.domainMemory</li>
<li>Stage3D.request3DContext, when using hardware acceleration</li>
</ul>
<p>These features are used together by the Unity and Unreal engines and allow console-quality games to be played in the browser. They could also be used together inadvertently by developers rolling their own optimizations; for example, using domainMemory for code optimizations and Stage3D for rendering would also fall under the new terms.</p>
<p>Up until today, developers like me have assumed that, like everything else in Flash Player, these features would always be free.</p>
<p>So, what exactly does &#8220;9% of net revenue&#8221; mean for social game developers? In the cutthroat, thinning-margin social games business, it probably means that no one will be able to afford to use the new features. Dropping your effective LTV from $3 to $2.73, when you&#8217;re paying $2.50 to acquire that user, means you now have <em>54%</em> less money to cover both marginal costs (hosting and support) and fixed costs (initial and ongoing development). That&#8217;s huge.</p>
<p>I suspect we&#8217;ll see a few developers give it a shot, but in the longer run this is going to push more people to HTML5 / WebGL and contribute to the eventual abandonment of Flash as a platform for social games.</p>
<p>I can only assume that the Flash Player team is doing this because they&#8217;ve been told they have to figure out a way to pay for themselves. But I hope they figure out a different way&#8211;perhaps taking a revshare on tools like Unity instead of games themselves&#8211;so that the Flash gaming ecosystem can continue to live and grow.</p>
<p>Thanks to <a href="https://twitter.com/#!/justinrosenthal">Justin Rosenthal</a> for reading drafts of this.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/brianrue.wordpress.com/84/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/brianrue.wordpress.com/84/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=brianrue.wordpress.com&#038;blog=2434272&#038;post=84&#038;subd=brianrue&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://brianrue.wordpress.com/2012/03/28/what-adobes-new-pricing-for-flash-means-for-social-game-developers/feed/</wfw:commentRss>
		<slash:comments>33</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/88a92f42715fd0f4b281aff5380827e4?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">brianrue</media:title>
		</media:content>
	</item>
		<item>
		<title>Farewell, Lolapps</title>
		<link>http://brianrue.wordpress.com/2012/03/23/farewell-lolapps/</link>
		<comments>http://brianrue.wordpress.com/2012/03/23/farewell-lolapps/#comments</comments>
		<pubDate>Fri, 23 Mar 2012 23:00:31 +0000</pubDate>
		<dc:creator>Brian Rue</dc:creator>
				<category><![CDATA[Startups]]></category>

		<guid isPermaLink="false">http://brianrue.wordpress.com/?p=79</guid>
		<description><![CDATA[Today marks my last day at 6waves Lolapps. 6waves Lolapps was formed last July as the result of a merger between 6waves, a Hong Kong-based publisher of social games, and Lolapps, the company I co-founded 4 years ago. On Monday this week we let go substantially all of the development staff, and today is the [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=brianrue.wordpress.com&#038;blog=2434272&#038;post=79&#038;subd=brianrue&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>Today marks my last day at 6waves Lolapps. 6waves Lolapps was formed last July as the result of a merger between 6waves, a Hong Kong-based publisher of social games, and Lolapps, the company I co-founded 4 years ago. On Monday this week we <a href="http://www.insidesocialgames.com/2012/03/19/exclusive-6waves-lolapps-cuts-development-staff-focuses-exclusively-on-publishing/">let go substantially all</a> of the <a href="http://techcrunch.com/2012/03/19/6waves-lolapps-layoffs/">development staff</a>, and today is the end of my short transition-out period.</p>
<p>It&#8217;s been a crazy ride of ups and downs and it feels very strange that it&#8217;s come to an end. I&#8217;m proud of the culture that we built, and it was especially evident this week as suddenly-former employees banded together to commiserate and find new companies to call home. I’m also very proud of the products we built, from the well-tuned viral apps in the early days (Quiz Creator and Gift Creator) to the envelope-pushing games we made more recently (<a href="http://www.facebook.com/RavenwoodFair">Ravenwood Fair</a> and <a href="http://www.facebook.com/RavenskyeCity">Ravenskye City</a>). And I’ve thoroughly enjoyed being part of an amazing team of talented, fun, and ambitious people.</p>
<p>I&#8217;ve learned more than I could have imagined and look forward to cataloging that over the coming few weeks.</p>
<p>What I’m doing next: still to be determined. What I do know: I want to start another company, and I want to try something very different. Check out the <a href="http://angel.co/brianr">markets I follow on AngelList</a> to see the general direction.</p>
<p>Countless thanks to Annie Chang, Kamo Asatryan, <a href="http://twitter.com/kavinstewart">Kavin Stewart</a>, <a href="http://twitter.com/arjunsethi">Arjun Sethi</a>, AJ Cantu, <a href="http://twitter.com/justinrosenthal">Justin Rosenthal</a>, <a href="https://twitter.com/#!/coryvirok">Cory Virok</a>, Vivek Tatineni, and the rest of the Lolapps team for an amazing four years. I can’t wait to see what we all come up with next.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/brianrue.wordpress.com/79/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/brianrue.wordpress.com/79/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=brianrue.wordpress.com&#038;blog=2434272&#038;post=79&#038;subd=brianrue&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://brianrue.wordpress.com/2012/03/23/farewell-lolapps/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/88a92f42715fd0f4b281aff5380827e4?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">brianrue</media:title>
		</media:content>
	</item>
		<item>
		<title>My experience note-taking at PyCon 2012</title>
		<link>http://brianrue.wordpress.com/2012/03/11/my-experience-note-taking-at-pycon-2012/</link>
		<comments>http://brianrue.wordpress.com/2012/03/11/my-experience-note-taking-at-pycon-2012/#comments</comments>
		<pubDate>Sun, 11 Mar 2012 16:28:35 +0000</pubDate>
		<dc:creator>Brian Rue</dc:creator>
				<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://brianrue.wordpress.com/?p=72</guid>
		<description><![CDATA[First off: the notes are here. I took most of them, but got some help from Roman Kofman and Alex Graveley. Thanks guys! The rest of this post is a reflection on the note-taking experience. I&#8217;m not able to attend PyCon today so hopefully someone else will carry the torch the rest of the way [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=brianrue.wordpress.com&#038;blog=2434272&#038;post=72&#038;subd=brianrue&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>First off: <a href="https://hackpad.com/LQgZLPeokTB#PyCon-2012-Notes">the notes are here</a>. I took most of them, but got some help from Roman Kofman and Alex Graveley. Thanks guys!</p>
<p>The rest of this post is a reflection on the note-taking experience. I&#8217;m not able to attend PyCon today so hopefully someone else will carry the torch the rest of the way <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>I started my notetaking extravaganza as a means of remembering what happened, and writing down interesting things to share with the rest of the engineering team at <a href="http://www.lolapps.com">6waves Lolapps</a> who weren&#8217;t in attendance. I took them in TextEdit. Paul Graham&#8217;s keynote was really good so I posted the notes on this blog. I did the same for the first few sessions I attended, but the formatting was <a href="http://brianrue.wordpress.com/2012/03/09/pycon-2012-the-art-of-subclassing-raymond-hettinger/">really</a> <a href="http://brianrue.wordpress.com/2012/03/09/pycon-2012-notes-advanced-security-topics/">terrible</a>. Then I remembered seeing something on TechCrunch about using HackPad to take shared notes at SXSW, and tried it out on the next talk. It worked pretty well so I ended up taking notes at each of the sessions I went to.</p>
<p>Here&#8217;s my quick review of HackPad for this purpose:</p>
<ul>
<li>Liked the interface &#8211; easy to type stuff pretty fast</li>
<li>Liked that sharing it is super easy. Cool to see people online in real-time.</li>
<li>Sync worked reasonably well over the conference wifi. not realtime but updated every ~second</li>
<li>Got disconnected a lot on saturday. Not sure if that was HackPad&#8217;s problem or the wifi&#8217;s.</li>
<li>Didn&#8217;t appear to be a way to delete any pads, or remove them from collections. This kept me from using a Collection for the notes &#8211; I couldn&#8217;t remove the default &#8220;Welcome to [this collection]&#8221; pad that would&#8217;ve been confusing because I already had a &#8220;home page&#8221; pad.</li>
<li>Better code formatting support would be nice. you can format things as &#8220;code&#8221; by indenting 4 spaces, but it feels a little fragile, and it&#8217;s hard to indent multiple lines of code that has its own indentation.</li>
<li>Auto-&#8221;table of contents&#8221; by looking at things that are bold was cool. Worked reasonably well here, though on some of the larger documents it would&#8217;ve been nice to have multiple layers of headings.</li>
</ul>
<p>Some more general thoughts about the shared-note-taking experience:</p>
<ul>
<li>Taking notes was pretty useful for me, to remember what was presented and force myself to stay engaged.</li>
<li>One problem with them being shared is that I feel a little awkward promoting them because I don&#8217;t really own them.</li>
<li>The notes feel the most useful and most meaningful for the talks that didn&#8217;t have as much info on the slides. There were a few talks where I found myself trying to type everything that was on the slides&#8230; that seems like an unnecessary duplication of effort. The talks where the slides were <a href="https://hackpad.com/suhVIfEClcY#2:15pm---Storm:-the-Hadoop-of-Real-Time-Processing">minimal</a> or <a href="https://hackpad.com/4WQkPTzV1bf#9:50am---Paul-Graham-Keynote">nonexistent</a> felt better from a note-taking perspective.</li>
</ul>
<p>All in all, this was a lot of fun and I&#8217;ll definitely do it again, especially if more people get involved. And for those of you at pycon now, <a href="https://hackpad.com/LQgZLPeokTB#PyCon-2012-Notes">go take some notes</a>!</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/brianrue.wordpress.com/72/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/brianrue.wordpress.com/72/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=brianrue.wordpress.com&#038;blog=2434272&#038;post=72&#038;subd=brianrue&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://brianrue.wordpress.com/2012/03/11/my-experience-note-taking-at-pycon-2012/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/88a92f42715fd0f4b281aff5380827e4?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">brianrue</media:title>
		</media:content>
	</item>
		<item>
		<title>PyCon 2012 Notes &#8211; Advanced Security Topics</title>
		<link>http://brianrue.wordpress.com/2012/03/09/pycon-2012-notes-advanced-security-topics/</link>
		<comments>http://brianrue.wordpress.com/2012/03/09/pycon-2012-notes-advanced-security-topics/#comments</comments>
		<pubDate>Fri, 09 Mar 2012 22:29:25 +0000</pubDate>
		<dc:creator>Brian Rue</dc:creator>
				<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://brianrue.wordpress.com/?p=66</guid>
		<description><![CDATA[Here are my raw notes. Friday &#8211; 1:45pm &#8211; Advanced Security Topics Paul McMillan &#160; Hashing Common Crpyo Hashes: md5, sha1, sha256 If you&#8217;re typing md5 into your code, you&#8217;re probably doing it wrong &#160; Message signing &#8211; did the message come from who i expect it to come from? &#160; How can we be attacked? [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=brianrue.wordpress.com&#038;blog=2434272&#038;post=66&#038;subd=brianrue&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p><em>Here are my raw notes.</em></p>
<p><strong>Friday &#8211; 1:45pm &#8211; Advanced Security Topics</strong></p>
<p>Paul McMillan</p>
<p>&nbsp;</p>
<p><strong>Hashing</strong></p>
<p>Common Crpyo Hashes: md5, sha1, sha256</p>
<p>If you&#8217;re typing md5 into your code, you&#8217;re probably doing it wrong</p>
<p>&nbsp;</p>
<p>Message signing &#8211; did the message come from who i expect it to come from?</p>
<p>&nbsp;</p>
<p>How can we be attacked?</p>
<p>&nbsp;</p>
<p>Did this file get corrupted</p>
<p>&nbsp;</p>
<p>When doing a basic md5 hash, we check that hash that we have. Where did we get that hash?</p>
<p>If we know that the md5 hash that we have is good, then we&#8217;re pretty secure &#8211; hard to generate a hash collision (reasonably hard problem).</p>
<p>&nbsp;</p>
<p>For message signing, it&#8217;s diferent.</p>
<p>H = md5(secret + message)</p>
<p>NO!</p>
<p>&nbsp;</p>
<p>An attacker can generate:</p>
<p>md5(secret + message) == md5(secret + message + junk + attacker_message)</p>
<p>maybe your app is strict about format and this will result in an error</p>
<p>If an attacker can, given one message, sign a different message, it&#8217;s not good.</p>
<p>Solution: <strong>use HMAC</strong></p>
<p>HMAC is essentially: hash(secret + hash(message))</p>
<p>use hmac lib</p>
<p>and salt your secret key.</p>
<p>salt = &#8216;session_cookie_signing&#8217;</p>
<p>hmac.new(salt + secret_key, msg)</p>
<p>If you don&#8217;t salt based on the use in each area of your app, then an attacker could take a signed message from one area and use it in another area.</p>
<p>&nbsp;</p>
<p>Don&#8217;t use MD5! Avoid SHA1. Use SHA256 (for now).</p>
<p>There&#8217;s also SHA512, but on 32-bit machines can have serious performance problems. SHA256 is similarly secure.</p>
<p>&nbsp;</p>
<p><strong>Encryption</strong></p>
<p>You should not be implementing encryption, in almost all cases.</p>
<p>Why do you need it?</p>
<p>If when protecting data in transit, use SSL/TLS.</p>
<p>Protecting data at rest: use underlying OS. There are already good solutions for this.</p>
<p>&nbsp;</p>
<p><strong>Random numbers</strong></p>
<p>Generating a secret key:</p>
<p>&nbsp;</p>
<p>import random</p>
<p>secret = &#8221;.join(random.choice(allowed_cars) for i in range(length))</p>
<p>&nbsp;</p>
<p>Don&#8217;t do that! Default random in python is predictable.</p>
<p>&nbsp;</p>
<p>Solution:</p>
<p>from random import SystemRandom()</p>
<p>&nbsp;</p>
<p>will use entropy data from various sources.</p>
<p>&nbsp;</p>
<p>But&#8230; you don&#8217;t know how much entropy is actually there. In some cases this can be a real problem. i.e. if you&#8217;re running at the start of a virtualized machine, there&#8217;s not a lot of entropy yet. It&#8217;ll run out of entropy and give you predictable numbers.</p>
<p>&nbsp;</p>
<p><strong>Timing attacks</strong></p>
<p>message, sig = &#8216;|&#8217;.split(incoming)</p>
<p>sig2 = hmac.new(salt + secret_key, message)</p>
<p>if sig == sig2:</p>
<p>do_something()</p>
<p>&nbsp;</p>
<p>== is the problem because string comparison will short circuit when there isn&#8217;t a match.</p>
<p>&nbsp;</p>
<p>If you take a lot of message, it&#8217;s possible to figure out a long string, one character at a time.</p>
<p>&nbsp;</p>
<p>Very small difference but it&#8217;s statistically decidable in hundreds-to-millions of messages depending on the app. Over the internet there&#8217;s a lot of latency so it&#8217;s impractical. But a lot of apps are virtualized &#8211; I&#8217;m on the same machine as you, can ask you lots of questions really fast.</p>
<p>&nbsp;</p>
<p>Solution: use a constant-time compare function.</p>
<p>check same length, then do an operation of every set of characters.</p>
<p>&nbsp;</p>
<p>if len(val1) != len(val2):</p>
<p>return False</p>
<p>result = 0</p>
<p>for x, y in zip(val1, val2):</p>
<p>result |= ord(x) ^ ord(y)</p>
<p>return result == 0</p>
<p>&nbsp;</p>
<p><strong>Pickle</strong></p>
<p>Loading an untrusted string is equivalent to running eval() on that string!</p>
<p>Use JSON or something, not pickle, for untrusted data.</p>
<p>If you must use pickle, sign and verify it&#8230; but use JSON if possible to avoid complexity of signing.</p>
<p>&nbsp;</p>
<p><strong>&#8220;You would think that&#8230;&#8221;</strong></p>
<p>No. Always verify your assumptions.</p>
<p>&nbsp;</p>
<p>For example&#8230;.</p>
<p>pip install Django</p>
<p>- I trust the django authors</p>
<p>- i trust the people who run pypi</p>
<p>- i trust the people who wrote pip</p>
<p>- pip verifies the md5 hashes of packages</p>
<p>- packages on pypi can be pgp signed</p>
<p>- pypi uses ssl</p>
<p>&nbsp;</p>
<p>So I&#8217;m safe right?</p>
<p>Of course not&#8230; all of these things require you to trust everyone on the internet.</p>
<p>- pip verifies md5 hash  &#8212; but it downloaded the hash from the same page it downloaded the package from, and that&#8217;s in plain text. if someone can change the code, they can change the hash.</p>
<p>- pgp signed &#8212; no tool currently checks pgp</p>
<p>- pypi uses ssl &#8212; not really</p>
<p>&nbsp;</p>
<p>PyPi -</p>
<p>- untrusted (by default) certificate</p>
<p>- plaintext by default</p>
<p>- easy_install and pip don&#8217;t use the SSL</p>
<p>Python doesn&#8217;t make it easy to check SSL certs. This is a problem.</p>
<p>&nbsp;</p>
<p>You&#8217;d think that when you open a HTTPS url you&#8217;d get encryption&#8230; and you do, but it doesn&#8217;t verify the certificate.</p>
<p>&nbsp;</p>
<p>Recommendation: use the &#8216;requests&#8217; library. It *does* do the cert check by default.</p>
<p>&nbsp;</p>
<p><strong>Demo</strong></p>
<p>DNS lookup &#8211; UDP. Computer will trust the first response it gets back. So on open wifi, easy for someone to spoof your dns and say that pypi.org is whatever they want.</p>
<p>&nbsp;</p>
<p>&#8220;sudo pip install certifi&#8221;</p>
<p>&nbsp;</p>
<p>Runs setup.py &#8212; so anyone can put code in setup.py and then it&#8217;ll run on your computer as root.</p>
<p>&nbsp;</p>
<p>PyPI offers everything necessary to make this not possible, but we don&#8217;t use it.</p>
<p>&nbsp;</p>
<p><strong>How do we help the python community?</strong></p>
<p>- use the requests library</p>
<p>- if you&#8217;re using hashes, use hmac.</p>
<p>&nbsp;</p>
<p><strong>Q&amp;A</strong></p>
<p>Q: Putting packages on pypi &#8212; is there a better way to do this at a release-process level?</p>
<p>A: It&#8217;s a hard problem. If you put something in the package that verifies the package is what you expected, that&#8217;s no good. If you provide something alongside the package, it&#8217;s the same problem. Signed PGP files &#8212; it&#8217;s great, but noone checks this. We need to make the tools.</p>
<p>&nbsp;</p>
<p>Q: How much of this is actually new? How much of this is actually security-specific?</p>
<p>The HMAC stuff, for example, is all &#8220;don&#8217;t reinvent the wheel&#8221;, and security is the context. Are there cases where you have to do something because of a security reason? What about the signing stuff &#8211; that&#8217;s been seen before too.</p>
<p>A: None of this is new. But as a community we pretend it doesn&#8217;t exist. The end result of most conversations about this are &#8220;it&#8217;s not pypi&#8217;s problem, users should be doing something secure.&#8221; But that&#8217;s not the way to think about this: should make the way that&#8217;s obvious the right thing.</p>
<p>Q: But right now it&#8217;s more work to do it the right way, so it&#8217;s bad engineering on the part of users.</p>
<p>A: Higher-level constructs tend to make code more secure. But have to use</p>
<p>&nbsp;</p>
<p>Q: Why didn&#8217;t the demo work? Issues with the wifi &#8211; security features?</p>
<p>A: Script was set up for WPA2 network, but this is an older network.</p>
<p>&nbsp;</p>
<p>Q: Timing attack &#8211; constant-time string compare is not the obvious way to do it&#8230;</p>
<p>A: Have to think about security implications. Python should have a constant-time compare function.</p>
<p>&nbsp;</p>
<p>Q: Constant-time compare function probably has problems because of mallocs. Don&#8217;t think it&#8217;s possible to really have a constant time compare function.</p>
<p>A: Is possible to get very very close. Not possible in C either but can get close.</p>
<p>&nbsp;</p>
<p>Q: Suggestions for downloading packages for doing releases?</p>
<p>A: Most large software projects have a system for finalizing packages. Unusual to install things directly from the cheese shop. Pip team is sprinting on adding auth.</p>
<p>&nbsp;</p>
<p>Q: crate.io &#8211; what does this actually do to increase security if installers are still the same?</p>
<p>A: Storing sha256 hashes. Storing hashes long-term so you have a history of what files were there. In PyPI things can be changed without you noticing. crate will maintain a history.</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/brianrue.wordpress.com/66/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/brianrue.wordpress.com/66/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=brianrue.wordpress.com&#038;blog=2434272&#038;post=66&#038;subd=brianrue&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://brianrue.wordpress.com/2012/03/09/pycon-2012-notes-advanced-security-topics/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/88a92f42715fd0f4b281aff5380827e4?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">brianrue</media:title>
		</media:content>
	</item>
		<item>
		<title>PyCon 2012 &#8211; The Art of Subclassing (Raymond Hettinger)</title>
		<link>http://brianrue.wordpress.com/2012/03/09/pycon-2012-the-art-of-subclassing-raymond-hettinger/</link>
		<comments>http://brianrue.wordpress.com/2012/03/09/pycon-2012-the-art-of-subclassing-raymond-hettinger/#comments</comments>
		<pubDate>Fri, 09 Mar 2012 20:11:28 +0000</pubDate>
		<dc:creator>Brian Rue</dc:creator>
				<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://brianrue.wordpress.com/?p=63</guid>
		<description><![CDATA[Here are my notes. Many thanks to Raymond for this excellent talk. Hopefully he can share his slides soon &#160; Friday &#8211; 11:30am &#8211; The Art of Subclassing Raymond Hettinger &#160; - revisit the notion of a class and subclass witha  view to deepening our core concepts of what it means to be a calass/subclass/instance [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=brianrue.wordpress.com&#038;blog=2434272&#038;post=63&#038;subd=brianrue&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p><em>Here are my notes. Many thanks to Raymond for this excellent talk. Hopefully he can share his slides soon <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </em></p>
<p>&nbsp;</p>
<p><strong>Friday &#8211; 11:30am &#8211; The Art of Subclassing</strong></p>
<p>Raymond Hettinger</p>
<p>&nbsp;</p>
<p>- revisit the notion of a class and subclass witha  view to deepening our core concepts of what it means to be a calass/subclass/instance</p>
<p>- discuss use cases, principles, and design patterns</p>
<p>- demonstrate super()</p>
<p>- use examples from standard library</p>
<p>&nbsp;</p>
<p>terminology:</p>
<p>adding: Dog adds the bark() method to Animal which didn&#8217;t know how to do before</p>
<p>overriding: snake replaces walk()</p>
<p>extending: cat modifies walk() to add tail swishing</p>
<p>&nbsp;</p>
<p>Patterns for subclassing:</p>
<p>1. Frameworks</p>
<p>- parent class supplies all of the controller functionality and makes calls to prenamed stub methods</p>
<p>- the subclass overrides stub methods of interest</p>
<p>- e.g. SimpleHTTPServer runs an event loop and dispatches HTTP requests to stub methods like do_HEAD() and do_GET()</p>
<p>(these start as just &#8220;pass&#8221;)</p>
<p>- someone writing an HTTP server would use a subclass to supply to desired actions in the event of a GET or HEAD request</p>
<p>&nbsp;</p>
<p>very static. choices to override are predefined. framework tells you &#8220;here are the things you can subclass&#8221;</p>
<p>&nbsp;</p>
<p>2. Dynamic dispatch to subclass methods</p>
<p>- parent class uses getattr() to dispatch to new functionality</p>
<p>- child class implements appropriately names methods</p>
<p>example: cmd.py</p>
<p>&nbsp;</p>
<p>* best way to become a better python programmer is to read code written by great python programmers, like the standard library</p>
<p>&nbsp;</p>
<p>polish a class and think about subclassers (like yourself) in the future</p>
<p>dynamic dispatch is a great method.</p>
<p>&nbsp;</p>
<p>3. Call Pattern</p>
<p>don&#8217;t hardwire class name in __repr__ &#8212; use self.__class__.__name__</p>
<p>&nbsp;</p>
<p>&#8212;</p>
<p>super:</p>
<p>#1 misunderstanding: in other languages, means i&#8217;m calling one or more of my parents.</p>
<p>&#8216;self&#8217; might not be you.</p>
<p>when you call super, it&#8217;s not your ancestry tree that matters, it&#8217;s the caller&#8217;s.</p>
<p>super means go up from your children &#8211; start at the bottom.</p>
<p>&nbsp;</p>
<p>&#8212;</p>
<p>Let&#8217;s retool our thinking about subclasses.</p>
<p>&nbsp;</p>
<p>patterns from java, etc. cause you to think in a constrained way in python.</p>
<p>&nbsp;</p>
<p>What does it mean to be an object/class?</p>
<p>Object: an entity that encapsulates data together with functions (methods) for manipulating that data.</p>
<p>We implement that with dictionaries:</p>
<p>- instance dictionaries hold state and point to their class</p>
<p>- class dicts hold the functions (methods)</p>
<p>&nbsp;</p>
<p>InstDict1 -&gt;</p>
<p>InstDict2 -&gt;  ClassDict</p>
<p>InstDict3 -&gt;</p>
<p>&nbsp;</p>
<p>instance points at the class, not the other way around.</p>
<p>&nbsp;</p>
<p>So what is a subclass?</p>
<p>- a class that <em>delegates work</em> to another class</p>
<p>- a subclass and its parent are just two different dicts that contain functions</p>
<p>- subclass points to its parent</p>
<p>- pointer means &#8220;i delegate work to this class&#8221;</p>
<p>&nbsp;</p>
<p>InstDict1 -&gt;</p>
<p>InstDict2 -&gt;  SubClassDict -&gt; ParClassDict</p>
<p>InstDict3 -&gt;</p>
<p>&nbsp;</p>
<p>&#8220;subclass means to specialize&#8221; &#8211;&gt; no, that&#8217;s not it in python. it&#8217;s <em>delegation</em>.</p>
<p>&nbsp;</p>
<p>- Subclassing can be viewed as a technique for code reuse.</p>
<p>- It is the subclass that is in charge</p>
<p>- The subclass decides what work gets delegated.</p>
<p>&nbsp;</p>
<p>Operational (implementaiton) view of subclassing:</p>
<p>- classes are dicts of functions</p>
<p>- subclasses point to other dictionaries to reuse their code</p>
<p>- subclasses are in complete contorl of what happens</p>
<p>&nbsp;</p>
<p>Conceptual views of a subclasses:</p>
<p>[the way many people think of them - not how it actually is!]</p>
<p>- parent classes define an interface</p>
<p>- subclasses can extend that interface</p>
<p>- parents are in charge</p>
<p>- subclasses are just specializations of the parent</p>
<p>&nbsp;</p>
<p>Shift from the view at the bottom to the view at the top.</p>
<p>&nbsp;</p>
<p>Liskov Substitution Principle</p>
<p>&#8220;If S is a subtype of T, then objects of type T may be replaced with objects of the S&#8221;</p>
<p>&nbsp;</p>
<p>Why do we care about Liskov?</p>
<p>- It is all about polymorphism and subsitutability so that our subclass can be used in client code without changing the client code.</p>
<p>- Example: consider a large body of code for a cash register that calls an accept_payment() method on a payment object</p>
<p>e.g. deployed code given to clients</p>
<p>- We can write separate classes for credit cards, cash, checks, etc that all owrk without chanigng the cash register code</p>
<p>- We can write subclasses of the credit card class that provides custom handling for Visa, Amex, etc.</p>
<p>&nbsp;</p>
<p>It&#8217;s a <em>Principle </em>not a <em>Law</em>.</p>
<p>&nbsp;</p>
<p>Liskov Violations:</p>
<p>- any part of the api that isn&#8217;t fully substituatable</p>
<p>- this is common and normal</p>
<p>- useful subclasses commonly have different constructor signatures</p>
<p>- for example, the array API is very similar to the list API but the constructor is different:</p>
<p>s = list(someiterable)</p>
<p>s = array(&#8216;c&#8217;, someiterable)</p>
<p>-&gt; not substitutable.</p>
<p>&nbsp;</p>
<p>Goal: minimize or isolate the impact when signature is different.</p>
<p>&nbsp;</p>
<p>e.g. sets:</p>
<p>MutableSet instances suport union, intersection, difference</p>
<p>So they need to be able to create new instances of MutableSets</p>
<p>But the siganture of the constructor is unknown</p>
<p>So, we factor out calls to the constructor in _from_iterable().</p>
<p>-&gt; if your constructor has a different signature, override _from_iterable and you&#8217;re good to go.</p>
<p>&nbsp;</p>
<p>-&gt; Factor out all your Liskov violations into one place to make it easier on subclasses. Just one adapter.</p>
<p>&nbsp;</p>
<p>The Circle / Ellipse Problem</p>
<p>- in math, circle is just a special case of ellipse</p>
<p>- if one ellipse method stretches an axis, what does that mean for circle instances? (i.e. circle.skew())</p>
<p>- the problem is that circles have less info that an ellipse and have constraints that don&#8217;t apply to general ellipses</p>
<p>- the reverse wouldn&#8217;t work either because circles have capabilites that don&#8217;t apply to ellipses (i.e. the bounding box is a square)</p>
<p>&nbsp;</p>
<p>-&gt; there&#8217;s no Liskov-wise right answer as to which is the superclass</p>
<p>&nbsp;</p>
<p>So how do you decide?</p>
<p>Not specialization: think about code reuse.</p>
<p>Principle for deciding which is the parent class: whichever maximizes code reuse. (whichever has the most reusable code should be the parent.)</p>
<p>&nbsp;</p>
<p>Taxonomy hierarchies do not neatly transform into useful class hierarchies.</p>
<p>- i.e. making a tree of exceptions</p>
<p>- substitutability can be a hard problem.</p>
<p>something is kind of a TypeEror, kind of a RuntimeError&#8230; use multiple inheritance.</p>
<p>&nbsp;</p>
<p>substitutability is a nontrivial problem. if you start a sentence with &#8220;well you just&#8230;&#8221; that&#8217;s probably not a good answer.</p>
<p>&nbsp;</p>
<p>* think about code reuse.</p>
<p>&nbsp;</p>
<p>Open-Closed Principle</p>
<p>- &#8220;software enttiies (classes, modules, functions, etc.) should be open for extension, but closed for modification&#8221;</p>
<p>- has many different interpretations</p>
<p>- sometimes it refers to use of abstract base classes to create fixed interfaces with multiple impls</p>
<p>&nbsp;</p>
<p>Facts of life when subclassing builtins:</p>
<p>- dicts: overridding __getitem__ does not solve it for get()</p>
<p>it&#8217;s possible for you to do something that breaks an invariant.</p>
<p>so need to override every method instead of just one</p>
<p>&nbsp;</p>
<p>OCP in python with name mangling</p>
<p>- A method named __update in a class caleed MyDict transforms the name into _MyDict__update</p>
<p>- This makes the method invisible to subclasses. Use this to create protected internal calls in addition to overridable public methods.</p>
<p>&nbsp;</p>
<p>class MyDict:</p>
<p>def __init__(self, iterable):</p>
<p>self.items_list = []</p>
<p>self.__update(iterable)</p>
<p>&nbsp;</p>
<p>def update(self, iterable):</p>
<p>for item in iterable:</p>
<p>self.items_list.append(item)</p>
<p>__update = update</p>
<p>&nbsp;</p>
<p>This is what the double-underscore is for.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/brianrue.wordpress.com/63/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/brianrue.wordpress.com/63/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=brianrue.wordpress.com&#038;blog=2434272&#038;post=63&#038;subd=brianrue&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://brianrue.wordpress.com/2012/03/09/pycon-2012-the-art-of-subclassing-raymond-hettinger/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/88a92f42715fd0f4b281aff5380827e4?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">brianrue</media:title>
		</media:content>
	</item>
		<item>
		<title>PyCon 2012 Notes &#8211; Paul Graham Keynote</title>
		<link>http://brianrue.wordpress.com/2012/03/09/pycon-2012-notes-paul-graham-keynote/</link>
		<comments>http://brianrue.wordpress.com/2012/03/09/pycon-2012-notes-paul-graham-keynote/#comments</comments>
		<pubDate>Fri, 09 Mar 2012 18:59:36 +0000</pubDate>
		<dc:creator>Brian Rue</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Startups]]></category>

		<guid isPermaLink="false">http://brianrue.wordpress.com/2012/03/09/pycon-2012-notes-paul-graham-keynote/</guid>
		<description><![CDATA[Here are my raw notes from the keynote. Update: PG posted this talk in essay form. It&#8217;s not much longer than my notes; you should probably read that instead.  big startup ideas are actually terrifying &#8211; threaten your identity 1. making a new search engine to compete with google seems almost impossible knew that msft [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=brianrue.wordpress.com&#038;blog=2434272&#038;post=60&#038;subd=brianrue&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p><em>Here are my raw notes from the keynote.<br />
Update: PG <a href="http://paulgraham.com/ambitious.html">posted this talk in essay form</a>. It&#8217;s not much longer than my notes; you should probably read that instead. </em></p>
<p>big startup ideas are actually terrifying &#8211; threaten your identity</p>
<p>1. making a new search engine to compete with google</p>
<p>seems almost impossible</p>
<p>knew that msft had peaked when it got into the search business. now google is getting into the social network business&#8230;</p>
<p>find the tiny thing that turns into the gigantic idea</p>
<p>dinosaur egg &#8211; make a search engine that all the hackers use. (top 10,000). don&#8217;t worry about doing something constraining in the short term, because if you don&#8217;t succeed in the short term there won&#8217;t be a long term</p>
<p>2. replace email</p>
<p>inbox is a todo list. email is the protocol for putting stuff on it</p>
<p>it&#8217;s not a good todo list. anybody can put something on it.</p>
<p>will have to make a new protocol (&#8220;todo list protocol&#8221;). could degrade to the old protocol. should give more power to the recipient. control who can put something in your inbox</p>
<p>powerful people are in pain because of email. that&#8217;s an opportunity.</p>
<p>whatever you build, make it fast. gmail has become painfully slow.</p>
<p>3. replace universities</p>
<p>heading down wrong path last couple decades. not fun for students or professors.</p>
<p>universities won&#8217;t be replaced wholesale but will be replaced piecewise &#8211; lots of little things. pycon, ycombinator are examples.</p>
<p>universities are now a credential. if they go away, credentialling will have to be supplied separately.</p>
<p>4. kill hollywood</p>
<p>internet is the winning delivery mechanism (not cable &#8211; esp. bc of cable&#8217;s client, the TV).</p>
<p>how do you deliver drama via the internet?</p>
<p>will have to be on a larger scale than youtube clips</p>
<p>delivery+payment &#8211; maybe something like netflix will be the &#8220;app store&#8221; for entertainment</p>
<p>5. a new apple</p>
<p>his friend from apple: there will be no new good stuff post-steve jobs.</p>
<p>if apple is not going to make the next ipad, who will?</p>
<p>none of the existing players will &#8211; not run by product visionaries.</p>
<p>only way to get a product visionary as the ceo of a company is to start it and not get fired.</p>
<p>so next apple will have to be a startup.</p>
<p>someone taking on the problem now has the advantage of having the example of apple.</p>
<p>just have to be better than samsung, hp, motorola &#8211; not so hard <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>6. bring back the old moore&#8217;s law</p>
<p>old moore&#8217;s law used to mean that if your software was slow, you could just wait for the next gen of processors. hardware solved software&#8217;s problems.</p>
<p>now, you have to rewrite it to do more things in parallel.</p>
<p>it would be great if a startup could make a lot of cpus look to the developer like 1 cpu.</p>
<p>most ambitious: do it automatically with a compiler.</p>
<p>really hard, but is this really impossible?</p>
<p>if so, prove it <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  if not, the expected value of working on it might be really high.</p>
<p>why high: web services. programmers like convenience.</p>
<p>this boils down to being a new intel.</p>
<p>less ambitious: start from the bottom. build programs out of more-parallelizable lego blocks. programmer still does most of the work.</p>
<p>middle ground: build something that looks to the user like a sufficiently-smart compiler, but in the middle there are humans doing optimization. could have a marketplace for optimization. write bots to do the optimization. if you ever got to the point where all the bots could do the work, you&#8217;d have created the sufficiently smart compiler. (but no one would own it)</p>
<p>7. ongoing diagnosis</p>
<p>one way to get startup ideas: imagine the way we&#8217;ll seem backwards to people in the future.</p>
<p>e.g. heart disease &#8211; what % blocked are your arteries? someday we&#8217;ll know this number as well as we know our weight.</p>
<p>same for cancer.</p>
<p>obstacles:</p>
<p>- some from medical profession</p>
<p>a lot of doctors worry that if you start testing people all the time, you&#8217;ll get a lot of false alarms that make people panic, cost a lot of money, etc.</p>
<p>but if you scan people all the time, it won&#8217;t be alarming.</p>
<p>&#8212;</p>
<p>Tactical advice:</p>
<p>do not make a direct frontal attack on the problem. don&#8217;t say that you&#8217;re going to replace email, because employees and investors will ask &#8220;are you there yet?&#8221; and you&#8217;ll attract lots of haters.</p>
<p>start with small things and grow them bigger.</p>
<p>maybe it&#8217;s a bad idea to have really big ambitions initially. the longer you project into the future, the more likely you are to be wrong.</p>
<p>don&#8217;t try to identify a precise thing in the future. better model: columbus. &#8220;there&#8217;s something west. i&#8217;ll sail westward&#8221;.</p>
<p>empirically, it&#8217;s probably better to have a blurry vision of the future instead of a precise one.</p>
<p>&#8212;</p>
<p>what is property has been defined by what&#8217;s convenient to be property.</p>
<p>can&#8217;t charge for copies of stuff anymore &#8211; doesn&#8217;t work anymore.</p>
<p>instead of getting a degree from an institution, get it from a person. (sorta like phds). this is actually how universities used to work &#8211; you&#8217;d get certified by someone from the guild.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/brianrue.wordpress.com/60/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/brianrue.wordpress.com/60/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=brianrue.wordpress.com&#038;blog=2434272&#038;post=60&#038;subd=brianrue&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://brianrue.wordpress.com/2012/03/09/pycon-2012-notes-paul-graham-keynote/feed/</wfw:commentRss>
		<slash:comments>18</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/88a92f42715fd0f4b281aff5380827e4?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">brianrue</media:title>
		</media:content>
	</item>
		<item>
		<title>Not enough food on the plane</title>
		<link>http://brianrue.wordpress.com/2012/03/01/not-enough-food-on-the-plane/</link>
		<comments>http://brianrue.wordpress.com/2012/03/01/not-enough-food-on-the-plane/#comments</comments>
		<pubDate>Thu, 01 Mar 2012 21:15:39 +0000</pubDate>
		<dc:creator>Brian Rue</dc:creator>
				<category><![CDATA[Management]]></category>

		<guid isPermaLink="false">http://brianrue.wordpress.com/?p=54</guid>
		<description><![CDATA[On my weather-delayed flight from Boston to San Francisco tonight, I watched a frustrated flight attendant deal with a situation out of her control: there wasn&#8217;t enough food to feed everyone on the plane. The flight was scheduled for 5:40pm but didn&#8217;t take off until almost 7, and it was after 8 by the time [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=brianrue.wordpress.com&#038;blog=2434272&#038;post=54&#038;subd=brianrue&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>On my weather-delayed flight from Boston to San Francisco tonight, I watched a frustrated flight attendant deal with a situation out of her control: there wasn&#8217;t enough food to feed everyone on the plane.</p>
<p>The flight was scheduled for 5:40pm but didn&#8217;t take off until almost 7, and it was after 8 by the time the service carts made it to the back quarter of the plane. My row got the last few items on the food cart, so the flight attendant had to explain to the 6 rows of hungry passengers behind me that there wasn&#8217;t anything left. To one passenger, she said:</p>
<blockquote><p>Let me give you some advice: never trust the airlines to give you anything. Nothing is free anymore. Buy your food at the airport and bring it with you because you can&#8217;t count on there being anything on the plane.</p></blockquote>
<p>Ouch. And this was just one of a series of comments exchanged between flight attendants about how under-equipped they were to do their job. It can&#8217;t be good when your most customer-facing employees are so fed up with the resources they&#8217;re being given [1] that they&#8217;ll open disparage their company in front of the customers they&#8217;re trying so hard to serve.</p>
<p>More broadly: this is a great reminder that one of the most simple and powerful things you can do as a manager is give your employees the resources they need to do their jobs, then get out of their way and let them do it. And when you don&#8217;t&#8230; things get ugly.</p>
<p>&lt;/rant&gt;. You can follow me on twitter <a href="http://twitter.com/brianrue">here</a>.</p>
<p>[1] Practically speaking&#8230; how hard can it really be to make sure there&#8217;s enough food on the plane? This wasn&#8217;t the first time I&#8217;ve seen the food cart run out of food, but even if it really were uncommon, I have to believe that it&#8217;s better to over-stock and deal with a bit of spoilage than under-stock and deal with hungry passengers.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/brianrue.wordpress.com/54/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/brianrue.wordpress.com/54/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=brianrue.wordpress.com&#038;blog=2434272&#038;post=54&#038;subd=brianrue&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://brianrue.wordpress.com/2012/03/01/not-enough-food-on-the-plane/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/88a92f42715fd0f4b281aff5380827e4?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">brianrue</media:title>
		</media:content>
	</item>
		<item>
		<title>Pinterest is a Categorized Stream</title>
		<link>http://brianrue.wordpress.com/2012/01/05/pinterest-is-a-categorized-stream/</link>
		<comments>http://brianrue.wordpress.com/2012/01/05/pinterest-is-a-categorized-stream/#comments</comments>
		<pubDate>Thu, 05 Jan 2012 20:10:43 +0000</pubDate>
		<dc:creator>Brian Rue</dc:creator>
				<category><![CDATA[Products]]></category>

		<guid isPermaLink="false">http://brianrue.wordpress.com/?p=31</guid>
		<description><![CDATA[I found Elad Gil’s recent post about Pinterest and the general trend toward curation quite interesting and insightful. However, I think this point is a bit off the mark: All of the social services continued to serve content as a time ordered stream.  Moving from a stream to a structured collectible set of content was [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=brianrue.wordpress.com&#038;blog=2434272&#038;post=31&#038;subd=brianrue&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<div>
<p dir="ltr">I found Elad Gil’s <a href="http://blog.eladgil.com/2011/12/how-pinterest-will-transform-web-in.html">recent post</a> about Pinterest and the general trend toward curation quite interesting and insightful. However, I think this point is a bit off the mark:</p>
<blockquote>
<p dir="ltr">All of the social services continued to serve content as a time ordered stream.  Moving from a stream to a structured collectible set of content was the next innovation in social media.</p>
</blockquote>
<p dir="ltr">Pinterest boards provide structure, but they are still a stream that has a concept of time. They are not a “set” that is fixed in time. This distinction is important, and I think Pinterest (and most of the other curation sites) made the right decision to stick with a time-based stream rather than a static set.</p>
<p dir="ltr">The problem with a static collection that builds over time is that it gets stale. The Facebook friend list is one example (as Michael Arrington <a href="http://uncrunched.com/2012/01/03/nobody-goes-to-facebook-anymore-its-too-crowded/">recently blogged</a>). When I first joined just before coming to college, every person I met and friended was relevant and fresh. The total value of my Facebook network was high and rising fast. Over time, the value was brought up as I accumulated more friends, but brought down as I lost touch with some of my early friends and as the audience for my content became more varied. At some point the total value peaks and starts declining, and then I have to either remove friends or start over.</p>
<div style="margin:1em 1em 2em;">
<p dir="ltr"><img class="size-medium wp-image-32 alignleft" title="Average Individual Friend Value" src="http://brianrue.files.wordpress.com/2012/01/average-individual-friend-value.png?w=300&#038;h=180" alt="" width="300" height="180" /><img class="size-medium wp-image-33 alignright" title="Total Friend List Value" src="http://brianrue.files.wordpress.com/2012/01/total-friend-list-value.png?w=300&#038;h=180" alt="" width="300" height="180" /></p>
<div style="clear:both;"></div>
</div>
<p dir="ltr">The stream model that’s worked so well for blogs, Facebook posts, and Twitter avoids this problem because the time aspect makes it very easy to tell what is fresh from what is stale. Old content doesn’t bog down the new content because it’s out of sight unless you look for it.</p>
<p dir="ltr">Pinterest, Quora’s Boards, and Snip.It follow the same model. On the Pinterest front page, pins are sorted most-recent first (left-to-right, then top-to-bottom). The same is true on an individual board’s page. This means curators can continually add content and the collection never feels stale because the newest content is always the most visible.</p>
<p dir="ltr">I’m going to label this class of product the categorized stream. A categorized stream is simply a stream with a name, like <a href="http://pinterest.com/brianrue/places-i-want-to-go/">Places I want to go</a> on Pinterest or <a href="http://www.quora.com/Shreyes-Seshasai/Economics-of-Sports">Economics of Sports</a> on Quora. Categorized streams are not entirely new: we’ve seen this before with tagged blog posts (Blogger) and bookmarks (del.icio.us), and to some extent twitter hashtags.</p>
<p dir="ltr">A categorized stream provides:</p>
<ul>
<li><strong>Built-in context for every post.</strong> On Facebook, the context is just “me”. On Pinterest, the context is “me + Places I want to go”. Every post automatically has more meaning and requires less explanation.</li>
<li><strong>Consumer-side filtering.</strong> You can follow just the boards you like on Pinterest instead of every board of every friend; following someone’s board on Quora just follows that board. This is a different approach to the problem Google+ is trying to solve with Circles and Facebook is trying to solve with Friend Lists. It’s consumer-side filtering based on interests instead of producer-side filtering based on privacy. And that allows me, as a content creator or curator, to post content that appeals to only a subset of my connections without worrying about spamming the rest.</li>
</ul>
<p dir="ltr">I think these effects, especially the second, could end up being as important to curation as the push-button element.</p>
<p dir="ltr">It will be very interesting to see how the curation sites evolve over the next year and if we start to see categorized streams cropping up elsewhere, in longer-form content than pure curation&#8211;perhaps on Google+, Facebook, or Twitter as they work to solve the relevancy problem. How would it change my Twitter experience if I could subscribe to @parislemon’s posts about tech but not to his posts about football?</p>
<p dir="ltr">Many thanks to <a href="http://twitter.com/#!/ajalison">Alison Johnston</a> for reviewing drafts of this post.</p>
<p dir="ltr">You can follow me on Twitter <a href="http://twitter.com/#!/brianrue">here</a>.</p>
</div>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/brianrue.wordpress.com/31/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/brianrue.wordpress.com/31/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=brianrue.wordpress.com&#038;blog=2434272&#038;post=31&#038;subd=brianrue&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://brianrue.wordpress.com/2012/01/05/pinterest-is-a-categorized-stream/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://2.gravatar.com/avatar/88a92f42715fd0f4b281aff5380827e4?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">brianrue</media:title>
		</media:content>

		<media:content url="http://brianrue.files.wordpress.com/2012/01/average-individual-friend-value.png?w=300" medium="image">
			<media:title type="html">Average Individual Friend Value</media:title>
		</media:content>

		<media:content url="http://brianrue.files.wordpress.com/2012/01/total-friend-list-value.png?w=300" medium="image">
			<media:title type="html">Total Friend List Value</media:title>
		</media:content>
	</item>
	</channel>
</rss>
