<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-9842007</id><updated>2021-09-13T02:49:54.989-05:00</updated><category term="tocollege.net"/><category term="git"/><category term="gwt"/><category term="hibernate"/><title type='text'>jeff dwyer&#39;s blog</title><subtitle type='html'>vox clamantis in interneto</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://blog.jdwyah.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9842007/posts/default?alt=atom'/><link rel='alternate' type='text/html' href='http://blog.jdwyah.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/9842007/posts/default?alt=atom&amp;start-index=26&amp;max-results=25'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/13347545383502498067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>228</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-9842007.post-4845922413332597474</id><published>2018-10-24T09:41:00.001-05:00</published><updated>2018-10-24T09:42:53.983-05:00</updated><title type='text'>Accomplishing Early Prediction Of LTV with RapidMiner</title><content type='html'>&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://3.bp.blogspot.com/-94DFNxz-Y3s/W9CCd8N5ZnI/AAAAAAADK14/nzymGE8zdLESaI0WZVrN9wmmwMRD6mLEACLcBGAs/s1600/Screen%2BShot%2B2018-10-24%2Bat%2B10.31.46%2BAM.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;765&quot; data-original-width=&quot;1600&quot; height=&quot;190&quot; src=&quot;https://3.bp.blogspot.com/-94DFNxz-Y3s/W9CCd8N5ZnI/AAAAAAADK14/nzymGE8zdLESaI0WZVrN9wmmwMRD6mLEACLcBGAs/s400/Screen%2BShot%2B2018-10-24%2Bat%2B10.31.46%2BAM.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;I presented at &lt;a href=&quot;https://rapidminer.com/wisdom/early-prediction-ltv/&quot;&gt;https://rapidminer.com/wisdom/early-prediction-ltv/&lt;/a&gt; on the work we&#39;ve done at ezCater to predict LTV/CLV based on the first N days of a customer&#39;s data. (Although secret #1 is never ever say LTV or CLV) Anyway, it was my first major ML project and it was really a blast. RapidMiner was great to use and gave me a ton of flexibility to try different approaches easily. It&#39;s hard to overstate how much we now rely on these models to run our business.&lt;br /&gt;&lt;br /&gt;The slides are now up&amp;nbsp;&lt;a href=&quot;https://rapidminer.com/wisdom/early-prediction-ltv/&quot;&gt;https://rapidminer.com/wisdom/early-prediction-ltv/&lt;/a&gt; if you want to take a gander.</content><link rel='replies' type='application/atom+xml' href='http://blog.jdwyah.com/feeds/4845922413332597474/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9842007&amp;postID=4845922413332597474' title='39 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9842007/posts/default/4845922413332597474'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9842007/posts/default/4845922413332597474'/><link rel='alternate' type='text/html' href='http://blog.jdwyah.com/2018/10/accomplishing-early-prediction-of-ltv.html' title='Accomplishing Early Prediction Of LTV with RapidMiner'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/13347545383502498067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://3.bp.blogspot.com/-94DFNxz-Y3s/W9CCd8N5ZnI/AAAAAAADK14/nzymGE8zdLESaI0WZVrN9wmmwMRD6mLEACLcBGAs/s72-c/Screen%2BShot%2B2018-10-24%2Bat%2B10.31.46%2BAM.png" height="72" width="72"/><thr:total>39</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9842007.post-4314451534525356320</id><published>2018-01-16T17:34:00.003-05:00</published><updated>2018-01-16T17:34:59.373-05:00</updated><title type='text'>Estimating LTV</title><content type='html'>Around the beginning of 2017, we realized that we really needed to understand how to predict our customers LTV.&amp;nbsp; I hate to be trendy, but the more I looked the more it turned out to be a really good candidate for an ML solution.&lt;br /&gt;&lt;br /&gt;With Elements of Statistical Learning&amp;nbsp;&amp;nbsp;&lt;a href=&quot;https://www.amazon.com/Elements-Statistical-Learning-Prediction-Statistics/dp/0387848576/ref=as_li_ss_il?ie=UTF8&amp;amp;linkCode=li1&amp;amp;tag=jesbl-20&amp;amp;linkId=7a194b10aea2d40f068a813120450dfa&quot; target=&quot;_blank&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;//ws-na.amazon-adsystem.com/widgets/q?_encoding=UTF8&amp;amp;ASIN=0387848576&amp;amp;Format=_SL110_&amp;amp;ID=AsinImage&amp;amp;MarketPlace=US&amp;amp;ServiceVersion=20070822&amp;amp;WS=1&amp;amp;tag=jesbl-20&quot; /&gt;&lt;/a&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; height=&quot;1&quot; src=&quot;https://ir-na.amazon-adsystem.com/e/ir?t=jesbl-20&amp;amp;l=li1&amp;amp;o=1&amp;amp;a=0387848576&quot; style=&quot;border: none !important; margin: 0px !important;&quot; width=&quot;1&quot; /&gt;&lt;br /&gt;and the&amp;nbsp;&lt;a href=&quot;https://www.coursera.org/learn/machine-learning&quot;&gt;https://www.coursera.org/learn/machine-learning&lt;/a&gt;&amp;nbsp; course under my belt I set off on a journey of self discovery and lots and lots of CSVs &amp;amp; R.&lt;br /&gt;&lt;br /&gt;Finally found some time to blog it all up so here it is:&lt;br /&gt;&lt;a href=&quot;https://engineering.ezcater.com/early-prediction-of-customer-lifetime-value&quot;&gt;https://engineering.ezcater.com/early-prediction-of-customer-lifetime-value&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.jdwyah.com/feeds/4314451534525356320/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9842007&amp;postID=4314451534525356320' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9842007/posts/default/4314451534525356320'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9842007/posts/default/4314451534525356320'/><link rel='alternate' type='text/html' href='http://blog.jdwyah.com/2018/01/estimating-ltv.html' title='Estimating LTV'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/13347545383502498067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9842007.post-5943155466644125755</id><published>2017-07-04T14:27:00.002-05:00</published><updated>2017-07-04T14:27:54.244-05:00</updated><title type='text'>AWS Athena &amp; Firehose are my new favorite hammer</title><content type='html'>I blogged a bit about how I&#39;m using AWS Athena and Firehose at Ratelim.it to record and process usage logs. It&#39;s been super satisfying and easy to get going and cheap as anything.&lt;br /&gt;&lt;br /&gt;http://blog.ratelim.it/blog/log-aggregation-at-scale-for-cheap-with-aws-athena-and-kinesis-firehose&lt;br /&gt;&lt;br /&gt;If you&#39;ve got a ton of data that you just need to get to S3 and you have irregular access patterns this seems like a fabulous solution. Amazing to have a Presto cluster at your fingertips for mere pennies.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.jdwyah.com/feeds/5943155466644125755/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9842007&amp;postID=5943155466644125755' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9842007/posts/default/5943155466644125755'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9842007/posts/default/5943155466644125755'/><link rel='alternate' type='text/html' href='http://blog.jdwyah.com/2017/07/aws-athena-firehose-are-my-new-favorite.html' title='AWS Athena &amp; Firehose are my new favorite hammer'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/13347545383502498067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9842007.post-4007748437571541889</id><published>2017-06-01T13:49:00.001-05:00</published><updated>2017-06-01T15:05:34.546-05:00</updated><title type='text'>Finished up blog posts on Experiments and p-Value graphs</title><content type='html'>I blogged! again!&lt;br /&gt;&lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://4.bp.blogspot.com/-ZrdLpvIDfP4/WTBhHVCfeGI/AAAAAAADKiI/DkU2njqWuQgV_dv_nN-Q39ADsKNEeqZ6QCLcB/s1600/Screen%2BShot%2B2017-06-01%2Bat%2B12.26.02%2BPM.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;505&quot; data-original-width=&quot;1600&quot; height=&quot;200&quot; src=&quot;https://4.bp.blogspot.com/-ZrdLpvIDfP4/WTBhHVCfeGI/AAAAAAADKiI/DkU2njqWuQgV_dv_nN-Q39ADsKNEeqZ6QCLcB/s640/Screen%2BShot%2B2017-06-01%2Bat%2B12.26.02%2BPM.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Two new posts, the &lt;a href=&quot;https://engineering.ezcater.com/deciding-when-to-call-an-experiment-p-value-graphs&quot;&gt;first one&lt;/a&gt; a riff on the &lt;a href=&quot;https://medium.com/airbnb-engineering/experiments-at-airbnb-e2db3abf39e7&quot;&gt;AirBnB post about experiment analysis&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The second one a breakdown of the &lt;a href=&quot;https://engineering.ezcater.com/measuring-ab-tests-sql-for-pvalue-graphs-in-redshift&quot;&gt;fancy Redshift SQL&lt;/a&gt; to create said graph.&lt;br /&gt;&lt;br /&gt;Glad to have wrapped up these posts, they were sitting in the queue forever, and I quite like the experiment infrastructure that we&#39;ve built at ezCater.&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.jdwyah.com/feeds/4007748437571541889/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9842007&amp;postID=4007748437571541889' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9842007/posts/default/4007748437571541889'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9842007/posts/default/4007748437571541889'/><link rel='alternate' type='text/html' href='http://blog.jdwyah.com/2017/06/finished-up-blog-posts-on-experiments.html' title='Finished up blog posts on Experiments and p-Value graphs'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/13347545383502498067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://4.bp.blogspot.com/-ZrdLpvIDfP4/WTBhHVCfeGI/AAAAAAADKiI/DkU2njqWuQgV_dv_nN-Q39ADsKNEeqZ6QCLcB/s72-c/Screen%2BShot%2B2017-06-01%2Bat%2B12.26.02%2BPM.png" height="72" width="72"/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9842007.post-992408847336207645</id><published>2017-04-13T09:29:00.002-05:00</published><updated>2017-04-13T09:29:28.784-05:00</updated><title type='text'>DIY Heroku using Amazon ECS</title><content type='html'>&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://1.bp.blogspot.com/-QBaTio0XEyU/WO-K-4jUsjI/AAAAAAADKgI/2Uip1H8nYycKXUFvpXyZofwgKrmdJ1aswCLcB/s1600/Screen%2BShot%2B2017-04-13%2Bat%2B10.27.41%2BAM.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;228&quot; src=&quot;https://1.bp.blogspot.com/-QBaTio0XEyU/WO-K-4jUsjI/AAAAAAADKgI/2Uip1H8nYycKXUFvpXyZofwgKrmdJ1aswCLcB/s400/Screen%2BShot%2B2017-04-13%2Bat%2B10.27.41%2BAM.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;I spoke at Boston.Rb this week and I&#39;ve uploaded the slides to Slideshare. Enjoy &lt;a href=&quot;https://www.slideshare.net/jdwyah/diy-heroku-using-amazon-ecs-and-terraform&quot;&gt;DIY Heroku using Amazon ECS &amp;amp; Terraform&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.jdwyah.com/feeds/992408847336207645/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9842007&amp;postID=992408847336207645' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9842007/posts/default/992408847336207645'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9842007/posts/default/992408847336207645'/><link rel='alternate' type='text/html' href='http://blog.jdwyah.com/2017/04/diy-heroku-using-amazon-ecs.html' title='DIY Heroku using Amazon ECS'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/13347545383502498067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://1.bp.blogspot.com/-QBaTio0XEyU/WO-K-4jUsjI/AAAAAAADKgI/2Uip1H8nYycKXUFvpXyZofwgKrmdJ1aswCLcB/s72-c/Screen%2BShot%2B2017-04-13%2Bat%2B10.27.41%2BAM.png" height="72" width="72"/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9842007.post-525793123863691521</id><published>2017-04-13T09:21:00.001-05:00</published><updated>2017-04-13T09:21:01.556-05:00</updated><title type='text'>How to write an event ingestion pipeline</title><content type='html'>I blogged over at the new &lt;a href=&quot;https://engineering.ezcater.com/ezexperiments-ab-testing-at-ezcater-part-1-event-taxonomy-warehousing&quot;&gt;ezCater engineering blog.&lt;/a&gt;&amp;nbsp; I think we&#39;ve built a pretty solid event pipeline for our usage tracking and AB testing and wanted to share. &amp;nbsp;Here&#39;s a preview:&lt;br /&gt;&lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://2.bp.blogspot.com/-psQkIAZecQI/WO-JPVBXJCI/AAAAAAADKf4/VByf1ckVivga7tWkdOz3F2RvF0-13RhTACLcB/s1600/Screen%2BShot%2B2017-04-05%2Bat%2B12.29.09%2BPM.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;257&quot; src=&quot;https://2.bp.blogspot.com/-psQkIAZecQI/WO-JPVBXJCI/AAAAAAADKf4/VByf1ckVivga7tWkdOz3F2RvF0-13RhTACLcB/s320/Screen%2BShot%2B2017-04-05%2Bat%2B12.29.09%2BPM.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.jdwyah.com/feeds/525793123863691521/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9842007&amp;postID=525793123863691521' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9842007/posts/default/525793123863691521'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9842007/posts/default/525793123863691521'/><link rel='alternate' type='text/html' href='http://blog.jdwyah.com/2017/04/how-to-write-event-ingestion-pipeline.html' title='How to write an event ingestion pipeline'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/13347545383502498067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://2.bp.blogspot.com/-psQkIAZecQI/WO-JPVBXJCI/AAAAAAADKf4/VByf1ckVivga7tWkdOz3F2RvF0-13RhTACLcB/s72-c/Screen%2BShot%2B2017-04-05%2Bat%2B12.29.09%2BPM.png" height="72" width="72"/><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9842007.post-2515166187256915818</id><published>2017-02-17T20:30:00.001-05:00</published><updated>2017-02-17T20:30:11.772-05:00</updated><title type='text'>RateLim.it Launched</title><content type='html'>&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://1.bp.blogspot.com/-WZ31vk_17BI/WKejLnHNYmI/AAAAAAADKdg/1bzefuoc63wk0vpvubqZ2FRojAlZ3xIMQCLcB/s1600/ratelimit.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;82&quot; src=&quot;https://1.bp.blogspot.com/-WZ31vk_17BI/WKejLnHNYmI/AAAAAAADKdg/1bzefuoc63wk0vpvubqZ2FRojAlZ3xIMQCLcB/s320/ratelimit.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Excited to announce that I finally managed to kick &lt;a href=&quot;https://www.ratelim.it/&quot;&gt;rate limits as a service&lt;/a&gt; out the door. A year or so in the making, but it&#39;s already been scratching my itch and solving my problems for a few months now.&lt;br /&gt;&lt;br /&gt;I didn&#39;t intend to build feature flags in as well, but when I started coding I realized I can no longer code without them and it was just as easy to build them for everybody as it was to build them for just myself, so they&#39;re included too! (&lt;a href=&quot;https://www.ratelim.it/documentation/feature_flags&quot;&gt;Feature flag documentation&lt;/a&gt;)&lt;br /&gt;&lt;br /&gt;Two libraries so far:&amp;nbsp;&lt;a href=&quot;https://github.com/jdwyah/ratelimit-ruby&quot;&gt;ratelimit-ruby&lt;/a&gt;&amp;nbsp;and&amp;nbsp;&lt;a href=&quot;https://github.com/jdwyah/ratelimit-java&quot;&gt;ratelimit-java&lt;/a&gt;. You&#39;ll never guess what they do!&lt;br /&gt;&lt;br /&gt;Blogging about it at&amp;nbsp;http://blog.ratelim.it/blog so head on over and subscribe to that to hear more. Oh and twittering at&amp;nbsp;https://twitter.com/RateLimitInc&lt;br /&gt;&lt;br /&gt;Happy rate-limiting to you!&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.jdwyah.com/feeds/2515166187256915818/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9842007&amp;postID=2515166187256915818' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9842007/posts/default/2515166187256915818'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9842007/posts/default/2515166187256915818'/><link rel='alternate' type='text/html' href='http://blog.jdwyah.com/2017/02/ratelimit-launched.html' title='RateLim.it Launched'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/13347545383502498067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://1.bp.blogspot.com/-WZ31vk_17BI/WKejLnHNYmI/AAAAAAADKdg/1bzefuoc63wk0vpvubqZ2FRojAlZ3xIMQCLcB/s72-c/ratelimit.png" height="72" width="72"/><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9842007.post-1788543450071606610</id><published>2016-02-16T15:49:00.003-05:00</published><updated>2017-04-11T09:07:59.917-05:00</updated><title type='text'>Ruby on Rails on Docker on Amazon ECS w/ Terraform &amp; DataDog</title><content type='html'>Buzzword buzzword buzzword.&lt;br /&gt;&lt;br /&gt;But no seriously buzzword. This post is a followup to &lt;a href=&quot;https://segment.com/blog/rebuilding-our-infrastructure/&quot;&gt;https://segment.com/blog/rebuilding-our-infrastructure/&lt;/a&gt; which is a great post about how a real company is doing something awesome.&lt;br /&gt;&lt;br /&gt;My real company (&lt;a href=&quot;http://ezcater.com/&quot;&gt;ezCater&lt;/a&gt;) is interested in doing awesome things too, but since a month ago I didn&#39;t really know how to plug a docker into a cloud I thought I&#39;d start off simple with my smaller project &lt;a href=&quot;http://whatsize.is/&quot;&gt;whatsize.is&lt;/a&gt;&amp;nbsp;(&quot;So the gift always fits&quot; &amp;nbsp;catchy right?)&lt;br /&gt;&lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://1.bp.blogspot.com/-Y9sRvM6DMFI/VsOBaLJBj3I/AAAAAAADKTA/Y2chJofWQAs/s1600/Screen%2BShot%2B2016-02-16%2Bat%2B3.06.36%2BPM.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;192&quot; src=&quot;https://1.bp.blogspot.com/-Y9sRvM6DMFI/VsOBaLJBj3I/AAAAAAADKTA/Y2chJofWQAs/s320/Screen%2BShot%2B2016-02-16%2Bat%2B3.06.36%2BPM.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;br /&gt;&lt;/div&gt;As I said the Segment post is great, but it did leave a bit to the imagination and I&#39;m a real literal fellow. So here comes the gritty details.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Dockerfile&lt;/h3&gt;Nothing too too amazing. But you can see we&#39;re also installing Traceview. And then, maybe not too gracefully working around Docker&#39;s inability to run &amp;gt; 1 thing by running start.sh and running 2 things in there. You would probably want to do supervisord if you were being smarter.&lt;br /&gt;&lt;div class=&quot;gistLoad&quot; data-id=&quot;3e9ea335713f04b3b872&quot; id=&quot;gist-3e9ea335713f04b3b872&quot;&gt;&lt;/div&gt;&lt;br /&gt;&lt;a href=&quot;https://1.bp.blogspot.com/-BT4akFGiMOw/VsODRZEYd9I/AAAAAAADKTM/Z46cJzG3fc8/s1600/Screen%2BShot%2B2016-02-16%2Bat%2B3.10.30%2BPM.png&quot; imageanchor=&quot;1&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://1.bp.blogspot.com/-BT4akFGiMOw/VsODRZEYd9I/AAAAAAADKTM/Z46cJzG3fc8/s320/Screen%2BShot%2B2016-02-16%2Bat%2B3.10.30%2BPM.png&quot; /&gt;&lt;/a&gt;  &lt;br /&gt;&lt;h3&gt;Terraform&lt;/h3&gt;Do you like the AWS UI? &amp;nbsp;Do you get a warm fuzzy feeling using a UI to click around and reconfigure your VPCs &amp;amp; ELBs? &amp;nbsp;I sure don&#39;t. &amp;nbsp;Never do that again.&amp;nbsp;&lt;a href=&quot;https://www.terraform.io/&quot;&gt;Terraform&lt;/a&gt;&amp;nbsp;fixes this whole problem and makes me feel warm and fuzzy that I&#39;m not going to end up with some bespoke AWS setup that I can no longer comprehend.&lt;br /&gt;&lt;br /&gt;Check out &lt;a href=&quot;https://github.com/jdwyah/rails-docker-ecs-datadog-traceview-terraform&quot;&gt;rails-docker-ecs-datadog-traceview-terraform&lt;/a&gt;&amp;nbsp;for an AWS setup that gets you:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;ELB&lt;/li&gt;&lt;li&gt;ECS&lt;/li&gt;&lt;li&gt;VPC&lt;/li&gt;&lt;li&gt;Roles &amp;amp; Policies&lt;/li&gt;&lt;li&gt;DataDog agent running in a container on each of your instances&lt;/li&gt;&lt;li&gt;Traceview running next to your rails apps.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;Do NOT blindly put ^ in production. I am bad at security and bad at AWS. &amp;nbsp;The above functions afaict. But I punched security &amp;amp; common decency in the nose a couple times. &amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a href=&quot;http://datadoghq.com/&quot;&gt;DataDog&lt;/a&gt;&lt;/div&gt;&lt;div&gt;You don&#39;t realize how blind most devs are flying until you change companies and no longer have your opentsdb stack, your customer monitoring and alerting solution, your lisp-ish TSDB explorer, your custom Stats-On-The-TV service. Impressively DataDog seems to solve most all of this. You want instance metrics? Docker metrics? ELB metrics? RDS metrics? Custom metrics? Super customizable alerting? Seriously afaict it&#39;s game over and the Dawg won. You get a ridiculous amount for free out of the box. And with the setup above you have a statsd sink listening on udp:8125 that your app can kick any metric it wants to and instantly have it available in the Dawg.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div class=&quot;gistLoad&quot; data-id=&quot;46e894a55b221d881a65&quot; id=&quot;gist-46e894a55b221d881a65&quot;&gt;&lt;/div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a href=&quot;https://www.appneta.com/products/traceview/&quot;&gt;Traceview&lt;/a&gt;&lt;/div&gt;&lt;div&gt;Trace view is a lot like NewRelic, but has the advantage of being able to differentiate your ass from your elbow in the UI. &amp;nbsp;Seriously, look at this.&amp;nbsp;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;br /&gt;&lt;/div&gt;Every single request you get a little blue mark. &amp;nbsp;Great you say, but get this! Drag a rectangle around them and you can slice into those requests, then for each of them you get a full freaking overview of just what happened in that request. Even the SQL. So freaking good.&lt;br /&gt;&lt;br /&gt;Also fwiw if it sounds too good to be true or maybe it only works for my piddly little app I can verify that this also works at scale, with microservices.&lt;br /&gt;&lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://4.bp.blogspot.com/-rKoR8s_vI5k/VsOG5t-O1VI/AAAAAAADKTk/Xi8_GzWnc2Y/s1600/Screen%2BShot%2B2016-02-16%2Bat%2B3.30.17%2BPM.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;337&quot; src=&quot;https://4.bp.blogspot.com/-rKoR8s_vI5k/VsOG5t-O1VI/AAAAAAADKTk/Xi8_GzWnc2Y/s640/Screen%2BShot%2B2016-02-16%2Bat%2B3.30.17%2BPM.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://1.bp.blogspot.com/-z_wK27k5IFw/VsOG1g2Vx7I/AAAAAAADKTg/fmTXsIxA2q0/s1600/Screen%2BShot%2B2016-02-16%2Bat%2B3.30.00%2BPM.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;432&quot; src=&quot;https://1.bp.blogspot.com/-z_wK27k5IFw/VsOG1g2Vx7I/AAAAAAADKTg/fmTXsIxA2q0/s640/Screen%2BShot%2B2016-02-16%2Bat%2B3.30.00%2BPM.png&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;That&#39;s all I&#39;ve got. ECS is pretty awesome so far &amp;amp; something I feel decent taking a bet on, but it&#39;s definitely still young. The big todos left in this stack imho are:   &lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;How do I run rake tasks from cron?&lt;/li&gt;&lt;li&gt;Where do I get a rails console in prod?&lt;/li&gt;&lt;li&gt;A deploy script to twiddle my ECS task versions.&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;Interested in making some of this real life? Come work with me!&amp;nbsp;&lt;a href=&quot;https://www.ezcater.com/home/about/jobs&quot;&gt;ezCater Jobs&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;script type=&quot;text/javascript&quot;&gt;(function() {          // Initialize the load the main script.     try {         initGist();     } catch(e) {        console.log(e);     } })(); &lt;/script&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.jdwyah.com/feeds/1788543450071606610/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9842007&amp;postID=1788543450071606610' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9842007/posts/default/1788543450071606610'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9842007/posts/default/1788543450071606610'/><link rel='alternate' type='text/html' href='http://blog.jdwyah.com/2016/02/ruby-on-rails-on-docker-on-amazon-ecs-w.html' title='Ruby on Rails on Docker on Amazon ECS w/ Terraform &amp; DataDog'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/13347545383502498067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://1.bp.blogspot.com/-Y9sRvM6DMFI/VsOBaLJBj3I/AAAAAAADKTA/Y2chJofWQAs/s72-c/Screen%2BShot%2B2016-02-16%2Bat%2B3.06.36%2BPM.png" height="72" width="72"/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9842007.post-8697093199908423207</id><published>2015-07-07T14:35:00.000-05:00</published><updated>2015-07-07T14:35:23.146-05:00</updated><title type='text'>Dealing with Git Merge Revisions</title><content type='html'>&lt;h3 style=&quot;widows: 1;&quot;&gt;Zen and the Art of Git Chainsaw Maintenance&lt;/h3&gt;&lt;div style=&quot;widows: 1;&quot;&gt;Git is pretty awesome and mind expanding, but I don’t think that anything is quite a mind-blowing as the first time you learn how to revert a merge. There’s a great explanation here:&amp;nbsp;&lt;a href=&quot;https://web.archive.org/web/20111229193713/http://stackoverflow.com/questions/1078146/re-doing-a-reverted-merge-in-git&quot;&gt;http://stackoverflow.com/questions/1078146/re-doing-a-reverted-merge-in-git&lt;/a&gt;&lt;/div&gt;&lt;div style=&quot;widows: 1;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;widows: 1;&quot;&gt;Basically, if you’ve merged a feature in by mistake, you can simply revert the merge to get back to a happy state. The mind bending comes when you decide that the feature is ready to be merged for real. &amp;nbsp;While intuition might tell you to just git merge feature again, what you really want to do is “revert the revert”.&lt;/div&gt;&lt;div style=&quot;widows: 1;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;widows: 1;&quot;&gt;It makes sense, and it’s awesome, and it’s righteously scary in that wonderful way that only git can be.&lt;/div&gt;&lt;div style=&quot;widows: 1;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;widows: 1;&quot;&gt;At PatientsLikeMe we were familiar with this, but we hadn’t had a chance to do it in practice until last week. A branch was merged in prematurely and we successfully reverted.&lt;/div&gt;&lt;div style=&quot;widows: 1;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;widows: 1;&quot;&gt;The new wrinkle that I faced today was that the branch that was merged in and since reverted, is actually a long running branch and development continues on it. I wanted to merge master into this long running branch to stay up to date, but when I did that, I noticed pretty quickly that something was awry. 27 conflicts and a bucket of fail. Worse, my mergetool was consistently picking the wrong side of the merge.&lt;/div&gt;&lt;div style=&quot;widows: 1;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;widows: 1;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;widows: 1;&quot;&gt;Let’s go to the simulated instant replay, sponsored by GitX.&lt;/div&gt;&lt;div&gt;&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;widows: 1;&quot;&gt;This is the state of the repo after we’re reverted our accidental merge.&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://1.bp.blogspot.com/-nZQun4H1ZcU/VZwoROTzCUI/AAAAAAADKMw/ows-duqyoes/s1600/Screen%2BShot%2B2015-07-07%2Bat%2B3.20.29%2BPM.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;http://1.bp.blogspot.com/-nZQun4H1ZcU/VZwoROTzCUI/AAAAAAADKMw/ows-duqyoes/s1600/Screen%2BShot%2B2015-07-07%2Bat%2B3.20.29%2BPM.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;widows: 1;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;widows: 1;&quot;&gt;Here is the repo with more work on both the feature and the master branch.&lt;/span&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://1.bp.blogspot.com/-_-TvCa3bqLE/VZwoRJBg5AI/AAAAAAADKNI/Kh2cdQjq1KA/s1600/Screen%2BShot%2B2015-07-07%2Bat%2B3.22.16%2BPM.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;183&quot; src=&quot;http://1.bp.blogspot.com/-_-TvCa3bqLE/VZwoRJBg5AI/AAAAAAADKNI/Kh2cdQjq1KA/s320/Screen%2BShot%2B2015-07-07%2Bat%2B3.22.16%2BPM.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;widows: 1;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;widows: 1;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;widows: 1;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;div style=&quot;widows: 1;&quot;&gt;So, I’d like to merge master into the feature branch, but that leads to a sorts of erroneous conflicts. Why? Well, because git merge master asks git to merge the revert commit into my feature branch, that’s why. The revert commit essentially contains diffs that say to remove all the early work on feature branch.&amp;nbsp;&lt;/div&gt;&lt;div style=&quot;widows: 1;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;blockquote class=&quot;tr_bq&quot;&gt;&lt;i&gt;It makes sense to apply this to master, but it is a terrible commit to apply to the feature branch. It’s a bit like time travelling and accidentally killing your parents.&lt;/i&gt;&lt;/blockquote&gt;&lt;div style=&quot;widows: 1;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;widows: 1;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;widows: 1;&quot;&gt;So what do we do? We know that we need to ‘revert the revert’ at some point. It turns out that there’s no reason not to do that immediately; we just need a new ‘shim’ branch. We’ll call it master_w_revert_reverted.&lt;/div&gt;&lt;div style=&quot;widows: 1;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;pre class=&quot;brush: plain;&quot; style=&quot;widows: 1;&quot;&gt;git checkout master&lt;br /&gt;git checkout -b master_w_revert_reverted&lt;br /&gt;git revert SHA_OF_THE_MERGE_REVERSION&lt;br /&gt;git commit&lt;br /&gt;&lt;/pre&gt;&lt;pre class=&quot;brush: plain;&quot; style=&quot;widows: 1;&quot;&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://4.bp.blogspot.com/-OOhoaQrgHWE/VZwoRCAoF0I/AAAAAAADKM8/lfVM_x44DDg/s1600/Screen%2BShot%2B2015-07-07%2Bat%2B3.24.03%2BPM.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;160&quot; src=&quot;http://4.bp.blogspot.com/-OOhoaQrgHWE/VZwoRCAoF0I/AAAAAAADKM8/lfVM_x44DDg/s320/Screen%2BShot%2B2015-07-07%2Bat%2B3.24.03%2BPM.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style=&quot;widows: 1;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;pre class=&quot;brush: plain;&quot; style=&quot;widows: 1;&quot;&gt;&lt;span style=&quot;font-family: Times, Times New Roman, serif;&quot;&gt;Now let&#39;s merge this shim into our feature branch.&lt;/span&gt;&lt;/pre&gt;&lt;pre class=&quot;brush: plain;&quot; style=&quot;widows: 1;&quot;&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre class=&quot;brush: plain;&quot; style=&quot;widows: 1;&quot;&gt;git co feature&lt;br /&gt;git merge master_w_revert_reverted&lt;br /&gt;&lt;/pre&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;widows: 1;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;widows: 1;&quot;&gt;Voila! we’ve successfully merged our master branch into the long running feature and we’ve taken care of the ‘revert the revert’ going forward.&lt;/div&gt;&lt;div style=&quot;widows: 1;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;widows: 1;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;widows: 1;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;widows: 1;&quot;&gt;The next time we want to merge from master to the long running feature branch, or indeed from when we’re ready to merge the feature into master, we just merge as we would normally. Our days of reversion are over.&lt;/div&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://2.bp.blogspot.com/-cGW-BCsOh1c/VZwoRgyH6vI/AAAAAAADKNA/gY9F9VfDuRE/s1600/Screen%2BShot%2B2015-07-07%2Bat%2B3.25.47%2BPM.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;208&quot; src=&quot;http://2.bp.blogspot.com/-cGW-BCsOh1c/VZwoRgyH6vI/AAAAAAADKNA/gY9F9VfDuRE/s320/Screen%2BShot%2B2015-07-07%2Bat%2B3.25.47%2BPM.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;widows: 1;&quot;&gt;Until next time, happy merging!&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;widows: 1;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;widows: 1;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;article class=&quot;post&quot; id=&quot;post-330&quot; style=&quot;widows: 1;&quot;&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/article&gt;&lt;section id=&quot;commentarea&quot; style=&quot;widows: 1;&quot;&gt;&lt;/section&gt;&lt;/div&gt; Like this post? Take a look at my side project, &lt;a href=&quot;http://forcerank.it&quot;&gt;ForceRank.it&lt;/a&gt;. &lt;!--HubSpot Call-to-Action Code --&gt;&lt;span class=&quot;hs-cta-wrapper&quot; id=&quot;hs-cta-wrapper-dcfa48b1-e55d-4f86-9c9f-8fb0fcc29e2e&quot;&gt;    &lt;span class=&quot;hs-cta-node hs-cta-dcfa48b1-e55d-4f86-9c9f-8fb0fcc29e2e&quot; id=&quot;hs-cta-dcfa48b1-e55d-4f86-9c9f-8fb0fcc29e2e&quot;&gt;        &lt;!--[if lte IE 8]&gt;&lt;div id=&quot;hs-cta-ie-element&quot;&gt;&lt;/div&gt;&lt;![endif]--&gt;        &lt;a href=&quot;http://cta-redirect.hubspot.com/cta/redirect/193623/dcfa48b1-e55d-4f86-9c9f-8fb0fcc29e2e&quot; &gt;&lt;img class=&quot;hs-cta-img&quot; id=&quot;hs-cta-img-dcfa48b1-e55d-4f86-9c9f-8fb0fcc29e2e&quot; style=&quot;border-width:0px;&quot; src=&quot;https://no-cache.hubspot.com/cta/default/193623/dcfa48b1-e55d-4f86-9c9f-8fb0fcc29e2e.png&quot;  alt=&quot;Help my group make a decision&quot;/&gt;&lt;/a&gt;    &lt;/span&gt;    &lt;script charset=&quot;utf-8&quot; src=&quot;https://js.hscta.net/cta/current.js&quot;&gt;&lt;/script&gt;    &lt;script type=&quot;text/javascript&quot;&gt;        hbspt.cta.load(193623, &#39;dcfa48b1-e55d-4f86-9c9f-8fb0fcc29e2e&#39;);     &lt;/script&gt;&lt;/span&gt;&lt;!-- end HubSpot Call-to-Action Code --&gt;  </content><link rel='replies' type='application/atom+xml' href='http://blog.jdwyah.com/feeds/8697093199908423207/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9842007&amp;postID=8697093199908423207' title='21 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9842007/posts/default/8697093199908423207'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9842007/posts/default/8697093199908423207'/><link rel='alternate' type='text/html' href='http://blog.jdwyah.com/2015/07/dealing-with-git-merge-revisions.html' title='Dealing with Git Merge Revisions'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/13347545383502498067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/-nZQun4H1ZcU/VZwoROTzCUI/AAAAAAADKMw/ows-duqyoes/s72-c/Screen%2BShot%2B2015-07-07%2Bat%2B3.20.29%2BPM.png" height="72" width="72"/><thr:total>21</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9842007.post-79060445652893487</id><published>2014-12-22T10:45:00.001-05:00</published><updated>2014-12-22T11:09:39.769-05:00</updated><title type='text'>What every CEO need to know about Distributed Version Control Systems.</title><content type='html'>Dear Executive Suite,&lt;br /&gt;&lt;br /&gt;You may think that you don&#39;t need to know what &quot;distributed version control systems&quot; (DVCS) means... but you would be wrong to do so.&lt;br /&gt;&lt;br /&gt;Human collaboration is the most critical product of a business whether it be high strategic imperatives or intricacies of interpersonal negotiating and tactics. Surprisingly, the nuts and bolts logistics of how we collaborate, whether it be video chat, meetings, Word Doc, Email threads or Google Doc, play massive roles in shaping the quality and speed of how our teams collaborate.&lt;br /&gt;&lt;br /&gt;These same &quot;communication logistics&quot; are also core to the way software engineers work and the good news is that software engineers have been working on improving these systems for decades. Many of the basic concepts of collaboration have already been adopted by business at large, but the biggest, most important shift we&#39;ve experienced is just at the point where it will start to cross the chasm from tech to business at large. The seismic shift that Git an GitHub have had on the logistics of software engineering &amp;amp; Open Source development in the past 5 years presages a dramatic revolution in the way successful companies are going to operate in the next decade. By understanding the revolution that has recently occurred in DVCS you will be able to get a glimpse of how your business should be operating in 2025.&lt;br /&gt;&lt;br /&gt;The essential insight is that by relinquishing a bit of control over process and focussing on the atomization of good ideas, we&#39;re starting to move away from &#39;the cathedral&#39; and fulfill the promise of &#39;&lt;a href=&quot;http://en.wikipedia.org/wiki/The_Cathedral_and_the_Bazaar&quot;&gt;the bazaar&lt;/a&gt;&#39;. This essay will seek to explain the principles of DVCS and give non-technical readers a sense of how this has revitalized open source development and what that means for the future of business.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;&lt;span style=&quot;font-size: large; font-weight: normal;&quot;&gt;The Evolution of Collaboration: In the Beginning&lt;/span&gt;&lt;/h3&gt;&lt;div&gt;&lt;span style=&quot;font-size: large; font-weight: normal;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;In the beginning, there was no version control. This is probably the system that you grew up on as well. Files were either on your local machine or on the server. If they were local, you needed to send them out as attachments when you wanted others to see them. If you sent it to two people and they each edited it and send it back you were left to reconcile the changes yourself, and send out the revised edition. Alternatively the document may have be on a server in which case everyone can edit the same file, but woe be to those who tried to edit it at the same time, for it was easy to wipe out someone&#39;s changes. Worse, there was no real way to go back. There was no long term undo. If Mary &amp;amp; John open the file at the same time, Mary writes 3 pages and John fixes a typo, but Mary saves before John, then John wipes out everything Mary&#39;s done.&lt;br /&gt;&lt;br /&gt;The &quot;solution&quot; here was to create &quot;read-only&quot; documents and or &quot;lock&quot; documents while they were being edited. While this works, it took all parallelism out of your process, reducing efficiency and limiting your ability to scale.&lt;br /&gt;&lt;br /&gt;The business analog to this is when you had a single author of your new RFP or 2015 Strategy Document. Sure, you could incorporate small feedback, or even perform massive re-writes of sections, but the cost of doing this was high. Eventually inertia wins and everyone just wants the damn thing to be finished, resulting in a subpar product and a stifling of great ideas, since a late-breaking great idea will require enormous logistic effort.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;&lt;span style=&quot;font-size: large; font-weight: normal;&quot;&gt;And then there was light.&lt;/span&gt;&lt;/h3&gt;&lt;div&gt;&lt;span style=&quot;font-size: large; font-weight: normal;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;For our purposes, CVS can be thought of as the first version control system. CVS is a pretty straightforward system where the server is made to save a snapshot of each file every time it is saved. It is easy to go back in time with this system as every version of every file is saved forever. It is also simple to compare what changed between version 1.9 and 1.14 or in a file between two dates.&lt;br /&gt;&lt;br /&gt;For many years this served software developers well. We could all get the canonical version of files from one place and we could easily bring our files up to date. We could then work away locally and once finished we could commit things back to the central repository. When workflows happen in parallel it will always be possible to conflict with other&#39;s work, but these conflicts were now readily apparent and nice interfaces grew up around CVS to allow us to see the differences and perform a merge in an easy and sane way. If your company is using Google Docs or Sharepoint, this is about where you are now. It seems pretty great doesn&#39;t it? &amp;nbsp;Anyone who has collaborated on a Google Doc can attest to the almost infinite superiority of the collaboration in comparison to &quot;the-bad-old-way&quot;.&lt;br /&gt;&lt;br /&gt;But not everyone was happy.&lt;br /&gt;&lt;br /&gt;In fact, one of the more esteemed members of our community, Linus Torvalds (creator of Linux) simply hated version control of the sorts we&#39;ve discussed so far and refused to use them. The reliance on a monolithic centralized repository was &#39;stupid (and ugly)&#39; to paraphrase his thoughts. Most of us mere mortals were still overjoyed not to be overwriting each other&#39;s changes accidentally and delighted that there was ONE central place to get our information. So what were we missing? Why did Linus Torvald hate source control?&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;&lt;span style=&quot;font-size: large; font-weight: normal;&quot;&gt;Branching&lt;/span&gt;&lt;/h3&gt;&lt;div&gt;&lt;span style=&quot;font-size: large; font-weight: normal;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;Branching is what happens when a user wants to pursue an idea that is not directly reconcilable with the mainstream. As an example, let&#39;s pretend that you&#39;re tasked with doing a comprehensive, interconnected rewrite of all the companies procedures. It is going to be long and difficult process. It will take weeks, and will be in a half baked and not ready for prime-time state for much of that time. That means we can&#39;t just commit it to the central repository, because then the unbaked efforts would be all mixed in to the current procedures. But unfortunately that was the only way we had to collaborate with others...&lt;br /&gt;&lt;br /&gt;This is a great time for a branch. A branch is basically an extra sandbox for working on a side project, which we hope will be eventually merged back into the trunk, or master of our system.&lt;br /&gt;&lt;br /&gt;Branching was possible in CVS, but it wasn&#39;t simple (and indeed is not a feature of SharePoint or Google Docs). Because it was possible however, many of us didn&#39;t realize just what we were missing when Linus and friends came down from the mountain top claiming that they had made branching a million times better. It sounded ok, but not revolutionary. But we were wrong.&lt;br /&gt;&lt;br /&gt;Easy branching frees your mind to think creatively, because there&#39;s far less pain to taking a thought and expounding on it in a new branch. This happens in two forms, local branches and distributed branches and this is where things get interesting.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Local branches&lt;/h4&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;I have a great idea in the middle of the night to change our marketing and communications theme. Awake at 3 in the morning, I create a local branch and get the thoughts out, boldly cutting out projects, rewording the slogan and changing the branding. &amp;nbsp;The next day I tweak it some more. On the third day I come to my senses and realize that it&#39;s terrible and I&#39;m able to delete the branch without anyone knowing about my wild idea. Reputation saved. Creativity fostered.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Distributed branches&lt;/h4&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;Alternatively, on day three my wild idea might seem like it&#39;s still got legs, but I&#39;d like to get feedback on it. I can easily push the local branch out to colleagues who I&#39;d like to take a look. This branch has now become a distributed project, de-centralized from the main line of day to day operations. If a co worker likes what they see, but wants to take things in another direction, they can easily branch this branch. In fact there is NO center. That &#39;main central branch&#39; &amp;nbsp;I told you about? That&#39;s simply a convention. No branch is inherently better than any other. Readers of &#39;The Cathedral and the Bazaar&#39; will recognize that we are firmly in bazaar territory now.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;&lt;span style=&quot;font-size: large;&quot;&gt;Trust &amp;gt; Authority&lt;/span&gt;&lt;/h3&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;Without a distributed system, the normal way of controlling the system is through something we call Access Control Lists. These are pretty straightforward tools which stores a list of permissions for every user eg &quot;Bob can edit Sales Documents&quot;. While they&#39;re conceptually simple, it may be fair to say that they&#39;re the single underlying failure behind innumerable business inefficiencies and Open Source to-date. Access control is a crude instrument. A user can change something or they can&#39;t. And therein lies the trouble. What if an employee spots a typo on the HR docs? Should they have write access to the centralized system? Certainly not. Should they be forced to find the appropriate change request form and file it with their manager? Certainly not. If they can fix it, they should be able to go ahead and do that right then. An access control list simply can&#39;t be fine grained enough to allow spelling fixes, but not policy changes. Distributed systems fix this problem dead. I find an error and change it. I don&#39;t have access, so I simply request a &#39;pull&#39; to the maintainer, who can easily see that this is a simple change and merge it in.&lt;br /&gt;&lt;br /&gt;This is a small example, but it underlies everything. When we rely on trust (with transparency) we gain huge efficiencies over simple coarse authority based systems.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;&lt;span style=&quot;font-size: large;&quot;&gt;The best and brightest: Management of a Distributed System&lt;/span&gt;&lt;/h3&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;This may sound like chaos. Amazingly it isn&#39;t. While it would seem that without a central arbiter many projects would fall into a chaos of conflicting ideas, in fact, the nature of the process seems to have led to fewer fractures in the software community, not more. I would argue that this is because distributed systems make the process more transparent and meritocratic. If you have a good idea you can create a branch to show it to the world, which can then collaborate on it. &lt;i&gt;When it is difficult to reconcile and merge ideas, creating change within an organization requires dramatic action.&lt;/i&gt; Think about the creation of Czar&#39;s, skunk works &amp;amp; splinter groups. A process that requires end-runs like these is an admission of a process that is failing to allow creativity.&lt;br /&gt;&lt;br /&gt;The fact that ad hoc &#39;skunk works&#39; are a mode of failure is not a new concept, but the central insight of the DVCS alternative is that we need not create a robust &#39;structure of change&#39; or a &#39;continual improvement&#39; system, but rather that we ought make &lt;i&gt;everything&lt;/i&gt; a skunk work. With distributed systems, everyone&#39;s work is reduced to splinters, but the operating principle is that the best splinters should be picked up and merged back into the trunk.&lt;br /&gt;&lt;br /&gt;On the Linux project, the master branch, the source of authority for all, is simply Linus Torvald&#39;s master branch. He relies on a number of lieutenants to pick up the best splinters from their subdomain. The master branch become more of an all-star team of ideas then a singular overarching concept.&lt;br /&gt;&lt;br /&gt;Please do not make the mistake of thinking that software is somehow a special case for this sort of collaboration. It may seem crazy to think that meaningful coordination could be achieved if your corporation were to throw open the gates to this sort of bazaar-like collaboration, but consider that software engineering is the very epitome of an instance in which all parts must work seamlessly together. A miscue between sales &amp;amp; marketing may result in sub-optimal performance, but &lt;i&gt;even a single byte of miscue&lt;/i&gt; between software components can easily spell a total system failure and this is the ancestral environment from which the bazaar comes.&lt;br /&gt;&lt;br /&gt;The CEO of the future will perform much the same roll that Linus does for Linux. He is the final quality checker and reviewer of branches as they work their way into the corporate master. He relies on the community create nuggets of insight and brilliance. He trusts his lieutenants to find these gems and elevate them to his attention.&lt;br /&gt;&lt;h3&gt;&lt;/h3&gt;&lt;h3&gt;&lt;br /&gt;&lt;/h3&gt;&lt;h3&gt;Take away: What we&#39;ve learned.&amp;nbsp;&lt;/h3&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;ul&gt;&lt;li&gt;Lowering the barrier to experiment expands creativity.&amp;nbsp;&lt;/li&gt;&lt;li&gt;Allow experiments to see the light of day and they will accrete adherents &amp;amp; spur still other ideas into existence.&amp;nbsp;&lt;/li&gt;&lt;li&gt;The key to reaping benefits from the splinters of ideas the ability to merge piecemeal concepts efficiently.&lt;/li&gt;&lt;li&gt;Authority based systems are poor at integrating insights from the Bazaar.&amp;nbsp;&lt;/li&gt;&lt;li&gt;Trust based relationships, openness, and transparency are good frameworks for merging concepts and insights.&lt;/li&gt;&lt;li&gt;Management of distributed systems transformed from an authoritarian role to the &quot;collector &amp;amp; curator&quot; of the organizations best ideas.&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;&lt;/h3&gt;&lt;h3&gt;&lt;br /&gt;&lt;/h3&gt;&lt;h3&gt;Checklist for success today:&lt;/h3&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;h4&gt;Easily access and edit information:&lt;/h4&gt;Can an curious manager pull P&amp;amp;L statements on a Saturday afternoon in order to better understand their departments role in the overall business? Business secrets keep competitors and employees in the same dark. Erecting barriers to information takes effort and has no chance of producing value.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Public experimentation:&lt;/h4&gt;Can an employee easily distribute a proposal to the rest of the company? Can experiments effectively snowball or do they require the innovator to push the ball all the way up the hill? If your sales manager in Topeka has an idea in the middle of the night for an advertisement / promotion, can they add this quickly to the list of concepts in the marketing department?&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Good merging:&lt;/h4&gt;What are the barriers between an employee with a good idea and a change in the process? Do managers regularly integrate the work and experimentations of subordinates and can subordinated collaborate together without supervision?&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;br /&gt;What to read next: &amp;nbsp;&lt;a href=&quot;http://blog.forcerank.it/counting-votes-is-hard&quot;&gt;Counting Votes is Hard&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;!--HubSpot Call-to-Action Code --&gt;&lt;span class=&quot;hs-cta-wrapper&quot; id=&quot;hs-cta-wrapper-c425b4a3-af31-4694-a15b-2bcd4b03e3e7&quot;&gt;    &lt;span class=&quot;hs-cta-node hs-cta-c425b4a3-af31-4694-a15b-2bcd4b03e3e7&quot; id=&quot;hs-cta-c425b4a3-af31-4694-a15b-2bcd4b03e3e7&quot;&gt;        &lt;!--[if lte IE 8]&gt;&lt;div id=&quot;hs-cta-ie-element&quot;&gt;&lt;/div&gt;&lt;![endif]--&gt;        &lt;a href=&quot;http://cta-redirect.hubspot.com/cta/redirect/193623/c425b4a3-af31-4694-a15b-2bcd4b03e3e7&quot;&gt;&lt;img class=&quot;hs-cta-img&quot; id=&quot;hs-cta-img-c425b4a3-af31-4694-a15b-2bcd4b03e3e7&quot; src=&quot;https://no-cache.hubspot.com/cta/default/193623/c425b4a3-af31-4694-a15b-2bcd4b03e3e7.png&quot; style=&quot;border-width: 0px;&quot; /&gt;&lt;/a&gt;    &lt;/span&gt;    &lt;script charset=&quot;utf-8&quot; src=&quot;https://js.hscta.net/cta/current.js&quot;&gt;&lt;/script&gt;        &lt;script type=&quot;text/javascript&quot;&gt;            hbspt.cta.load(193623, &#39;c425b4a3-af31-4694-a15b-2bcd4b03e3e7&#39;);         &lt;/script&gt;&lt;/span&gt;&lt;!-- end HubSpot Call-to-Action Code --&gt; </content><link rel='replies' type='application/atom+xml' href='http://blog.jdwyah.com/feeds/79060445652893487/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9842007&amp;postID=79060445652893487' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9842007/posts/default/79060445652893487'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9842007/posts/default/79060445652893487'/><link rel='alternate' type='text/html' href='http://blog.jdwyah.com/2014/12/what-every-ceo-need-to-know-about.html' title='What every CEO need to know about Distributed Version Control Systems.'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/13347545383502498067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9842007.post-8228157398443680675</id><published>2014-11-16T10:41:00.001-05:00</published><updated>2014-11-16T10:42:20.255-05:00</updated><title type='text'>Lactobacillus - Lactobasilisk</title><content type='html'>&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://4.bp.blogspot.com/-jNq6bhsRXAM/VGjFfa-S4BI/AAAAAAADKGA/yJHPeskTd7s/s1600/lactobasilisk.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;http://4.bp.blogspot.com/-jNq6bhsRXAM/VGjFfa-S4BI/AAAAAAADKGA/yJHPeskTd7s/s1600/lactobasilisk.jpg&quot; height=&quot;202&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.jdwyah.com/feeds/8228157398443680675/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9842007&amp;postID=8228157398443680675' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9842007/posts/default/8228157398443680675'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9842007/posts/default/8228157398443680675'/><link rel='alternate' type='text/html' href='http://blog.jdwyah.com/2014/11/lactobacillus-lactobasilisk.html' title='Lactobacillus - Lactobasilisk'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/13347545383502498067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/-jNq6bhsRXAM/VGjFfa-S4BI/AAAAAAADKGA/yJHPeskTd7s/s72-c/lactobasilisk.jpg" height="72" width="72"/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9842007.post-5490442365508348215</id><published>2014-11-16T10:28:00.003-05:00</published><updated>2014-11-16T10:28:47.653-05:00</updated><title type='text'>Tired &amp; Frustrated?</title><content type='html'>&lt;a href=&quot;http://3.bp.blogspot.com/-CsZRh7SmaZk/VGjCgC84JMI/AAAAAAADKF0/jWEHTQYqqlg/s1600/IMG_7076.jpg&quot; imageanchor=&quot;1&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;http://3.bp.blogspot.com/-CsZRh7SmaZk/VGjCgC84JMI/AAAAAAADKF0/jWEHTQYqqlg/s400/IMG_7076.jpg&quot; /&gt;&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.jdwyah.com/feeds/5490442365508348215/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9842007&amp;postID=5490442365508348215' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9842007/posts/default/5490442365508348215'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9842007/posts/default/5490442365508348215'/><link rel='alternate' type='text/html' href='http://blog.jdwyah.com/2014/11/tired-frustrated.html' title='Tired &amp; Frustrated?'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/13347545383502498067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/-CsZRh7SmaZk/VGjCgC84JMI/AAAAAAADKF0/jWEHTQYqqlg/s72-c/IMG_7076.jpg" height="72" width="72"/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9842007.post-3164141410591083390</id><published>2014-09-11T15:50:00.003-05:00</published><updated>2014-09-11T15:53:54.420-05:00</updated><title type='text'>CORS for Rails / Heroku &amp; Cloudfront (for dummies)</title><content type='html'>So starting today all your fonts don&#39;t load. Because CORS.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;No &#39;Access-Control-Allow-Origin&#39; header is present on the requested resource.&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Here&#39;s what to do.&lt;br /&gt;&lt;br /&gt;1) Remember your CloudFront password.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;2) Edit your behavior&lt;br /&gt;&lt;br /&gt;&amp;nbsp;   &lt;a href=&quot;http://3.bp.blogspot.com/-w_CF55y7s-Q/VBIKb_WISLI/AAAAAAADKCk/ynC4K08BTKc/s1600/Screen%2BShot%2B2014-09-11%2Bat%2B4.46.28%2BPM.png&quot; imageanchor=&quot;1&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;http://3.bp.blogspot.com/-w_CF55y7s-Q/VBIKb_WISLI/AAAAAAADKCk/ynC4K08BTKc/s320/Screen%2BShot%2B2014-09-11%2Bat%2B4.46.28%2BPM.png&quot; height=&quot;133&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;3) Forwarding headers -&amp;gt; whitelist&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://4.bp.blogspot.com/-Q_2dZstEC1o/VBIKbycjcmI/AAAAAAADKCo/_zRW_K3utJw/s1600/Screen%2BShot%2B2014-09-11%2Bat%2B4.47.26%2BPM.png&quot; imageanchor=&quot;1&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;http://4.bp.blogspot.com/-Q_2dZstEC1o/VBIKbycjcmI/AAAAAAADKCo/_zRW_K3utJw/s320/Screen%2BShot%2B2014-09-11%2Bat%2B4.47.26%2BPM.png&quot; height=&quot;400&quot; width=&quot;370&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;4) Add &quot;Origin&quot;&lt;br /&gt;&lt;br /&gt;5) Add rack-cors to Gemfile&lt;br /&gt;&lt;br /&gt;gem &#39;rack-cors&#39;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;6) Add stuff to config.ru&lt;br /&gt;&lt;br /&gt;require &#39;rack/cors&#39;&lt;br /&gt;use Rack::Cors do&lt;br /&gt;&lt;br /&gt;&amp;nbsp; # allow all origins in development&lt;br /&gt;&amp;nbsp; allow do&lt;br /&gt;&amp;nbsp; &amp;nbsp; origins &#39;*&#39;&lt;br /&gt;&amp;nbsp; &amp;nbsp; resource &#39;*&#39;,&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; :headers =&amp;gt; :any,&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; :methods =&amp;gt; [:get, :post, :delete, :put, :options]&lt;br /&gt;&amp;nbsp; end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;7) Deploy&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;8) Try to forget about CORS&lt;br /&gt;&lt;br /&gt;&lt;br /&gt; Did that work? Why not try my tool &lt;a href=&quot;http://forcerank.it&quot;&gt;ForceRank.it&lt;/a&gt;, a prioritization tool for product teams that lets you rank choices. It even lets you import a Trello board!   &lt;!--HubSpot Call-to-Action Code --&gt;&lt;span class=&quot;hs-cta-wrapper&quot; id=&quot;hs-cta-wrapper-1ff78b82-b11e-4dd1-9189-0d4ad23e6c6e&quot;&gt;    &lt;span class=&quot;hs-cta-node hs-cta-1ff78b82-b11e-4dd1-9189-0d4ad23e6c6e&quot; id=&quot;hs-cta-1ff78b82-b11e-4dd1-9189-0d4ad23e6c6e&quot;&gt;        &lt;!--[if lte IE 8]&gt;&lt;div id=&quot;hs-cta-ie-element&quot;&gt;&lt;/div&gt;&lt;![endif]--&gt;        &lt;a href=&quot;http://cta-redirect.hubspot.com/cta/redirect/193623/1ff78b82-b11e-4dd1-9189-0d4ad23e6c6e&quot;&gt;&lt;img class=&quot;hs-cta-img&quot; id=&quot;hs-cta-img-1ff78b82-b11e-4dd1-9189-0d4ad23e6c6e&quot; src=&quot;https://no-cache.hubspot.com/cta/default/193623/1ff78b82-b11e-4dd1-9189-0d4ad23e6c6e.png&quot; style=&quot;border-width: 0px;&quot; /&gt;&lt;/a&gt;    &lt;/span&gt;    &lt;script charset=&quot;utf-8&quot; src=&quot;https://js.hscta.net/cta/current.js&quot;&gt;&lt;/script&gt;        &lt;script type=&quot;text/javascript&quot;&gt;            hbspt.cta.load(193623, &#39;1ff78b82-b11e-4dd1-9189-0d4ad23e6c6e&#39;);         &lt;/script&gt;&lt;/span&gt;&lt;!-- end HubSpot Call-to-Action Code --&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.jdwyah.com/feeds/3164141410591083390/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9842007&amp;postID=3164141410591083390' title='16 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9842007/posts/default/3164141410591083390'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9842007/posts/default/3164141410591083390'/><link rel='alternate' type='text/html' href='http://blog.jdwyah.com/2014/09/cors-for-rails-heroku-cloudfront-for.html' title='CORS for Rails / Heroku &amp; Cloudfront (for dummies)'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/13347545383502498067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/-w_CF55y7s-Q/VBIKb_WISLI/AAAAAAADKCk/ynC4K08BTKc/s72-c/Screen%2BShot%2B2014-09-11%2Bat%2B4.46.28%2BPM.png" height="72" width="72"/><thr:total>16</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9842007.post-2497160544495561182</id><published>2013-08-31T07:59:00.000-05:00</published><updated>2014-12-01T22:11:02.348-05:00</updated><title type='text'>The Statistics of Monopoly with Respect to Cornish Game Hen Provisioning: Part 2 &quot;Probability is a bitch&quot;</title><content type='html'>In part one we figured out the average likelihood of a guest ending up on any particular square. So what&#39;s the problem with that?&lt;br /&gt;&lt;br /&gt;The problem can be summed up in one, easy to remember, phrase: &quot;YOLO&quot;.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;YOLO&lt;/h2&gt;So we did 100,000 simulations, that seems like it should be enough right? Maybe we should do one million to be more accurate? Nope, that&#39;s not the problem. The problem is that we&#39;re not throwing one million dinner parties. Or even 100,000. We&#39;re only throwing one dinner party. And frankly, anything could happen.&lt;br /&gt;&lt;br /&gt;Just because the expected value over the long run says that we&#39;ll need 5.44x the cornish game hens, this doesn&#39;t mean that the actually dinner party won&#39;t have 30 guests just haphazardly roll 12&#39;s on their first roll, throwing our expectations into turmoil.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;So what is a Culinary Experience creator to do?&lt;/h2&gt;It turns out that Monte Carlo works really well here too. Since we recorded all 100,000 simulations, we can ask the question &quot;How many game hens do I need to buy in order to have enough in 95% of simulations.&quot; Obviously we can change the percentage we use here too. The average, is actually just saying, &quot;How many game hens do I need to buy in order to have enough in 50% of simulations.&quot; Which is pretty much like saying &quot;How can I run out of game hens HALF OF THE TIME!&quot;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Gimme Code:&lt;/h2&gt;Get an array of the pretty names for the squares.&lt;br /&gt;&lt;br /&gt;&lt;div class=&quot;gistLoad&quot; data-id=&quot;6395450&quot; id=&quot;gist-6395450&quot;&gt;&lt;/div&gt;&lt;br /&gt;SQUARES is something like:&lt;br /&gt;&lt;div class=&quot;gistLoad&quot; data-id=&quot;6395452&quot; id=&quot;gist-6395452&quot;&gt;&lt;/div&gt;What we really want is to put all the Baltic Avenues together. Put all the B&amp;amp;O Railroads together. You know, kinda &#39;zip&#39; each of these arrays together.&lt;br /&gt;&lt;br /&gt;&lt;div class=&quot;gistLoad&quot; data-id=&quot;6395455&quot; id=&quot;gist-6395455&quot;&gt;&lt;/div&gt;&lt;br /&gt;Now zipped is:&lt;br /&gt;&lt;br /&gt;&lt;div class=&quot;gistLoad&quot; data-id=&quot;6395457&quot; id=&quot;gist-6395457&quot;&gt;&lt;/div&gt;&lt;br /&gt;Then we process the results:&lt;br /&gt;&lt;div class=&quot;gistLoad&quot; data-id=&quot;6395458&quot; id=&quot;gist-6395458&quot;&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;And:&lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://4.bp.blogspot.com/-jcNcJkWgcuc/UiE4kBMWs9I/AAAAAAAC_i4/1WT6n8zj1b8/s1600/Screen+Shot+2013-08-25+at+9.33.58+PM.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;199&quot; src=&quot;http://4.bp.blogspot.com/-jcNcJkWgcuc/UiE4kBMWs9I/AAAAAAAC_i4/1WT6n8zj1b8/s320/Screen+Shot+2013-08-25+at+9.33.58+PM.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;These results have the average in column one. The 95th percentile in column two and the max observed in column three. So what&#39;s the result? Well, say we run 4 moves. The average on chance was 5.44x. But if we want to provision enough food with 95% certainty that there will be enough, we&#39;re going to need 9x. And out of 100,000 simulations, one simulation had 15x the number of cornish game hens on Chance. That sure doesn&#39;t make it easy to plan the menu.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;PS&lt;/h2&gt;But what if we want to play by the monopoly rules? Well, then we just change our move function and run things again. This time you can see the super high prevalence of Jail and a bit of a secondary bump ~7 squares after Jail.&lt;br /&gt;&lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://4.bp.blogspot.com/-VzTFKDntReQ/UiE4xdxfLkI/AAAAAAAC_i8/G0m_dw4U0XA/s1600/Screen+Shot+2013-08-25+at+9.34.33+PM.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;198&quot; src=&quot;http://4.bp.blogspot.com/-VzTFKDntReQ/UiE4xdxfLkI/AAAAAAAC_i8/G0m_dw4U0XA/s320/Screen+Shot+2013-08-25+at+9.34.33+PM.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;script type=&quot;text/javascript&quot;&gt;(function() {          // Initialize the load the main script.     try {         initGist();     } catch(e) {        console.log(e);     } })(); &lt;/script&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.jdwyah.com/feeds/2497160544495561182/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9842007&amp;postID=2497160544495561182' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9842007/posts/default/2497160544495561182'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9842007/posts/default/2497160544495561182'/><link rel='alternate' type='text/html' href='http://blog.jdwyah.com/2013/08/the-statistics-of-monopoly-with-respect_31.html' title='The Statistics of Monopoly with Respect to Cornish Game Hen Provisioning: Part 2 &quot;Probability is a bitch&quot;'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/13347545383502498067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/-jcNcJkWgcuc/UiE4kBMWs9I/AAAAAAAC_i4/1WT6n8zj1b8/s72-c/Screen+Shot+2013-08-25+at+9.33.58+PM.png" height="72" width="72"/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9842007.post-7194173987044760989</id><published>2013-08-30T19:18:00.006-05:00</published><updated>2014-12-01T22:10:41.940-05:00</updated><title type='text'>The Statistics of Monopoly with Respect to Cornish Game Hen Provisioning</title><content type='html'>&lt;br /&gt;Let&#39;s pretend that you need to throw a once in a lifetime culinary spectacle in Panama. If you&#39;re &lt;a href=&quot;http://arazor.tumblr.com/&quot;&gt;@ashinyknife&lt;/a&gt;, this will be no problem.&lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://24.media.tumblr.com/4c6ee14a22e4260209d7d30c33727a5a/tumblr_mruemg51L51qznpm2o1_1280.jpg&quot; imageanchor=&quot;1&quot; style=&quot;clear: right; float: right; margin-bottom: 1em; margin-left: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;http://24.media.tumblr.com/4c6ee14a22e4260209d7d30c33727a5a/tumblr_mruemg51L51qznpm2o1_1280.jpg&quot; height=&quot;200&quot; width=&quot;200&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Let&#39;s pretend you decide upon a monopoly theme. Generally, N guests start out on go, roll dice and end up on a monopoly square.&lt;br /&gt;&lt;br /&gt;Let&#39;s pretend that each square has a wholy different gastronomic creation on it.&lt;br /&gt;&lt;br /&gt;Given the above, how many cornish game hens should we expect to buy for St Charles place? How much caviar will we need to supply the B&amp;amp;O railroad?&lt;br /&gt;&lt;br /&gt;These are the important questions that we will set out to answer today.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Probability&lt;/h2&gt;Our first approach might look something like this: &lt;a href=&quot;http://statistics.about.com/od/ProbHelpandTutorials/a/Probability-And-Monopoly.htm&quot;&gt;http://statistics.about.com/od/ProbHelpandTutorials/a/Probability-And-Monopoly.htm&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Basic probability, round 1 is reasonable. Round 2 makes sense.. oh gawd round 3 starts to get hard to keep track of.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Monte Carlo&lt;/h2&gt;So what should we do? It seems to me that the appropriate technique to use here is Monte Carlo simulation. What is Monte Carlo? Honestly Monte Carlo should be pretty attractive to those of us for whom probability 101 was a long time ago. Basically &quot;Monte Carlo simulation&quot; means &quot;let&#39;s just see what really happens&quot;. Say I ask you to figure out the probability that when flipping a coin 100 times I get at least one run of 10 heads. You&#39;ve got two choices:&lt;br /&gt;&lt;br /&gt;1) Figure out the appropriate math.&lt;br /&gt;2) Flip a coin 100 times. Figure out if you get 10 heads in a row. Do this 1 million times and calculate the percentage of times when it was true.&lt;br /&gt;&lt;br /&gt;Option 2 is monte carlo.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Time for computers&lt;/h2&gt;This is really pretty easy to code up. Create a two-dimension array. Dimension one will keep track of each simulation. Dimension two will track each of the 40 Monopoly squares.&lt;br /&gt;&lt;br /&gt;&lt;div class=&quot;gistLoad&quot; data-id=&quot;6395419&quot; id=&quot;gist-6395419&quot;&gt;&lt;/div&gt;For each simulation, for each user in the simulation, for each of the moves, move them around the board.&lt;br /&gt;&lt;div class=&quot;gistLoad&quot; data-id=&quot;6395416&quot; id=&quot;gist-6395416&quot;&gt;&lt;/div&gt;&lt;br /&gt;To move them around the board we just roll two dice, and move us along.&lt;br /&gt;&lt;br /&gt;&lt;div class=&quot;gistLoad&quot; data-id=&quot;6395411&quot; id=&quot;gist-6395411&quot;&gt;&lt;/div&gt;&lt;br /&gt;Finally it&#39;s just a matter of averaging up the values for each square in our simulation and voila&lt;br /&gt;&lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://1.bp.blogspot.com/-F4NpZOQYgIQ/UiDsANbIRGI/AAAAAAAC_ik/AUgc0zvQ7Ts/s1600/Screen+Shot+2013-08-30+at+11.34.01+AM.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;http://1.bp.blogspot.com/-F4NpZOQYgIQ/UiDsANbIRGI/AAAAAAAC_ik/AUgc0zvQ7Ts/s400/Screen+Shot+2013-08-30+at+11.34.01+AM.png&quot; height=&quot;356&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Summary&lt;/h2&gt;So now the big question: Did we answer our original question? Do we know how much food to buy?&lt;br /&gt;Say we&#39;re planning on serving 4 courses. Do we feel figuring out how many hens we would need for an even distribution, then buying 5.44x the cornish game hens for &#39;Chance&#39; and 3.8x the caviar for the B&amp;amp;O railroad?&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;What do you think?&lt;/h2&gt;See my answer in &lt;a href=&quot;http://blog.jdwyah.com/2013/08/the-statistics-of-monopoly-with-respect_31.html&quot;&gt;The Statistics of Monopoly with Respect to Cornish Game Hen Provisioning: Part 2 &quot;Probability is a bitch&quot;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;script type=&quot;text/javascript&quot;&gt;(function() {          // Initialize the load the main script.     try {         initGist();     } catch(e) {        console.log(e);     } })(); &lt;/script&gt;  &lt;!--HubSpot Call-to-Action Code --&gt;&lt;span class=&quot;hs-cta-wrapper&quot; id=&quot;hs-cta-wrapper-442e278b-0cd7-401c-adda-1a24062505be&quot;&gt;    &lt;span class=&quot;hs-cta-node hs-cta-442e278b-0cd7-401c-adda-1a24062505be&quot; id=&quot;hs-cta-442e278b-0cd7-401c-adda-1a24062505be&quot;&gt;        &lt;!--[if lte IE 8]&gt;&lt;div id=&quot;hs-cta-ie-element&quot;&gt;&lt;/div&gt;&lt;![endif]--&gt;        &lt;a href=&quot;http://cta-redirect.hubspot.com/cta/redirect/193623/442e278b-0cd7-401c-adda-1a24062505be&quot;&gt;&lt;img class=&quot;hs-cta-img&quot; id=&quot;hs-cta-img-442e278b-0cd7-401c-adda-1a24062505be&quot; src=&quot;https://no-cache.hubspot.com/cta/default/193623/442e278b-0cd7-401c-adda-1a24062505be.png&quot; style=&quot;border-width: 0px;&quot; /&gt;&lt;/a&gt;    &lt;/span&gt;    &lt;script charset=&quot;utf-8&quot; src=&quot;https://js.hscta.net/cta/current.js&quot;&gt;&lt;/script&gt;        &lt;script type=&quot;text/javascript&quot;&gt;            hbspt.cta.load(193623, &#39;442e278b-0cd7-401c-adda-1a24062505be&#39;);         &lt;/script&gt;&lt;/span&gt;&lt;!-- end HubSpot Call-to-Action Code --&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.jdwyah.com/feeds/7194173987044760989/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9842007&amp;postID=7194173987044760989' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9842007/posts/default/7194173987044760989'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9842007/posts/default/7194173987044760989'/><link rel='alternate' type='text/html' href='http://blog.jdwyah.com/2013/08/the-statistics-of-monopoly-with-respect.html' title='The Statistics of Monopoly with Respect to Cornish Game Hen Provisioning'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/13347545383502498067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/-F4NpZOQYgIQ/UiDsANbIRGI/AAAAAAAC_ik/AUgc0zvQ7Ts/s72-c/Screen+Shot+2013-08-30+at+11.34.01+AM.png" height="72" width="72"/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9842007.post-7442244057197408035</id><published>2013-08-16T09:58:00.001-05:00</published><updated>2014-07-17T22:42:58.436-05:00</updated><title type='text'>hbase scan: batch vs cache</title><content type='html'>&lt;span style=&quot;font-family: inherit;&quot;&gt;Here&#39;s today&#39;s contribution to the Internet:&lt;/span&gt;&lt;span style=&quot;font-family: inherit;&quot;&gt;tl;dr When it comes to HBase scanner settings, you want caching, not batchsize.&lt;/span&gt;&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;/span&gt;&lt;span style=&quot;font-family: inherit;&quot;&gt;Maybe this is totally clear to everyone else. But for those of us who are &#39;newer to hbase&#39; I can never quite remember what I&#39;m doing. &lt;/span&gt; &lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://3.bp.blogspot.com/-H6tR_qWNAsk/Ug46LUpKYJI/AAAAAAAC-zc/LdabzDKt2n0/s1600/i-have-no-idea-what-i-m-doing.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;248&quot; src=&quot;http://3.bp.blogspot.com/-H6tR_qWNAsk/Ug46LUpKYJI/AAAAAAAC-zc/LdabzDKt2n0/s320/i-have-no-idea-what-i-m-doing.jpg&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;span style=&quot;font-family: inherit;&quot;&gt;Say you&#39;ve got this code:&lt;/span&gt;&lt;br /&gt;&lt;blockquote class=&quot;tr_bq&quot;&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;Scan s = new Scan(startKey);&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;s.setCaching(foo);&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;s.setBatch(bar);&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;ResultScanner scanner = new ResultScanner(s);&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;for (final Result r : scanner) {&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&amp;nbsp; //stuff&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;font-size: x-small;&quot;&gt;&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;div&gt;But you&#39;re clever and you don&#39;t want to do RPC calls to HBase for every row. You might even say you&#39;d like to &#39;batch&#39; the results from your scanner.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;span style=&quot;font-family: inherit;&quot;&gt;So you read &lt;a href=&quot;http://hbase.apache.org/apidocs/org/apache/hadoop/hbase/client/Scan.html&quot;&gt;http://hbase.apache.org/apidocs/org/apache/hadoop/hbase/client/Scan.html&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;/span&gt; &lt;span style=&quot;font-family: Courier New, Courier, monospace; font-size: x-small;&quot;&gt;public void &lt;b&gt;setBatch&lt;/b&gt;(int&amp;nbsp;batch)&lt;/span&gt;&lt;br /&gt;&lt;dl style=&quot;white-space: normal;&quot;&gt;&lt;dd&gt;&lt;span style=&quot;font-family: Courier New, Courier, monospace; font-size: x-small;&quot;&gt;Set the maximum number of values to return for each call to next()&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Courier New, Courier, monospace; font-size: x-small;&quot;&gt;&lt;/span&gt;&lt;/dd&gt;&lt;dd&gt;&lt;/dd&gt;&lt;dd&gt;&lt;/dd&gt;&lt;span style=&quot;font-family: Courier New, Courier, monospace; font-size: x-small;&quot;&gt;public void &lt;b&gt;setCaching&lt;/b&gt;(int&amp;nbsp;caching)&lt;/span&gt;&lt;dl&gt;&lt;dd&gt;&lt;span style=&quot;font-family: Courier New, Courier, monospace; font-size: x-small;&quot;&gt;Set the number of rows for caching that will be passed to scanners. If not set, the default setting from&amp;nbsp;&lt;a href=&quot;http://hbase.apache.org/apidocs/org/apache/hadoop/hbase/client/HTable.html#getScannerCaching()&quot;&gt;&lt;code&gt;HTable.getScannerCaching()&lt;/code&gt;&lt;/a&gt;&amp;nbsp;will apply. Higher caching values will enable faster scanners but will use more memory.&lt;/span&gt;&lt;/dd&gt;&lt;/dl&gt;&lt;/dl&gt;&lt;/div&gt;&lt;div&gt;Annnd.... not sure. I mean, I only want one Result every time I call &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;next()&lt;/span&gt;in my iterator, right? What would &amp;nbsp;a number &amp;gt;1 even mean?&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;And I&#39;m sure I shouldn&#39;t set &#39;caching&#39; that sounds like it will &#39;cache&#39; something. I want to read the real stuff.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;But you do want caching. Caching is how many things come back in a batch from your scanner.&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Ok. Fine. Caching got named poorly. &amp;nbsp;What is batch?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Batch is in case you have super wide rows. Say you have 250 columns. Batch of 100 would give your iterator:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;Iteration 1: Result id 0. Columns 0-99&lt;/li&gt;&lt;li&gt;Iteration 2: Result id 0. Columns 100-199&lt;/li&gt;&lt;li&gt;Iteration 3: Result id 0. Columns 200-249&lt;/li&gt;&lt;li&gt;Iteration 4: Result id 1. Columns 0-99&lt;/li&gt;&lt;li&gt;Iteration 5: Result id 1. Columns 100-199&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;div style=&quot;font-family: Times; white-space: normal;&quot;&gt;&lt;/div&gt;&lt;div style=&quot;font-family: Times; white-space: normal;&quot;&gt;Or at least that&#39;s what &lt;a href=&quot;http://twitter.com/monkeyatlarge&quot;&gt;http://twitter.com/monkeyatlarge&lt;/a&gt; told me.&lt;/div&gt;&lt;div style=&quot;font-family: Times; white-space: normal;&quot;&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;dl style=&quot;font-family: Times; white-space: normal;&quot;&gt;&lt;/dl&gt;&lt;!--HubSpot Call-to-Action Code --&gt;&lt;span class=&quot;hs-cta-wrapper&quot; id=&quot;hs-cta-wrapper-1ff78b82-b11e-4dd1-9189-0d4ad23e6c6e&quot;&gt;    &lt;span class=&quot;hs-cta-node hs-cta-1ff78b82-b11e-4dd1-9189-0d4ad23e6c6e&quot; id=&quot;hs-cta-1ff78b82-b11e-4dd1-9189-0d4ad23e6c6e&quot;&gt;        &lt;!--[if lte IE 8]&gt;&lt;div id=&quot;hs-cta-ie-element&quot;&gt;&lt;/div&gt;&lt;![endif]--&gt;        &lt;a href=&quot;http://cta-redirect.hubspot.com/cta/redirect/193623/1ff78b82-b11e-4dd1-9189-0d4ad23e6c6e&quot;&gt;&lt;img class=&quot;hs-cta-img&quot; id=&quot;hs-cta-img-1ff78b82-b11e-4dd1-9189-0d4ad23e6c6e&quot; style=&quot;border-width:0px;&quot; src=&quot;https://no-cache.hubspot.com/cta/default/193623/1ff78b82-b11e-4dd1-9189-0d4ad23e6c6e.png&quot; /&gt;&lt;/a&gt;    &lt;/span&gt;    &lt;script charset=&quot;utf-8&quot; src=&quot;https://js.hscta.net/cta/current.js&quot;&gt;&lt;/script&gt;        &lt;script type=&quot;text/javascript&quot;&gt;            hbspt.cta.load(193623, &#39;1ff78b82-b11e-4dd1-9189-0d4ad23e6c6e&#39;);         &lt;/script&gt;&lt;/span&gt;&lt;!-- end HubSpot Call-to-Action Code --&gt; </content><link rel='replies' type='application/atom+xml' href='http://blog.jdwyah.com/feeds/7442244057197408035/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9842007&amp;postID=7442244057197408035' title='237 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9842007/posts/default/7442244057197408035'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9842007/posts/default/7442244057197408035'/><link rel='alternate' type='text/html' href='http://blog.jdwyah.com/2013/08/hbase-scan-batch-vs-cache.html' title='hbase scan: batch vs cache'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/13347545383502498067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/-H6tR_qWNAsk/Ug46LUpKYJI/AAAAAAAC-zc/LdabzDKt2n0/s72-c/i-have-no-idea-what-i-m-doing.jpg" height="72" width="72"/><thr:total>237</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9842007.post-27939617620139583</id><published>2013-06-12T09:24:00.000-05:00</published><updated>2014-04-12T12:58:43.926-05:00</updated><title type='text'>Github gists on blogger</title><content type='html'>&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://octodex.github.com/images/original.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;320&quot; src=&quot;http://octodex.github.com/images/original.jpg&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;span class=&quot;webkit-html-tag&quot; style=&quot;font-family: monospace; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class=&quot;webkit-html-tag&quot; style=&quot;font-family: monospace; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;webkit-html-tag&quot; style=&quot;font-family: inherit; white-space: pre-wrap;&quot;&gt;I&#39;ve been using https://github.com/moski/gist-Blogger/ to display gists in blogger like:&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;span class=&quot;webkit-html-tag&quot; style=&quot;white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;div class=&quot;gistLoad&quot; data-id=&quot;5561359&quot; id=&quot;gist-5561359&quot;&gt;&lt;/div&gt;&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;span class=&quot;webkit-html-tag&quot; style=&quot;white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class=&quot;webkit-html-tag&quot; style=&quot;white-space: pre-wrap;&quot;&gt;The only problem with this was that I was including a link to the raw github which was getting a mime type of text/plain, which caused some browsers to not load the JS. The solution is to use github pages apparently, but that a small pita to setup, so I hereby share the results of my toils.&lt;/span&gt;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;webkit-html-tag&quot; style=&quot;font-family: monospace; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class=&quot;webkit-html-tag&quot; style=&quot;font-family: inherit; white-space: pre-wrap;&quot;&gt;&lt;b&gt;Step 1:&lt;/b&gt; Create your gist&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: inherit;&quot;&gt;&lt;span class=&quot;webkit-html-tag&quot; style=&quot;white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class=&quot;webkit-html-tag&quot; style=&quot;white-space: pre-wrap;&quot;&gt;&lt;b&gt;Step 2:&lt;/b&gt; Add a div to your blog post&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;webkit-html-tag&quot; style=&quot;white-space: pre-wrap;&quot;&gt;&lt;span style=&quot;font-family: monospace;&quot;&gt;&amp;lt;div class=&quot;gistLoad&quot; data-id=&quot;5561359&quot; id=&quot;gist-5561359&quot;&amp;gt; &amp;lt;/div&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;webkit-html-tag&quot; style=&quot;font-family: monospace; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class=&quot;webkit-html-tag&quot; style=&quot;font-family: inherit; white-space: pre-wrap;&quot;&gt;&lt;b&gt;Step 3:&lt;/b&gt; Add this script to your blog post&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;webkit-html-tag&quot; style=&quot;font-family: monospace; white-space: pre-wrap;&quot;&gt;&amp;lt;script &lt;span class=&quot;webkit-html-attribute-name&quot;&gt;src&lt;/span&gt;=&quot;&lt;a class=&quot;webkit-html-attribute-value webkit-html-resource-link&quot; href=&quot;http://jdwyah.github.io/gist-Blogger/javascript/gistLoader.js&quot; target=&quot;_blank&quot;&gt;http://jdwyah.github.io/gist-Blogger/javascript/gistLoader.js&lt;/a&gt;&quot; &lt;span class=&quot;webkit-html-attribute-name&quot;&gt;type&lt;/span&gt;=&quot;&lt;span class=&quot;webkit-html-attribute-value&quot;&gt;text/javascript&lt;/span&gt;&quot;&amp;gt;&lt;/span&gt;&lt;span class=&quot;webkit-html-tag&quot; style=&quot;font-family: monospace; white-space: pre-wrap;&quot;&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class=&quot;webkit-html-tag&quot; style=&quot;font-family: monospace; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class=&quot;webkit-html-tag&quot; style=&quot;font-family: monospace; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class=&quot;webkit-html-tag&quot; style=&quot;font-family: inherit; white-space: pre-wrap;&quot;&gt;&lt;b&gt;Step 4:&lt;/b&gt; Profit&lt;/span&gt;  &lt;script src=&quot;http://jdwyah.github.io/gist-Blogger/javascript/gistLoader.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;&lt;br/&gt;&lt;br/&gt;&lt;!--HubSpot Call-to-Action Code --&gt;&lt;span class=&quot;hs-cta-wrapper&quot; id=&quot;hs-cta-wrapper-442e278b-0cd7-401c-adda-1a24062505be&quot;&gt;    &lt;span class=&quot;hs-cta-node hs-cta-442e278b-0cd7-401c-adda-1a24062505be&quot; id=&quot;hs-cta-442e278b-0cd7-401c-adda-1a24062505be&quot;&gt;        &lt;!--[if lte IE 8]&gt;&lt;div id=&quot;hs-cta-ie-element&quot;&gt;&lt;/div&gt;&lt;![endif]--&gt;        &lt;a href=&quot;http://cta-redirect.hubspot.com/cta/redirect/193623/442e278b-0cd7-401c-adda-1a24062505be&quot;&gt;&lt;img class=&quot;hs-cta-img&quot; id=&quot;hs-cta-img-442e278b-0cd7-401c-adda-1a24062505be&quot; style=&quot;border-width:0px;&quot; src=&quot;https://no-cache.hubspot.com/cta/default/193623/442e278b-0cd7-401c-adda-1a24062505be.png&quot; /&gt;&lt;/a&gt;    &lt;/span&gt;    &lt;script charset=&quot;utf-8&quot; src=&quot;https://js.hscta.net/cta/current.js&quot;&gt;&lt;/script&gt;        &lt;script type=&quot;text/javascript&quot;&gt;            hbspt.cta.load(193623, &#39;442e278b-0cd7-401c-adda-1a24062505be&#39;);         &lt;/script&gt;&lt;/span&gt;&lt;!-- end HubSpot Call-to-Action Code --&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.jdwyah.com/feeds/27939617620139583/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9842007&amp;postID=27939617620139583' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9842007/posts/default/27939617620139583'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9842007/posts/default/27939617620139583'/><link rel='alternate' type='text/html' href='http://blog.jdwyah.com/2013/06/github-gists-on-blogger.html' title='Github gists on blogger'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/13347545383502498067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9842007.post-601643061813002419</id><published>2013-05-11T16:08:00.001-05:00</published><updated>2013-06-12T09:02:34.491-05:00</updated><title type='text'>Postgres Common Table Expression Super Example (with a hot little window function action too)</title><content type='html'>&lt;br /&gt;&lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://2.bp.blogspot.com/-tu6-KV_i0xY/UT-6QRv7bvI/AAAAAAABqF0/kdzZiLPdKGY/s1600/Screen+Shot+2013-03-12+at+7.27.43+PM.png&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;200&quot; src=&quot;http://2.bp.blogspot.com/-tu6-KV_i0xY/UT-6QRv7bvI/AAAAAAABqF0/kdzZiLPdKGY/s200/Screen+Shot+2013-03-12+at+7.27.43+PM.png&quot; width=&quot;163&quot; /&gt;&lt;/a&gt;&lt;/div&gt;Common table expressions are a PostgreSQL user&#39;s best friend. Let me show you them.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;The Example Problem:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Let&#39;s take a look at how to build SymptomsLikeMe. This is something that would look at a bunch of health reports and figure out who has symptoms that are most like mine.&lt;br /&gt;&lt;br /&gt;The data model is pretty simple. A user has many symptom surveys. Each symptom survey has a &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;symptom_id&lt;/span&gt; (ie pain, nausea, fatigue) and a &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;severity&lt;/span&gt; (1,2,3,4).&lt;br /&gt;&lt;br /&gt;So, here&#39;s the challenge in more details. Given all of a user&#39;s latest symptom surveys (1 for fatigue, 4 for pain), compare that to all other latest symptom surveys and produce a similarity score (least square). Return the top 10 closest symptom reports.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;So what needs to happen?&lt;/h3&gt;&lt;ol&gt;&lt;li&gt;Get all of the latests symptom surveys&lt;/li&gt;&lt;li&gt;Get just this users&#39;s latest symptom survey&lt;/li&gt;&lt;li&gt;Compare that to all other latest symptom surveys and produce a similarity score (using least squares).&lt;/li&gt;&lt;li&gt;Return the top 10 closest symptom reports.&lt;/li&gt;&lt;/ol&gt;&lt;h3&gt;How to do it?&lt;/h3&gt;&lt;div&gt;Well, that&#39;s a lot to do, right? Let&#39;s look at a couple approaches.&lt;/div&gt;&lt;ul&gt;&lt;li&gt;In Ruby? Wow. There are ~= 1,788,141 symptom reports eh? So we serialize them all into ruby and... &amp;nbsp;no.&lt;/li&gt;&lt;li&gt;We&#39;ll denormalize it! &amp;nbsp; Urm... I&#39;m not really sure what that would mean. We explode the combinatorial space of all symptoms to symptoms.... &amp;nbsp;ouch.&lt;/li&gt;&lt;li&gt;??????&lt;/li&gt;&lt;/ul&gt;&lt;h4&gt;PostgreSQL!!!!&lt;/h4&gt;&lt;h4&gt;&lt;span style=&quot;font-weight: normal;&quot;&gt;Let&#39;s forget trying to do the whole problem in one massive statement and just do the four steps we listed out above.&amp;nbsp;&lt;/span&gt;&lt;/h4&gt;&lt;h4&gt;Step 1 &quot;Get all of the latest symptom surveys&quot;&lt;/h4&gt;&lt;div class=&quot;gistLoad&quot; data-id=&quot;251749&quot; id=&quot;gist-251749&quot; style=&quot;display: none;&quot;&gt;&lt;/div&gt;&lt;div class=&quot;gistLoad&quot; data-id=&quot;5561359&quot; id=&quot;gist-5561359&quot;&gt;&lt;/div&gt;&lt;br /&gt;huh? Why not use a &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;not exist &lt;/span&gt;well, because not exists have a bad habit of returning more than one row when things starts colliding and we have to tie break collisions or suffer the consequences of duplicate counts. &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;rank = 1 &lt;/span&gt;guarantees us that we&#39;ll only get 1 result, no matter how many dupes there are.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Step 2 &quot;Given this user&#39;s latest symptom survey&quot;&lt;/h4&gt;&lt;div class=&quot;gistLoad&quot; data-id=&quot;5561371&quot; id=&quot;gist-5561371&quot;&gt;&lt;/div&gt;&lt;br /&gt;&lt;h4&gt;&lt;span style=&quot;font-weight: normal;&quot;&gt;easy peasy.&lt;/span&gt;&lt;/h4&gt;&lt;h4&gt;Step 3 &quot;compare that to all other latest symptom surveys and produce a similarity score&quot;&lt;/h4&gt;&lt;div class=&quot;gistLoad&quot; data-id=&quot;5561373&quot; id=&quot;gist-5561373&quot;&gt;&lt;/div&gt;&lt;h4&gt;&lt;span style=&quot;font-weight: normal;&quot;&gt;So to compute the similarity, we need to compare our user, vs each user. If only there were a way to JOIN our user&#39;s info onto each row of a another user&#39;s data... oo a join!&lt;/span&gt;&lt;/h4&gt;&lt;div&gt;&lt;span style=&quot;font-weight: normal;&quot;&gt;Ok, so that&#39;s the join and then we just want the difference of the two columns &#39;minus&#39; and we square that (for least squares) and um, sum().&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-weight: normal;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span style=&quot;font-weight: normal;&quot;&gt;Easy peasy!!&lt;/span&gt;&lt;/div&gt;&lt;h4&gt;Step 4 &quot;Return the top 10 closest symptom reports.&quot;&lt;/h4&gt;&lt;div class=&quot;gistLoad&quot; data-id=&quot;5561374&quot; id=&quot;gist-5561374&quot;&gt;&lt;/div&gt;&lt;br /&gt;&lt;h4&gt;All together now&lt;/h4&gt;&lt;div&gt;&lt;a href=&quot;https://gist.github.com/jdwyah/5561378#file-pgtips-sql&quot;&gt;https://gist.github.com/jdwyah/5561378#file-pgtips-sql&lt;/a&gt;&lt;/div&gt;&lt;div&gt;But then we need all 4 pieces of this to work together and... omg we are done.&lt;/div&gt;&lt;div class=&quot;gistLoad&quot; data-id=&quot;5561378&quot; id=&quot;gist-5561378&quot;&gt;&lt;/div&gt;&lt;br /&gt;&lt;h4&gt;Conclusion&lt;/h4&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;CommonTableExpressions work to decompose SQL problems into manageable hunks.&lt;/li&gt;&lt;li&gt;Read Steps 1-4 backwards and it&#39;s just a bunch of unfunded mandates that you need to fill in.&lt;/li&gt;&lt;li&gt;I really didn&#39;t tell you how window functions work. Sorry. They&#39;re great. But they need another blog post to really explain. See&amp;nbsp;http://www.postgresql.org/docs/9.1/static/tutorial-window.html which is really pretty good.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;script src=&quot;http://jdwyah.github.io/gist-Blogger/javascript/gistLoader.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.jdwyah.com/feeds/601643061813002419/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9842007&amp;postID=601643061813002419' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9842007/posts/default/601643061813002419'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9842007/posts/default/601643061813002419'/><link rel='alternate' type='text/html' href='http://blog.jdwyah.com/2013/05/postgres-common-table-expression-super.html' title='Postgres Common Table Expression Super Example (with a hot little window function action too)'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/13347545383502498067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/-tu6-KV_i0xY/UT-6QRv7bvI/AAAAAAABqF0/kdzZiLPdKGY/s72-c/Screen+Shot+2013-03-12+at+7.27.43+PM.png" height="72" width="72"/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9842007.post-2787131738001505304</id><published>2013-05-11T15:21:00.001-05:00</published><updated>2013-05-13T16:36:25.781-05:00</updated><title type='text'>Decoding the &quot;Two Weeks&quot; estimate</title><content type='html'>&lt;b id=&quot;docs-internal-guid-7b846b2e-952c-6ceb-e521-700da36f3905&quot;&gt;&lt;/b&gt;&lt;br /&gt;&lt;h2&gt;&lt;span id=&quot;docs-internal-guid-7b846b2e-952c-6ceb-e521-700da36f3905&quot;&gt;&lt;span style=&quot;font-family: Arial;&quot;&gt;&lt;span style=&quot;font-size: large; line-height: 17px; white-space: pre-wrap;&quot;&gt;The Psychology of Overconfidence&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;&lt;span id=&quot;docs-internal-guid-7b846b2e-952c-6ceb-e521-700da36f3905&quot;&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;Dan Milstein has a nice write up of his thoughts on estimation: &lt;a href=&quot;http://ow.ly/kmROs&quot;&gt;Coding, Fast and Slow: Developers and the Psychology of Overconfidence&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;b id=&quot;docs-internal-guid-7b846b2e-952c-6ceb-e521-700da36f3905&quot;&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;&lt;span id=&quot;docs-internal-guid-7b846b2e-952c-6ceb-e521-700da36f3905&quot;&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;To try to summarize,&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;span id=&quot;docs-internal-guid-7b846b2e-952c-6ceb-e521-700da36f3905&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;&lt;/div&gt;&lt;span id=&quot;docs-internal-guid-7b846b2e-952c-6ceb-e521-700da36f3905&quot;&gt;&lt;/span&gt;&lt;ol&gt;&lt;span id=&quot;docs-internal-guid-7b846b2e-952c-6ceb-e521-700da36f3905&quot;&gt;&lt;li style=&quot;font-weight: bold;&quot;&gt;&lt;span id=&quot;docs-internal-guid-7b846b2e-952c-6ceb-e521-700da36f3905&quot; style=&quot;font-weight: normal;&quot;&gt;&lt;div dir=&quot;ltr&quot; style=&quot;display: inline !important; line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&quot;Writing Software = Learning Something You Don’t Know When You Start&quot;&lt;/span&gt;&lt;/div&gt;&lt;/span&gt;&lt;/li&gt;&lt;li style=&quot;font-weight: bold;&quot;&gt;&lt;b id=&quot;docs-internal-guid-7b846b2e-952c-6ceb-e521-700da36f3905&quot; style=&quot;font-weight: normal;&quot;&gt;&lt;div dir=&quot;ltr&quot; style=&quot;display: inline !important; line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;&quot;&gt; We are systematically, provably, overconfident.&lt;/span&gt;&lt;/div&gt;&lt;/b&gt;&lt;/li&gt;&lt;li style=&quot;font-weight: bold;&quot;&gt;&lt;b id=&quot;docs-internal-guid-7b846b2e-952c-6ceb-e521-700da36f3905&quot; style=&quot;font-weight: normal;&quot;&gt;&lt;div dir=&quot;ltr&quot; style=&quot;display: inline !important; line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;That said, we can get decent at estimating things that will take ~0-4 hours.&lt;/span&gt;&lt;/div&gt;&lt;/b&gt;&lt;/li&gt;&lt;li style=&quot;font-weight: bold;&quot;&gt;&lt;b id=&quot;docs-internal-guid-7b846b2e-952c-6ceb-e521-700da36f3905&quot; style=&quot;font-weight: normal;&quot;&gt;&lt;div dir=&quot;ltr&quot; style=&quot;display: inline !important; line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;But there&#39;s no way to get good at quick-estimation of things &amp;gt; 8 hours, because you need really quick feedback loops to hone this skill.&lt;/span&gt;&lt;/div&gt;&lt;/b&gt;&lt;/li&gt;&lt;li style=&quot;font-weight: bold;&quot;&gt;&lt;b id=&quot;docs-internal-guid-7b846b2e-952c-6ceb-e521-700da36f3905&quot; style=&quot;font-weight: normal;&quot;&gt;&lt;div dir=&quot;ltr&quot; style=&quot;display: inline !important; line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;Sadly adding up 100 4 hour tasks does not equal an accurate estimate of a large project.&lt;/span&gt;&lt;/div&gt;&lt;/b&gt;&lt;/li&gt;&lt;/span&gt;&lt;/ol&gt;&lt;span id=&quot;docs-internal-guid-7b846b2e-952c-6ceb-e521-700da36f3905&quot;&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;/span&gt;&lt;div dir=&quot;ltr&quot; style=&quot;font-weight: normal; line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;So I totally agree that there&#39;s value to using &#39;System I&#39; to make quick gut check estimates on small things. And I agree that spending very much time deeply estimating a project with &#39;System II&#39; is pretty useless.&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;/span&gt;&lt;div dir=&quot;ltr&quot; style=&quot;font-weight: normal; line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;What I want to try to defend is the &quot;2 week&quot;, &quot;1 month&quot; size gut check estimates. I&#39;m definitely not going to argue that they&#39;re something to bet money on, but I think that used properly they can be useful.&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;font-weight: normal;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;/span&gt;&lt;h2&gt;&lt;span style=&quot;font-family: Arial; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;span style=&quot;font-size: large;&quot;&gt;Decoding the proverbial &quot;Two Weeks&quot;&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;&lt;div dir=&quot;ltr&quot; style=&quot;line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;So here&#39;s my &lt;i&gt;&lt;b&gt;secret decoder ring for programmer estimates&lt;/b&gt;&lt;/i&gt;. &quot;Two weeks&lt;i style=&quot;font-weight: normal;&quot;&gt;&quot;&lt;/i&gt;&lt;span style=&quot;font-weight: normal;&quot;&gt; really means &quot;In two weeks, I&#39;ll be able to tell you what is really happening&quot;. Maybe 50% of the time that&#39;s because it you will have &lt;/span&gt;&lt;i style=&quot;font-weight: bold;&quot;&gt;actual working software&lt;/i&gt;&lt;span style=&quot;font-weight: normal;&quot;&gt;. But the rest of the time it means you&#39;ll have an engineer who now better understands why this will take another month. Or six. Or simply a day of cleanup.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;font-weight: normal;&quot;&gt;&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;font-weight: normal;&quot;&gt;&lt;b id=&quot;docs-internal-guid-7b846b2e-952c-6ceb-e521-700da36f3905&quot; style=&quot;font-weight: normal;&quot;&gt;&lt;/b&gt;&lt;/div&gt;&lt;blockquote class=&quot;tr_bq&quot; style=&quot;font-weight: bold;&quot;&gt;&lt;b id=&quot;docs-internal-guid-7b846b2e-952c-6ceb-e521-700da36f3905&quot; style=&quot;font-weight: normal;&quot;&gt;&lt;span style=&quot;font-size: 15px; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;&quot;Two weeks&lt;i&gt;&quot;&lt;/i&gt; really means: &quot;In two weeks, I&#39;ll be able to tell you what is really happening&quot;. &lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;/span&gt;&lt;h4 style=&quot;font-weight: bold;&quot;&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;So how can this help you?&lt;/span&gt;&lt;/h4&gt;&lt;div dir=&quot;ltr&quot; style=&quot;font-weight: normal; line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;I may doubt an engineer&#39;s confidence in their estimation, but I feel a lot better about relying on their hatred of inefficiency. And I think that&#39;s part of what you&#39;re getting with a &quot;2 week estimate.&quot; You&#39;re getting &quot;Anything less than 2 weeks is going to be an inefficient use of my time.&quot;&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;/span&gt;&lt;div dir=&quot;ltr&quot; style=&quot;font-weight: normal; line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;So how do we translate a developer saying &quot;2 months&quot;? This is big. So big that it&#39;s going to take me two months to figure out the scope of what this thing is. That&#39;s right, you want an accurate estimate of Project X I&#39;ve got news for you. If somebody says &quot;2 months&quot; they just told you it will take &quot;2 months&quot; to have an accurate estimate.&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;/span&gt;&lt;h4 style=&quot;font-weight: bold;&quot;&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;Is there any good news?&lt;/span&gt;&lt;/h4&gt;&lt;div dir=&quot;ltr&quot; style=&quot;font-weight: normal; line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;Yes! If we change what we hear I think estimates can actually speed up process and reduce churn from shifting priorities. Take the developer&#39;s &quot;2 weeks&quot; then don&#39;t bug them for 2 weeks. If you are going to ask them a question about schedule reduce it to this simple one: &quot;what percent sure are you that this will be done&quot;. 80% means things are good. A seasoned developer will say 80% even if the code is written and tested and sales has signed off, and the CEO loves it, but marketing just wants to take &quot;a quick look at the copy&quot;. Because a sesoned developer has seen 20% of their &quot;done&quot; projects still slip right here.&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;/span&gt;&lt;div dir=&quot;ltr&quot; style=&quot;font-weight: normal; line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;If the developer says they&#39;re only 50% sure you can start planning the reprioritizatuon meeting. But leave the engineers doing what they&#39;re doing. Make sure they&#39;re focussed on the totality of the problem. And at the end of their proverbial &quot;two weeks&quot; you will have a concrete and legitimate estimation about your project.&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;font-family: Arial, Helvetica, sans-serif; font-size: large; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;How to Frame &quot;2 Week&quot;+ Projects&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; font-weight: bold; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;div dir=&quot;ltr&quot; style=&quot;font-weight: normal; line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;So if we decide to be honest with ourselves and re-defined the nature of &quot;two weeks&quot; projects, is that the best we can do? Actually I think we can reap even greater rewards by clearly framing projects for developers in this light. If we say &quot;You said &#39;2 weeks&#39;? Ok, do project X, you have 2 weeks&quot; we are likely to get: a whole bunch of code, slapped together in the last half of the second week, a feature that appears to work, but has an unknown number of bugs and has not been user tested and may or may not really be on the right track.&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;/span&gt;&lt;div dir=&quot;ltr&quot; style=&quot;font-weight: normal; line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;However if we say &quot;Work on project X, you have 2 weeks to report back to me what it&#39;s going to take to ship this with 95% confidence that it&#39;s a big win for customers&quot;. Well I think you get a really different result. I think you&#39;re going to have an engineer inclined to think critically about the problem, not about how to deliver &quot;something&quot; in &quot;2 weeks&quot;. And what does that mean? Well if they&#39;re any good it means you&#39;re going to get a combination of design work, code spikes, feasability and a list of distinct manageable 4 hour tasks that aren&#39;t finished yet.&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;/span&gt;&lt;div dir=&quot;ltr&quot; style=&quot;font-weight: normal; line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;In my experience, estimates up to 2 developers &amp;amp; 2 weeks can be relatively accurate about getting &#39;something&#39; shipped. But they absolutely require an &quot;after-party&quot; story to clean up. Baking this into the expectation from the outset can help engineers focus on the most critical bits first. Whether that&#39;s ensuring the API behaves properly, spiking out the critical path, or badgering the customer to figure out whether the feature is of any use at all.&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; font-weight: normal; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;/span&gt;&lt;div dir=&quot;ltr&quot; style=&quot;font-weight: normal; line-height: 1.15; margin-bottom: 0pt; margin-top: 0pt;&quot;&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;In closing, I say to you &quot;Go forth and shout your estimate from your hip!&quot;. (Just tell your PM what you really mean)&lt;/span&gt;&lt;/div&gt;&lt;div style=&quot;font-weight: normal;&quot;&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://3.bp.blogspot.com/-hXMkKmmeews/UY6oIMW8_HI/AAAAAAACJSc/PFLAEw9lxOU/s1600/Screen+Shot+2013-05-11+at+4.19.56+PM.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;320&quot; src=&quot;http://3.bp.blogspot.com/-hXMkKmmeews/UY6oIMW8_HI/AAAAAAACJSc/PFLAEw9lxOU/s320/Screen+Shot+2013-05-11+at+4.19.56+PM.png&quot; width=&quot;262&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-family: Arial; font-size: xx-small; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;P.S. I should perhaps point out that this is all based on previous jobs. I haven&#39;t actually &#39;estimated&#39; anything in the past 9 months at my new job. We just &#39;do&#39; stuff. Crazy I know.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-family: Arial; font-size: 15px; vertical-align: baseline; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;/span&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.jdwyah.com/feeds/2787131738001505304/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9842007&amp;postID=2787131738001505304' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9842007/posts/default/2787131738001505304'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9842007/posts/default/2787131738001505304'/><link rel='alternate' type='text/html' href='http://blog.jdwyah.com/2013/05/decoding-two-weeks-estimate.html' title='Decoding the &quot;Two Weeks&quot; estimate'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/13347545383502498067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/-hXMkKmmeews/UY6oIMW8_HI/AAAAAAACJSc/PFLAEw9lxOU/s72-c/Screen+Shot+2013-05-11+at+4.19.56+PM.png" height="72" width="72"/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9842007.post-3162134388333094076</id><published>2013-02-08T12:34:00.001-05:00</published><updated>2013-06-12T09:29:34.553-05:00</updated><title type='text'>Mock HBase for Unit Testing</title><content type='html'>&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://2.bp.blogspot.com/-rc0dd7gA9bw/URU2-fQUoDI/AAAAAAABomY/_2vr-xp-ekk/s1600/Apache+HBase.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;http://2.bp.blogspot.com/-rc0dd7gA9bw/URU2-fQUoDI/AAAAAAABomY/_2vr-xp-ekk/s1600/Apache+HBase.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;h2&gt;HBase Checklist:&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;Reliably store terabytes of data across umpteen cloudy shards? &amp;nbsp; Check.&amp;nbsp;&lt;/li&gt;&lt;li&gt;Backend for all your map reduce needs? &amp;nbsp; Check.&amp;nbsp;&lt;/li&gt;&lt;li&gt;Failover across region servers? &amp;nbsp; Check.&amp;nbsp;&lt;/li&gt;&lt;li&gt;Still work locally after your laptop goes to sleep? &amp;nbsp; Not so much.&amp;nbsp;&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;&lt;br /&gt;One repercussion of HBase&#39;s recalcitrance is that I find local development can be a bit of a pita when tests written against an HBase instance that needs a restarting everytime I get coffee.&lt;br /&gt;&lt;br /&gt;Beyond that it would be nice to be able to write some unit tests against HBase and not worry about configuring it. What I really want is a Mock implementation of HBase that just runs in memory.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Mocking HBase for fun &amp;amp; Profit&lt;/h2&gt;&lt;br /&gt;Happily there&#39;s a great gist out there which does just this. Thanks, Internet, you&#39;re the best. And here&#39;s the gist&amp;nbsp;&lt;a href=&quot;https://gist.github.com/agaoglu/613217&quot;&gt;https://gist.github.com/agaoglu/613217&lt;/a&gt;. I&#39;m not sure if it&#39;s perfect, but it&#39;s worked for whatever I&#39;ve thrown at it so far.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class=&quot;gistLoad&quot; data-id=&quot;613217&quot; id=&quot;gist-613217&quot;&gt;Loading ....&lt;/div&gt;&lt;script src=&quot;http://jdwyah.github.io/gist-Blogger/javascript/gistLoader.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.jdwyah.com/feeds/3162134388333094076/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9842007&amp;postID=3162134388333094076' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9842007/posts/default/3162134388333094076'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9842007/posts/default/3162134388333094076'/><link rel='alternate' type='text/html' href='http://blog.jdwyah.com/2013/02/mock-hbase-for-unit-testing.html' title='Mock HBase for Unit Testing'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/13347545383502498067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/-rc0dd7gA9bw/URU2-fQUoDI/AAAAAAABomY/_2vr-xp-ekk/s72-c/Apache+HBase.png" height="72" width="72"/><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9842007.post-104698105854956011</id><published>2012-08-25T11:59:00.001-05:00</published><updated>2013-02-19T15:35:08.885-05:00</updated><title type='text'>Patella Video from RailsConf live</title><content type='html'>&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;http://www.confreaks.com/videos/883-railsconf2012-patella-it-s-memoization-into-memcached-calculated-in-the-background-with-resque&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;254&quot; src=&quot;http://2.bp.blogspot.com/-oIkei-yVwv4/UDkDggCocTI/AAAAAAAACWw/gXNRQa8FL64/s320/Screen%2BShot%2B2012-08-25%2Bat%2B12.54.57%2BPM.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;Patella: Memoization into memcached via resque.&lt;br /&gt;&lt;br /&gt;Woot! The video of my &lt;a href=&quot;http://www.confreaks.com/videos/883-railsconf2012-patella-it-s-memoization-into-memcached-calculated-in-the-background-with-resque&quot;&gt;RailsConf talk&lt;/a&gt; is up on Confreaks.  Happily PLM is actually using the &lt;a href=&quot;https://github.com/patientslikeme/patella&quot;&gt; patella gem&lt;/a&gt; in production now too, so you can go check that out too.  In unrelated news I&#39;m going to be checking into Demosthenes School for Mumblers.  &lt;br /&gt;&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.jdwyah.com/feeds/104698105854956011/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9842007&amp;postID=104698105854956011' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9842007/posts/default/104698105854956011'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9842007/posts/default/104698105854956011'/><link rel='alternate' type='text/html' href='http://blog.jdwyah.com/2012/08/patella-video-from-railsconf-live.html' title='Patella Video from RailsConf live'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/13347545383502498067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://2.bp.blogspot.com/-oIkei-yVwv4/UDkDggCocTI/AAAAAAAACWw/gXNRQa8FL64/s72-c/Screen%2BShot%2B2012-08-25%2Bat%2B12.54.57%2BPM.png" height="72" width="72"/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9842007.post-5039302102069005204</id><published>2012-06-25T11:41:00.000-05:00</published><updated>2012-06-25T11:41:03.047-05:00</updated><title type='text'>Patella</title><content type='html'>I can&#39;t believe I forgot to self-promote after my RailsConf talk. The talk isn&#39;t up yet on Confreaks, but you can get a teaser video &lt;a href=&quot;http://vimeo.com/41780773&quot;&gt;In the Spotlight with Jeff Dwyer on Vimeo&lt;/a&gt;.   &lt;a href=&quot;http://vimeo.com/41780773&quot; imageanchor=&quot;1&quot; style=&quot;clear:left; float:left;margin-right:1em; margin-bottom:1em&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;180&quot; width=&quot;320&quot; src=&quot;http://1.bp.blogspot.com/-CmHrDnI65XI/T-iUINdW_II/AAAAAAAABPs/6WJKzOn9Zjw/s320/Screen%2Bshot%2B2012-06-25%2Bat%2B12.38.14%2BPM.png&quot; /&gt;&lt;/a&gt; Additionally I put the PPT up on SlideShare here: &lt;a href=&quot;http://www.slideshare.net/jdwyah/patella-railsconf-2012 &quot;&gt;Memoization into Memcached done in Resque&lt;/a&gt;.  Enjoy :)</content><link rel='replies' type='application/atom+xml' href='http://blog.jdwyah.com/feeds/5039302102069005204/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9842007&amp;postID=5039302102069005204' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9842007/posts/default/5039302102069005204'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9842007/posts/default/5039302102069005204'/><link rel='alternate' type='text/html' href='http://blog.jdwyah.com/2012/06/patella.html' title='Patella'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/13347545383502498067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/-CmHrDnI65XI/T-iUINdW_II/AAAAAAAABPs/6WJKzOn9Zjw/s72-c/Screen%2Bshot%2B2012-06-25%2Bat%2B12.38.14%2BPM.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9842007.post-3389448856372436880</id><published>2011-04-06T13:52:00.001-05:00</published><updated>2011-04-06T13:53:35.805-05:00</updated><title type='text'>WillPaginate in Half the Time</title><content type='html'>Finally got around to writing up a cool PostgreSQL trick on the PatientsLikeMe tech blog. &lt;a href=&quot;http://tech.patientslikeme.com/2011/04/06/will_paginate_in_half_the_time/&quot;&gt;WillPaginate in Half the Time&lt;/a&gt;.</content><link rel='replies' type='application/atom+xml' href='http://blog.jdwyah.com/feeds/3389448856372436880/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9842007&amp;postID=3389448856372436880' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9842007/posts/default/3389448856372436880'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9842007/posts/default/3389448856372436880'/><link rel='alternate' type='text/html' href='http://blog.jdwyah.com/2011/04/willpaginate-in-half-time.html' title='WillPaginate in Half the Time'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/13347545383502498067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9842007.post-2073739306340953264</id><published>2010-11-22T13:00:00.005-05:00</published><updated>2010-11-22T15:01:41.155-05:00</updated><title type='text'>Reader 9.4.1! a Adobe Reader Version History</title><content type='html'>I&#39;m very happy to welcome Adobe Acrobat Reader version 9.4.1 to the world. I&#39;m so excited about this new version. In fact, I&#39;m so excited that I thought I&#39;d take this as a chance to look back at some of the previous versions of Reader that we all know and love.&lt;br /&gt;&lt;br /&gt;Version       : Features&lt;br /&gt;Reader 1.0 : Opens PDFs!! Also Crashes&lt;br /&gt;Reader 1.1 : Still opens PDFs. More Crashes&lt;br /&gt;Reader 1.2 : Still opens PDFs. Fewer Crashes&lt;br /&gt;Reader 1.3 : Still opens PDFs. More Crashes&lt;br /&gt;Reader 2.0 : Still opens PDFs. Fewer Crashes&lt;br /&gt;Reader 2.1 : Still opens PDFs. More Crashes&lt;br /&gt;Reader 2.2 : Still opens PDFs. More Crashes&lt;br /&gt;Reader 3.0 : Still opens PDFs. Fewer Crashes&lt;br /&gt;Reader 3.1 : Still opens PDFs. Fewer Crashes&lt;br /&gt;Reader 3.2 : Still opens PDFs. Fewer Crashes&lt;br /&gt;Reader 3.3 : Still opens PDFs. Fewer Crashes&lt;br /&gt;Reader 4.0 : Still opens PDFs. More Crashes. New Logo!&lt;br /&gt;Reader 4.1 : Still opens PDFs. More Crashes&lt;br /&gt;Reader 4.2 : Still opens PDFs. Fewer Crashes&lt;br /&gt;Reader 4.3 : Still opens PDFs. More Crashes&lt;br /&gt;Reader 5.0 : Still opens PDFs. More Crashes&lt;br /&gt;Reader 5.1 : Still opens PDFs. Fewer Crashes&lt;br /&gt;Reader 5.2 : Still opens PDFs. More Crashes&lt;br /&gt;Reader 6.0 : Still opens PDFs. Fewer Crashes&lt;br /&gt;Reader 6.1 : Still opens PDFs. More Crashes&lt;br /&gt;Reader 6.2 : Still opens PDFs. More Crashes&lt;br /&gt;Reader 6.3 : Still opens PDFs. Fewer Crashes&lt;br /&gt;Reader 7.0 : Still opens PDFs. Fewer Crashes. New logo!&lt;br /&gt;Reader 7.1 : Still opens PDFs. More Crashes&lt;br /&gt;Reader 7.2 : Still opens PDFs. Fewer Crashes&lt;br /&gt;Reader 8.0 : Still opens PDFs. More Crashes&lt;br /&gt;Reader 8.1 : Still opens PDFs. Fewer Crashes&lt;br /&gt;Reader 8.2 : Still opens PDFs. Fewer Crashes&lt;br /&gt;Reader 8.3 : Still opens PDFs. Fewer Crashes&lt;br /&gt;Reader 9.0 : Still opens PDFs. Fewer Crashes&lt;br /&gt;Reader 9.1 : Still opens PDFs. Fewer Crashes&lt;br /&gt;Reader 9.2 : Still opens PDFs. Fewer Crashes&lt;br /&gt;Reader 9.3 : Still opens PDFs. More Crashes&lt;br /&gt;Reader 9.4 : ???? A brave new world!</content><link rel='replies' type='application/atom+xml' href='http://blog.jdwyah.com/feeds/2073739306340953264/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9842007&amp;postID=2073739306340953264' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9842007/posts/default/2073739306340953264'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9842007/posts/default/2073739306340953264'/><link rel='alternate' type='text/html' href='http://blog.jdwyah.com/2010/11/reader-941-adobe-reader-version-history.html' title='Reader 9.4.1! a Adobe Reader Version History'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/13347545383502498067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9842007.post-5515189382485114704</id><published>2010-10-27T10:04:00.001-05:00</published><updated>2010-10-27T10:06:20.651-05:00</updated><title type='text'>Dealing with Git Merge Revisions</title><content type='html'>Forgot to astroturf my post on the PLM tech blog. Everything you wanted to know about &lt;a href=&quot;http://tech.patientslikeme.com/2010/09/29/dealing-with-git-merge-revisions/&quot;&gt;Dealing with Git Merge Revisions&lt;/a&gt; but were afraid to ask.</content><link rel='replies' type='application/atom+xml' href='http://blog.jdwyah.com/feeds/5515189382485114704/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=9842007&amp;postID=5515189382485114704' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9842007/posts/default/5515189382485114704'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9842007/posts/default/5515189382485114704'/><link rel='alternate' type='text/html' href='http://blog.jdwyah.com/2010/10/dealing-with-git-merge-revisions.html' title='Dealing with Git Merge Revisions'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/13347545383502498067</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry></feed>