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

<channel>
	<title>Kyle Cordes</title>
	<atom:link href="http://kylecordes.com/feed" rel="self" type="application/rss+xml" />
	<link>http://kylecordes.com</link>
	<description>Software, Business, and Life</description>
	<lastBuildDate>Fri, 18 Nov 2011 13:01:55 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Basics: Formatting Numbers for Tabular Display</title>
		<link>http://kylecordes.com/2011/tabular-display</link>
		<comments>http://kylecordes.com/2011/tabular-display#comments</comments>
		<pubDate>Fri, 18 Nov 2011 12:59:30 +0000</pubDate>
		<dc:creator>Kyle Cordes</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[basics]]></category>
		<category><![CDATA[commentary]]></category>

		<guid isPermaLink="false">http://kylecordes.com/?p=937</guid>
		<description><![CDATA[Here is the first, in hopefully a series, of posts about basic software design. Though not nearly as sexy as a location-based mobile social network with behavioral profiling for ad optimization (probably a real thing), doing basic software design well is one of our &#8220;secrets&#8221; at Oasis Digital. So here goes. Today&#8217;s topic is how [...]]]></description>
			<content:encoded><![CDATA[<p>Here is the first, in hopefully a series, of posts about basic software design. Though not nearly as sexy as a location-based mobile social network with behavioral profiling for ad optimization (probably a real thing), doing basic software design well is one of our &#8220;secrets&#8221; at Oasis Digital. So here goes.</p>
<p>Today&#8217;s topic is how numbers should be formatted for tabular display. This comes up quite frequently in data-centric applications. For an example, consider this mockup of a working-hours-per-person display screen, example 1:</p>
<p><a href="http://kylecordes.com/2011/tabular-display/col1" rel="attachment wp-att-938"><img class="alignnone size-full wp-image-938" title="col1" src="http://kylecordes.com/blog/wp-content/uploads/2011/11/col1.png" alt="" width="165" height="114" /></a></p>
<p>It looks quite nice with the numbers formatted trivially as whole numbers. What if someone worked 4.56 hours, though? How would that appear? To accomodate that possibility, you might always show two digits to the right of the decimal point like so, example 2:</p>
<p><a href="http://kylecordes.com/2011/tabular-display/col2" rel="attachment wp-att-941"><img class="alignnone size-full wp-image-941" title="col2" src="http://kylecordes.com/blog/wp-content/uploads/2011/11/col2.png" alt="" width="161" height="112" /></a></p>
<p>&#8230; which is OK, but not great &#8211; all those extra zeros distract the viewer from the essence of the data. One thing you should never do, though, is something like this:</p>
<p><a href="http://kylecordes.com/2011/tabular-display/col3" rel="attachment wp-att-942"><img class="alignnone size-full wp-image-942" title="col3" src="http://kylecordes.com/blog/wp-content/uploads/2011/11/col3.png" alt="" width="161" height="111" /></a></p>
<p>This is horrible. If you feel tempted to write software that displays data like this intentionally, please step away from the computer now. This breaks the rules of writing numbers that we all learned in primary school, probably before the age of 10: <strong>always line up the decimal point</strong>. Instead, for that particular set of numbers, the is reasonable:</p>
<p><a href="http://kylecordes.com/2011/tabular-display/col4" rel="attachment wp-att-943"><img class="alignnone size-full wp-image-943" title="col4" src="http://kylecordes.com/blog/wp-content/uploads/2011/11/col4.png" alt="" width="158" height="110" /></a></p>
<p>So is the answer to always display as many decimal digits as the data could possibly have? Perhaps, but only if you are <strong>unable to dynamically change the format</strong> based on the contents of the data. Examples 2 and 4 show a safe but unimpressive approach.</p>
<p>If you have the <strong>tools and skills to create a high quality solution</strong>, aim higher: dynamically choose the right number of decimal digits, to fit the specific data in question, then apply that same format uniformly to all the numbers. The output will therefore look like #1 if the data permits, and like #4 if the data requires it, but will not needlessly fill a column with 0s as in #3. This is more work, but is a more polished, professional result.</p>
   ]]></content:encoded>
			<wfw:commentRss>http://kylecordes.com/2011/tabular-display/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Group Programming, Projectors, and Big Screen HDTV</title>
		<link>http://kylecordes.com/2011/group-programming-hdtv</link>
		<comments>http://kylecordes.com/2011/group-programming-hdtv#comments</comments>
		<pubDate>Thu, 03 Nov 2011 01:23:12 +0000</pubDate>
		<dc:creator>Kyle Cordes</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[code-review]]></category>
		<category><![CDATA[pair-programming]]></category>

		<guid isPermaLink="false">http://kylecordes.com/?p=928</guid>
		<description><![CDATA[I&#8217;ve done a fair amount of pair programming over the years. My &#8220;Ward Number&#8221; is 1, if anyone recognizes the reference. But we pair only occasionally at Oasis Digital. Like Jeff Atwood, we don&#8217;t live the pair programming lifestyle. For our particular mix of people and problem spaces, we&#8217;ve found the sufficient amount of pairing [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve done a fair amount of <a href="http://en.wikipedia.org/wiki/Pair_programming">pair programming</a> over the years. My &#8220;Ward Number&#8221; is 1, if anyone recognizes the reference. But we pair only occasionally at <a href="http://oasisdigital.com/">Oasis Digital</a>. Like Jeff Atwood, we <a href="http://www.codinghorror.com/blog/2007/11/pair-programming-vs-code-reviews.html">don&#8217;t live the pair programming lifestyle</a>. For our particular mix of people and problem spaces, we&#8217;ve found the sufficient amount of pairing is roughly a couple of times per week, a couple hours at a time. We&#8217;re a partially <a href="http://kylecordes.com/2007/distributed-team-tools">distributed team</a>, so this often occurs via screen-sharing tools instead of at the same desk.</p>
<p>However, we do something perhaps even more &#8220;extreme&#8221; than pair programming: we spend a few hours every week programming in larger groups, sometimes as many as three of us in person and a couple more remotely. Why would anyone do that?</p>
<ul>
<li>To attack particularly hard problems</li>
<li>To resolve important detailed design issues</li>
<li>To share our programming style and culture</li>
<li>To freshen old skills</li>
<li>To build new skills</li>
<li>To efficiently pass knowledge 1-&gt;N, rather than 1-&gt;1</li>
</ul>
<p>I don&#8217;t quite know what to call this. <strong>Group</strong> programming? <strong>Cluster</strong> programming? <strong>N-tuple</strong> programming?</p>
<p>Regardless, we encounter an unavoidable issue: it is not pleasant for several people to cram in front of a PC monitor, even a large one, closely enough to read it. We&#8217;d rather spread out, particularly for sessions lasting a couple of hours straight.</p>
<p>In the past at other firms I&#8217;ve solved this by working in a conference room with a projector. This doesn&#8217;t work very well. Most projectors have a maximum native resolution of 1024&#215;768, or occasionally a bit higher, and those with reasonably high resolution are quite expensive. The reward for spending that money is continuous fan noise and an exhaust heat plume blowing on someone sitting on the unlucky side of the table.</p>
<p>This time we went a different direction: our group programming lair features:</p>
<ul>
<li>40-inch LED-LCD HDTV, with a native resolution of 1920&#215;1080, which generates no noise or heat, at less cost than a mediocre projector</li>
<li>A dedicated computer, so noone&#8217;e development laptop is occupied</li>
<li>wireless keyboard and mouse can be easily passed around</li>
<li>Speakers and a standalone mic, for very clear Skype audio</li>
<li>Nearby tables to accomodate everyone&#8217;s laptops, with 22/23 inch extra displays available</li>
</ul>
<p>It isn&#8217;t pretty:</p>
<p><a href="http://kylecordes.com/2011/group-programming-hdtv/bigmon-2" rel="attachment wp-att-930"><img class="alignnone size-full wp-image-930" title="BigMon" src="http://kylecordes.com/blog/wp-content/uploads/2011/11/BigMon1.jpg" alt="" width="614" height="395" /></a></p>
<p>It is <strong>very effective</strong>. We can comfortably work together in this area for hours, easily reading the screen from 6-8 feet away. (As I write this, I note that the room needs better chairs, a less beige color scheme, a printer that isn&#8217;t older than my teenager, and more Apple hardware.)</p>
<p>This approach isn&#8217;t for everyone; it requires a willingness to move furniture and buy non-standard equipment. I&#8217;d love to hear from anyone else doing something similar. In particular, I wonder how it compares to <a href="http://pivotallabs.com/users/jsusser/blog/articles/1505-pairing-tete-a-tete">Pivotal&#8217;s setup</a>.</p>
<p>&nbsp;</p>
   ]]></content:encoded>
			<wfw:commentRss>http://kylecordes.com/2011/group-programming-hdtv/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Steve Jobs</title>
		<link>http://kylecordes.com/2011/steve-jobs</link>
		<comments>http://kylecordes.com/2011/steve-jobs#comments</comments>
		<pubDate>Thu, 06 Oct 2011 01:41:24 +0000</pubDate>
		<dc:creator>Kyle Cordes</dc:creator>
				<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://kylecordes.com/?p=918</guid>
		<description><![CDATA[If you haven&#8217;t already done so, now would be a good time to watch Steve Jobs&#8217; 2005 Stanford commencement address.]]></description>
			<content:encoded><![CDATA[<p style="text-align: center;"><img class="aligncenter size-full wp-image-919" title="apple-jobs" src="http://kylecordes.com/blog/wp-content/uploads/2011/10/apple-jobs.png" alt="" width="589" height="395" /></p>
<p style="text-align: center;">If you haven&#8217;t already done so, now would be a good time<br />
to watch <a href="http://www.youtube.com/watch?v=UF8uR6Z6KLc">Steve Jobs&#8217; 2005 Stanford commencement address</a>.</p>
   ]]></content:encoded>
			<wfw:commentRss>http://kylecordes.com/2011/steve-jobs/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Mobile Lua &#8211; iOS and Android apps with Corona</title>
		<link>http://kylecordes.com/2011/ios-android-lua-corona</link>
		<comments>http://kylecordes.com/2011/ios-android-lua-corona#comments</comments>
		<pubDate>Tue, 31 May 2011 01:21:42 +0000</pubDate>
		<dc:creator>Kyle Cordes</dc:creator>
				<category><![CDATA[Presentations]]></category>
		<category><![CDATA[lua]]></category>

		<guid isPermaLink="false">http://kylecordes.com/?p=908</guid>
		<description><![CDATA[On Thursday (May 26, 2011), I presented at the St. Louis Mobile Dev group, on cross-mobile-platform development with Lua. There are various ways to do this (including rolling your own), but for simplicity I used Ansca&#8217;s Corona product. The talk was somewhat impromptu, so I didn&#8217;t record audio or video. The slides are available: &#160; [...]]]></description>
			<content:encoded><![CDATA[<p>On Thursday (May 26, 2011), I presented at the St. Louis Mobile Dev group, on cross-mobile-platform development with Lua. There are various ways to do this (including rolling your own), but for simplicity I used Ansca&#8217;s Corona product. The talk was somewhat impromptu, so I didn&#8217;t record audio or video. The slides are available:</p>
<div id="__ss_8155387" style="width: 425px;"><strong style="display: block; margin: 12px 0 4px;"><br />
</strong><object id="__sse8155387" width="425" height="355"><param name="movie" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=2011luacoronamobiledev-110530182157-phpapp01&amp;stripped_title=mobile-lua-for-ios-and-android-with-ansca-corona&amp;userName=kylecordes" /><param name="allowFullScreen" value="true" /><param name="allowScriptAccess" value="always" /><embed type="application/x-shockwave-flash" width="425" height="355" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=2011luacoronamobiledev-110530182157-phpapp01&amp;stripped_title=mobile-lua-for-ios-and-android-with-ansca-corona&amp;userName=kylecordes" allowfullscreen="true" allowscriptaccess="always" name="__sse8155387"></embed></object>&nbsp;</p>
<p>&#8230; or as a PDF: <a href="/files/2011-Lua-Corona-Mobile-Dev.pdf">2011-Lua-Corona-Mobile-Dev.pdf</a></p>
<p>From this blog, you might get the impression that I use Lua extensively. That is not true; 95% of my work does not involve Lua in any way.</p>
</div>
<p><script src="http://b.scorecardresearch.com/beacon.js?c1=7&amp;c2=7400849&amp;c3=1&amp;c4=&amp;c5=&amp;c6="></script></p>
   ]]></content:encoded>
			<wfw:commentRss>http://kylecordes.com/2011/ios-android-lua-corona/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Crafting a Summer Intern Program</title>
		<link>http://kylecordes.com/2011/crafting-intern-program</link>
		<comments>http://kylecordes.com/2011/crafting-intern-program#comments</comments>
		<pubDate>Sun, 29 May 2011 18:35:30 +0000</pubDate>
		<dc:creator>Kyle Cordes</dc:creator>
				<category><![CDATA[Business]]></category>

		<guid isPermaLink="false">http://kylecordes.com/?p=902</guid>
		<description><![CDATA[Inspired by Fog Creek&#8217;s summer intern program, for the last few years we&#8217;ve (occasionally) thought about a summer intern program at Oasis Digital. We&#8217;ll going to try it out this summer, with a single intern; a more substantial program is possible in the future. Serious Work When some people hear (or say) the word intern, [...]]]></description>
			<content:encoded><![CDATA[<p>Inspired by <a href="http://www.fogcreek.com/Jobs/SummerIntern.html">Fog Creek&#8217;s summer intern program</a>, for the last few years we&#8217;ve (occasionally) thought about a summer intern program at <a href="http://oasisdigital.com/">Oasis Digital</a>. We&#8217;ll going to try it out this summer, with a single intern; a more substantial program is possible in the future.</p>
<h3>Serious Work</h3>
<p>When some people hear (or say) the word intern, they imagine someone who makes copies and fetches lunch. Perhaps in some work cultures that is helpful, but here we have in mind serious work. Our interns will work on serious work:</p>
<ul>
<li>Projects that are helpful to our company operations</li>
<li>Exploratory programming, to try out ideas that don&#8217;t yet warrant commercial attention</li>
<li>Open Source programming, such as improvements to tools we use</li>
<li>Perhaps even a few bits of our real customer projects</li>
</ul>
<p>The kinds of work could include&#8230;</p>
<ul>
<li>writing software</li>
<li>testing software</li>
<li>reading and writing about software</li>
<li>marketing work around the software</li>
</ul>
<h3>Twofold Purpose</h3>
<p>The purpose and goal of our internships will be:</p>
<ol>
<li>Educate and enlighten the intern</li>
<li>Hopefully also create something useful to Oasis Digital and its customers</li>
</ol>
<h3>Paid vs Unpaid Internships</h3>
<p>Many companies are eager to get free help from interns. But it&#8217;s clear from a few minutes research that a for-profit company with an intern working on potentially valuable project, must pay. Therefore, we will only offer paid internships.</p>
<h3>Location</h3>
<p>The internship work will be conducted at our at Oasis Digital office; interns must live in the St. Louis metro area.</p>
<h3>Can I Apply?</h3>
<p>Sorry &#8211; No. We&#8217;ve already selected an intern for our trial-run 2011 program. If we decide to continue and expand it for 2012, it will be announces in the spring (of 2012).</p>
<p>&nbsp;</p>
   ]]></content:encoded>
			<wfw:commentRss>http://kylecordes.com/2011/crafting-intern-program/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Cloudy Data Storage, circa 2001</title>
		<link>http://kylecordes.com/2011/cloud-2001</link>
		<comments>http://kylecordes.com/2011/cloud-2001#comments</comments>
		<pubDate>Wed, 25 May 2011 02:46:29 +0000</pubDate>
		<dc:creator>Kyle Cordes</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[cloud]]></category>
		<category><![CDATA[sysadmin]]></category>

		<guid isPermaLink="false">http://kylecordes.com/?p=896</guid>
		<description><![CDATA[Around 2000-2001, Oasis Digital built a system for a client which (in retrospect) took a &#8220;cloudy&#8221; approach to data storage. 2001 is a few years before that approach gained popularity, so it&#8217;s interesting to look back and see how our solution stacks up. The problem domain was the storage of check images for banks; the [...]]]></description>
			<content:encoded><![CDATA[<p>Around 2000-2001, Oasis Digital built a system for a client which (in retrospect) took a &#8220;cloudy&#8221; approach to data storage. 2001 is a few years before that approach gained popularity, so it&#8217;s interesting to look back and see how our solution stacks up.</p>
<p>The problem domain was the storage of check images for banks; the images came out of a check-imaging device, a very specialized camera/scanner capable of photographing many checks per second, front and back. For example, to scan 1000 checks (a smallish run), it generated 2000 images. All of the images from a run were stored in a single archive file, accompanied by index data. OCR/mag-type data was also stored.</p>
<p>I don&#8217;t recall the exact numbers (and probably wouldn&#8217;t be able to talk about them anyway), so the numbers here are estimates to convey a sense of the scale of the problem in its larger installations:</p>
<ul>
<li>Many thousands of images per day.</li>
<li>Archive files generally between 100 MB and 2 GB</li>
<li>Hundred, then thousands, of these archive files</li>
<li>In an era when hard drives were much smaller than they are today</li>
</ul>
<p>Our client considered various off-the-shelf high-capacity storage systems, but instead worked with us to contruct a solution roughly as follows.</p>
<h3>Hardware and Networking</h3>
<ul>
<li>Multiple servers were purchased and installed, over time.</li>
<li>Servers were distributed across sites, connected by a WAN.</li>
<li>Multiple hard drives (of capacity C) were installed in each server, without RAID.</li>
<li>Each storage drive on each server was made accessible remotely via Windows networking</li>
</ul>
<h3>Software</h3>
<ul>
<li>To keep the file count managable, the files were kept in the many-image archives.</li>
<li>A database stored metadata about each image, including what file to find it in.</li>
<li>The offset of the image data within its archive file was also stored, so that it could be read directly without processing the whole archive.</li>
<li>Each archive file was written to N different drives, all on different servers, and some at different physical sites.</li>
<li>To pick where to store a new file, the software could simply look through the list of possibility and check for sufficient free space.</li>
<li>A database kept track of where (all) each archive file was stored.</li>
<li>An archive file could be read from any of its locations. Client software would connect to the database, learn of all the locations for a file.</li>
</ul>
<p>This system was read-mostly, and writes were not urgent. For writes, if N storage drives weren&#8217;t available, the operator (of the check-scanning system) would try again later. CAP and other concerns weren&#8217;t important for this application.</p>
<h3>Helpful Properties</h3>
<ul>
<li>Even if some servers, sites, or links were down, files remained generally accessible.</li>
<li>Offline media storage could be added, though I don&#8217;t recall if we got very far down that path.</li>
<li>The system was very insensitive to details like OSs, OS versions, etc. New storage servers and drives could be added with newer OS versions and bigger drive sizes, without upgrading old storage.</li>
<li>Drives could be made read-only once full, to avoid whole classes of possible corruption.</li>
<li>By increasing the number of servers, and number of hard drives over time, this basic design could scale quite far (for the era, anyway).</li>
</ul>
<p>This approach delivered for our client a lot of the benefits of an expensive scalable storage system, at a fraction of the cost and using only commodity equipment.</p>
<p>Why do I describe this as cloud-like? Because from things I&#8217;ve read, this is similar (but much less sophisticated, of course) to the approach taken inside of Amazon S3 and other cloud data storage systems/services.</p>
<h3>Key Lesson</h3>
<p>Assume you are willing to pay to store each piece of data on N disks. You get much better overall uptime (given the right software) if those N disks are in <strong>N different machines spread across sites</strong>, than you do by putting those N disks in a RAID on the same machine. Likewise, you can read a file much faster from an old slow hard drive in the same building than you can from a RAID-6 SAN across an 2000-era WAN. The tradeoff is software complexity.</p>
<p>&nbsp;</p>
   ]]></content:encoded>
			<wfw:commentRss>http://kylecordes.com/2011/cloud-2001/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Upcoming Talk: Lua on iPhone and Android (using Corona)</title>
		<link>http://kylecordes.com/2011/upcoming-lua-mobile</link>
		<comments>http://kylecordes.com/2011/upcoming-lua-mobile#comments</comments>
		<pubDate>Tue, 24 May 2011 03:32:52 +0000</pubDate>
		<dc:creator>Kyle Cordes</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[lua]]></category>
		<category><![CDATA[mobile]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://kylecordes.com/?p=892</guid>
		<description><![CDATA[This Thursday (May 26, 2011), I will give a talk at the St. Louis Mobile Dev group on cross-mobile-platform development with Lua. There are various ways to do this (including rolling your own), but for simplicity I&#8217;m using Ansca&#8217;s Corona product. As usual, I&#8217;ll zoom through some slides, and concentrate instead on the code. For some [...]]]></description>
			<content:encoded><![CDATA[<p>This Thursday (May 26, 2011), I will give a <a href="https://sites.google.com/site/stlmobiledev/meetings/meeting-15">talk</a> at the <a href="https://sites.google.com/site/stlmobiledev/home">St. Louis Mobile Dev group</a> on cross-mobile-platform development with Lua. There are various ways to do this (including rolling your own), but for simplicity I&#8217;m using <a href="http://www.anscamobile.com/">Ansca&#8217;s Corona</a> product.</p>
<p>As usual, I&#8217;ll zoom through some slides, and concentrate instead on the code. For some background on Lua, you may want to watch the <a href="http://kylecordes.com/2010/lua-strange-loop">video of my 20-minute Lua talk</a> from last year&#8217;s Strange Loop.</p>
<p>Update: slides are available <a href="http://kylecordes.com/2011/ios-android-lua-corona">here</a>.</p>
<p>&nbsp;</p>
   ]]></content:encoded>
			<wfw:commentRss>http://kylecordes.com/2011/upcoming-lua-mobile/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Coming this fall: Strange Loop 2011</title>
		<link>http://kylecordes.com/2011/fall-strange-loop-2011</link>
		<comments>http://kylecordes.com/2011/fall-strange-loop-2011#comments</comments>
		<pubDate>Mon, 16 May 2011 22:30:59 +0000</pubDate>
		<dc:creator>Kyle Cordes</dc:creator>
				<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://kylecordes.com/?p=887</guid>
		<description><![CDATA[Coming this fall, Alex Miller is putting on the third year of his Strange Loop conference, Strange Loop 2011. It&#8217;s not in &#8220;The Loop&#8221; this time, because The Loop isn&#8217;t big enough to hold it! I heartily recommend Strange Loop for any software developer interested in learning more about a wide variety of technical topics. [...]]]></description>
			<content:encoded><![CDATA[<p>Coming this fall, <a href="http://tech.puredanger.com/">Alex Miller</a> is putting on the third year of his Strange Loop conference, <a href="https://thestrangeloop.com/">Strange Loop 2011</a>. It&#8217;s not in &#8220;The Loop&#8221; this time, because The Loop isn&#8217;t big enough to hold it!</p>
<p>I heartily recommend Strange Loop for any software developer interested in learning more about a wide variety of technical topics. Unlike many other events, this one stays close to the technology all the way through &#8211; you might see a higher ratio of code-to-text on the slides here, than at any other conference.</p>
<p>(Again this year, my firm <a href="http://oasisdigital.com/news.html">Oasis Digital is a sponsor</a>, and I&#8217;ll probably submit a talk. I hesitate a bit though, because if I give a talk, I have to miss someone else&#8217;s talk in that timeslot.)</p>
<p>&nbsp;</p>
   ]]></content:encoded>
			<wfw:commentRss>http://kylecordes.com/2011/fall-strange-loop-2011/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ancient History: JBuilder Open Tools</title>
		<link>http://kylecordes.com/2011/jbuilder-open-tools</link>
		<comments>http://kylecordes.com/2011/jbuilder-open-tools#comments</comments>
		<pubDate>Tue, 03 May 2011 23:44:54 +0000</pubDate>
		<dc:creator>Kyle Cordes</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[www]]></category>

		<guid isPermaLink="false">http://kylecordes.com/?p=883</guid>
		<description><![CDATA[Some years ago, the Java IDE marketplace looked quite different than it does today. VisualAge was very popular. Borland&#8217;s JBuilder was another top contender. Since then, many of the good ideas from VisualAge ended up in Eclipse, while the JBuilder of that era was replaced by a newer, Eclipse-based JBuilder. Not everything ended up on [...]]]></description>
			<content:encoded><![CDATA[<p>Some years ago, the Java IDE marketplace looked quite different than it does today. VisualAge was very popular. Borland&#8217;s JBuilder was another top contender. Since then, many of the good ideas from VisualAge ended up in Eclipse, while the JBuilder of that era was replaced by a <a href="http://www.embarcadero.com/products/jbuilder">newer, Eclipse-based JBuilder</a>. Not everything ended up on Eclipse, though: NetBeans matured to a slick IDE (with its own plugin ecosystem), as did IDEA.</p>
<p>But this post isn&#8217;t about today, it&#8217;s about a leftover bit of history. Back in that era, I had a section of this web site dedicated to the numerous JBuilder &#8220;Open Tools&#8221; (plugins) then available. That content is long obsolete and I removed it years ago. Remarkably, this site still gets hits every day from people (or perhaps bots) looking for it.</p>
<p>I agree strongly that <a href="http://www.w3.org/Provider/Style/URI.html.en">Cool URIs don&#8217;t change</a>, but that&#8217;s OK, because my old JBuilder Open Tools content just wasn&#8217;t very cool anyway.</p>
<p>On the off chance you landed on this page looking for it, here is a <a href="http://www.google.com/search?q=jbuilder+open+tools">Google link for your convenience</a>, or you can take a look at <a href="http://replay.web.archive.org/20010613230757/http://www.kylecordes.com/jbot/">web.archive.org&#8217;s snapshot of my old list</a>.</p>
<p>&nbsp;</p>
   ]]></content:encoded>
			<wfw:commentRss>http://kylecordes.com/2011/jbuilder-open-tools/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Comparing OPML Files, or How to Leave NetNewsWire</title>
		<link>http://kylecordes.com/2011/compare-opml-files</link>
		<comments>http://kylecordes.com/2011/compare-opml-files#comments</comments>
		<pubDate>Sun, 20 Feb 2011 04:01:03 +0000</pubDate>
		<dc:creator>Kyle Cordes</dc:creator>
				<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://kylecordes.com/?p=873</guid>
		<description><![CDATA[Recently I reached a level of excessive frustration with NetNewsWire (Mac) and decided it was time to move on. Problems with NetNewsWire include: NetNewsWire has no way to sync its subscription list to match your Google Reader subscription list. There is a Merge button in the Preferences that sounds like it should do this, but [...]]]></description>
			<content:encoded><![CDATA[<p>Recently I reached a level of excessive frustration with NetNewsWire (Mac) and decided it was time to move on. Problems with NetNewsWire include:</p>
<ol>
<li>NetNewsWire has no way to sync its subscription list to match your Google Reader subscription list. There is a Merge button in the Preferences that sounds like it should do this, but it does not work correctly. Once your lists get out of sync, they generally stay that way.</li>
<li>NetNewsWire won&#8217;t prefetch images referenced in feeds. Without this, it is not useful for the most obvious purpose of a desktop reader: reading without a network connection. That&#8217;s a reasonable thing to leave out in early development, but in a mature product? What could they have been thinking?</li>
<li>NetNewsWire fails (silently) to subscribe to Google Alerts feeds, apparently because Google Reader already knows about those feeds&#8230; but see #1.</li>
<li>As many other users have reports, NetNewsWire frequently shows a different number of unread items from Google Reader, and no amount of Refreshing makes it match. The sync doesn&#8217;t quite work.</li>
</ol>
<p>But to get rid of NetNewsWire, I needed to verify that I had all my feeds in Google Reader. This was easy:</p>
<ol>
<li>Export OPML feed list from NNW</li>
<li>Export OPML feed list from Reader</li>
<li>Use a bit of perl regex and diff (below) to extract and compare just the list of feed URLs</li>
<li>Look over the diff, and copy-paste-subscribe the missing ones in Reader</li>
</ol>
<p>The commands are:</p>
<pre>
perl -ne '/xmlUrl="([^"]*)"/ &amp;&amp; print "$1\n"' &lt;google-reader-subscriptions.xml  | sort &gt;gr.urls
perl -ne '/xmlUrl="([^"]*)"/ &amp;&amp; print "$1\n"' &lt;nn.opml  | sort &gt;nn.urls
diff gr.urls nn.urls</pre>
<p>&#8230; which took much less time and far fewer keypresses than writing this post.</p>
<p>Offline reading is still very useful; at the moment I&#8217;m trying a combination of Google Reader, <a href="http://www.grumlapp.com/">Gruml</a>, and <a href="http://reederapp.com/ipad/">Reeder (iPad)</a>. Those work very well &#8211; so well that the risk of time-wasting feeds must be managed agressively: drop all but the most important, and don&#8217;t look every day.</p>
   ]]></content:encoded>
			<wfw:commentRss>http://kylecordes.com/2011/compare-opml-files/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Fix timestamps after a mass file transfer</title>
		<link>http://kylecordes.com/2011/fix-timestamps-after-file-transfer</link>
		<comments>http://kylecordes.com/2011/fix-timestamps-after-file-transfer#comments</comments>
		<pubDate>Sat, 19 Feb 2011 15:56:20 +0000</pubDate>
		<dc:creator>Kyle Cordes</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[sysadmin]]></category>
		<category><![CDATA[windows]]></category>

		<guid isPermaLink="false">http://kylecordes.com/?p=866</guid>
		<description><![CDATA[I recently transferred a few thousand files, totalling gigabytes, from one computer to another over a slowish internet connection. At the end of the transfer, I realized the process I used had lost all the original file timestamps. Rather, all the files on the destination machine had a create/modify date of when the transfer occurred. [...]]]></description>
			<content:encoded><![CDATA[<p>I recently transferred a few thousand files, totalling gigabytes, from one computer to another over a slowish internet connection. At the end of the transfer, I realized the process I used had lost all the original file timestamps. Rather, all the files on the destination machine had a create/modify date of when the transfer occurred. In this particular case I had uploaded files to Amazon S3 from end then downloaded them from another, but there are numerous other ways to transfer files that lose the timestamps; for example, many FTP clients do so by default.</p>
<p>This file transfer took many hours, so I wasn&#8217;t inclined to delete and try again with a better (timestamp-preserving) transfer process. Rather, it shouldn&#8217;t be very hard to fix them in-place.</p>
<p>Both machines were Windows servers; neither had a broad set of Unix tools installed. If I had those present, the most obvious solution would be a simple rsync command, which would fix the timestamps without retransferring the data. But without those tools present, and with an unrelated desire to keep these machines as &#8220;clean&#8221; as possible, plus a firewall obstacle to SSH, I looked elsewhere for a fix.</p>
<p>I did, however, happen to have a partial set of Unix tools (in the form of the MSYS tools that come with MSYSGIT) on the source machine. After a few minutes of puzzling, I came up with this approach:</p>
<ol>
<li>Run a command on the source machine</li>
<li>&#8230; which looks up the timestamp of each file</li>
<li>&#8230; and stores those in the form of batch file</li>
<li>Then copy this batch file to the destination machine and run it.</li>
</ol>
<p>Here is the source machine command, executed at the top of the file tree to be fixed:</p>
<pre>find . -print0 | xargs -0 stat -t "%d-%m-%Y %T"
 -f 'nircmd.exe setfilefoldertime "%N" "%Sc" "%Sm"'
 | tr '/' '\\' &gt;~/fix_dates.bat</pre>
<p>I broken it up to several lines here, but it&#8217;s intended as one long command.</p>
<ul>
<li>&#8220;find&#8221; gets the names of every file and directory in the file tree</li>
<li>xargs feeds these to the stat command</li>
<li>stat gets the create and modify dates of each file/directory, and formats the results in a very configurable way</li>
<li>tr converts the Unix-style &#8220;/&#8221; paths to Windows-style &#8220;\&#8221; paths.</li>
<li>The results are redirected to (stored in) a batch file.</li>
</ul>
<p>As far as I can tell, the traditional set of Windows built in command line tools does not include a way to set a file or directory&#8217;s timestamps. I haven&#8217;t spent much time with Powershell yet, so I used the (very helpful) <a href="http://www.nirsoft.net/utils/nircmd.html">NIRCMD</a> command line utilities, specifically the <a href="http://nircmd.nirsoft.net/setfilefoldertime.html">setfilefoldertime subcommand</a>. The batch file generated by the above process is simply a very long list of lines like this:</p>
<pre>nircmd.exe setfilefoldertime "path\filename" "19-01-2000 04:50:26" "19-01-2000 04:50:26"</pre>
<p>I copied this batch file to the destination machine and executed it; it corrected the timestamps, the problem was solved.</p>
   ]]></content:encoded>
			<wfw:commentRss>http://kylecordes.com/2011/fix-timestamps-after-file-transfer/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>New site: Learn Clojure</title>
		<link>http://kylecordes.com/2010/learn-clojure</link>
		<comments>http://kylecordes.com/2010/learn-clojure#comments</comments>
		<pubDate>Tue, 07 Dec 2010 02:43:51 +0000</pubDate>
		<dc:creator>Kyle Cordes</dc:creator>
				<category><![CDATA[Technology]]></category>
		<category><![CDATA[clojure]]></category>

		<guid isPermaLink="false">http://kylecordes.com/?p=862</guid>
		<description><![CDATA[Over the last few days I put together Learn-Clojure.com, a web site to help people get started with Clojure. Please take a look, and send feedback. I also have several other ideas for informational sites and simple applications, which I&#8217;ll launch as time allows. In the past I&#8217;ve been inclined to just post new things [...]]]></description>
			<content:encoded><![CDATA[<p>Over the last few days I put together <a href="http://learn-clojure.com/">Learn-Clojure.com</a>, a web site to help people get started with Clojure. Please take a look, and send feedback.</p>
<p>I also have several other ideas for informational sites and simple applications, which I&#8217;ll launch as time allows. In the past I&#8217;ve been inclined to just post new things here on my blog, but I think certain kinds of more &#8220;evergreen&#8221; information are more useful on standalone sites. Certainly the hosting/domain economics are such that it&#8217;s not a big deal to put them there.</p>
   ]]></content:encoded>
			<wfw:commentRss>http://kylecordes.com/2010/learn-clojure/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Hire a RAIT: Redundant Array of Independent Teams</title>
		<link>http://kylecordes.com/2010/hire-redundant-teams</link>
		<comments>http://kylecordes.com/2010/hire-redundant-teams#comments</comments>
		<pubDate>Wed, 17 Nov 2010 05:26:48 +0000</pubDate>
		<dc:creator>Kyle Cordes</dc:creator>
				<category><![CDATA[Business]]></category>
		<category><![CDATA[hiring]]></category>
		<category><![CDATA[risk]]></category>

		<guid isPermaLink="false">http://kylecordes.com/?p=848</guid>
		<description><![CDATA[Life is Risk Whenever you hire out work, either to a person, to a team, or to a company, there are risks. These risks can easily prevent the work from being completed, and even more easily prevent it from being completed on time. (I&#8217;m thinking mostly of software development work as I write this, but [...]]]></description>
			<content:encoded><![CDATA[<h3>Life is Risk</h3>
<p>Whenever you hire out work, either to a person, to a team, or to a company, there are risks. These risks can easily prevent the work from being completed, and even more easily prevent it from being completed on time. (I&#8217;m thinking mostly of software development work as I write this, but most of this applies to other domains as well.)</p>
<p>What could go wrong with the person/team/company you hire?</p>
<ul>
<li>They get distracted by family or personal issues.</li>
<li>They turn out to not be as qualified or capable as they appeared.</li>
<li>They leave for better work. Sure, you might have a contract requiring them to finish, but your lawsuit won&#8217;t get the work done on time.</li>
<li>They turn out to not be as interested in your work as they first appeared.</li>
<li>They start with an approach which, while initially appearing wise, turns out to be poorly suited.</li>
<li>Illness or injury.</li>
</ul>
<p>Of course you should carefully interview and check reputations to avert some of these risks, but you cannot make them all go away. You don&#8217;t always truly know who is good, who will produce. You can only estimate, with varying levels of accuracy. The future is unavoidably unknown and uncertain.</p>
<p>But you still want the work done, sufficiently well and sufficently soon. Or at least I do.</p>
<h3>Redundancy Reduces Risk</h3>
<p>A few years ago I stumbled across a way to attack many of these risks with the same, simple approach:<strong> hire N people or teams in parallel to separately attack the same work</strong>. I sometimes call this a RAIT, a <strong>Redundant Array of Independent Teams</strong>. Both the team size (one person or many), and the number of teams (N) can vary. Think of the normal practice of hiring a single person or single team as a degenerate case of RAIT with N=1.</p>
<p>To make RAIT practical, you need a hiring and management approach that uses your time (as the hirer) very efficiently. The key to efficiency here is to avoid doing things N times (once per team); rather, do them once, and broadcast to all N teams. For example, minimize cases where you answer developer questions in a one-off way. If you get asked a question by phone, IM, or email, answer it by adding information to a document or wiki; publish the document or wiki to all N teams. If you don&#8217;t have a publishing system or wiki technology in hand, in many cases simply using a shared Google Document is sufficient.</p>
<p>There are plenty of variations on the RAIT theme. For example, you might keep the teams completely isolated in terms of their interim work; this would minimize the risk that one teams&#8217; bad ideas will contaminate the others. Or you might pass their work back and forth from time to time, since this would reduce duplicated effort (and thus cost) and speed up completion.</p>
<p>Another variation is to start with N teams, then incrementally trim back to a single team. For example, consider a project that will take 10 weeks to complete. You could start with three concurrent efforts. After one week, drop one of the efforts &#8211; whichever has made the least progress. After three weeks, again drop whichever team has made the least progress, leaving a single team to work all 10 weeks. As you can see in the illustration below, the total cost of this approach is 14 team-weeks of work.</p>
<p><a rel="attachment wp-att-855" href="http://kylecordes.com/2010/hire-redundant-teams/rait-illustration"><img class="size-full wp-image-855 alignnone" title="rait-illustration" src="http://kylecordes.com/blog/wp-content/uploads/2010/11/rait-illustration.png" alt="" width="506" height="108" /></a></p>
<p>How might you think about that 14 team-weeks of effort/cost?</p>
<ol>
<li>It is a 40% increase in cost over picking the right team the first time. If you can <a href="http://en.wikipedia.org/wiki/Palant%C3%ADr">see the future</a>, you don&#8217;t need RAIT.</li>
<li>It is a 50% decrease compared to paying one team for 10 weeks, realizing they won&#8217;t produce, then paying another team for 10 more weeks.</li>
<li>If you hired only one team, which doesn&#8217;t deliver on time, you might miss a market opportunity.</li>
</ol>
<h3>Still, isn&#8217;t this an obvious waste of money?</h3>
<p>To understand the motivation here, you must first understand (and accept) that no matter how amazing your management, purchasing, and contracting skills, there remains a significant random element in the results of any non-trivial project. There is a range of possibilities, a probability function describing the likelihood with which the project will be done as a function of time.</p>
<p>RAIT is not about minimizing best-case cost. It is about maximizing the probability of timely, successful delivery:</p>
<ul>
<li>To reduce the risk of whether your project will be delivered.</li>
<li>To reduce the risk of whether your project will be delivered on time.</li>
<li>To increase your aggregate experience (as you learn from multple teams) faster.</li>
<li>To enable bolder exploration of alternative approaches to the work.</li>
</ul>
<h3>What projects are best suited for RAIT?</h3>
<p>Smaller projects have a lower absolute cost of duplicate efforts, so for these it is easier to consider some cost duplication. RAIT is especially well suited when hiring out work to be done &#8220;out there&#8221; by people scattered around the internet and around the world, because the risk of some of the teams/people not engaging effectively in the work is typically higher.</p>
<p>Very important projects justify the higher expense of RAIT. You could think of high-profile, big-dollar government technologies development programs as an example of RAIT: a government will sometimes pay two firms to developing different designs of working prototype aircraft, then choose only one of them for volume production. For a smaller-scale example, consider the notion of producing an iPhone app or Flash game for an upcoming event, where missing the date means getting no value at all for your efforts.</p>
<p><em>Thanks to David McNeil for reviewing a draft of this.</em></p>
   ]]></content:encoded>
			<wfw:commentRss>http://kylecordes.com/2010/hire-redundant-teams/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>If you like it, make a link to it &#8211; a plea for real links</title>
		<link>http://kylecordes.com/2010/like-it-link-it</link>
		<comments>http://kylecordes.com/2010/like-it-link-it#comments</comments>
		<pubDate>Sat, 30 Oct 2010 19:38:05 +0000</pubDate>
		<dc:creator>Kyle Cordes</dc:creator>
				<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://kylecordes.com/?p=832</guid>
		<description><![CDATA[You see something good on the web; now it&#8217;s time to tell other people about it. Maybe you&#8217;ll use various common tools: Facebook &#8220;like&#8221; it Social-network-share it Bit.ly it Tweet it Mention it in a forum post Mention it in a blog comment I believe it&#8217;s smart and convenient to do those things, but not [...]]]></description>
			<content:encoded><![CDATA[<p>You see something good on the web; now it&#8217;s time to tell other people about it. Maybe you&#8217;ll use various common tools:</p>
<ul>
<li>Facebook &#8220;like&#8221; it</li>
<li>Social-network-share it</li>
<li>Bit.ly it</li>
<li>Tweet it</li>
<li>Mention it in a forum post</li>
<li>Mention it in a blog comment</li>
</ul>
<p>I believe it&#8217;s smart and convenient to do those things, but not to <strong>only</strong> do those things. Why? Because they create redirected, tracked, short-lived, rel=nofollowed, or otherwise weak links. Links that don&#8217;t properly tell search engines that the content is worthwhile. Quasi-links that attempt to replace real links as the fundamental currency of the web.</p>
<p>If you <strong>really like it,</strong> if you think it deserves ongoing attention, then in addition to whatever else you do, <strong>put a real A-HREF link to it on your web site/blog</strong>.</p>
   ]]></content:encoded>
			<wfw:commentRss>http://kylecordes.com/2010/like-it-link-it/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>In the Arena</title>
		<link>http://kylecordes.com/2010/in-the-arena</link>
		<comments>http://kylecordes.com/2010/in-the-arena#comments</comments>
		<pubDate>Fri, 29 Oct 2010 13:30:31 +0000</pubDate>
		<dc:creator>Kyle Cordes</dc:creator>
				<category><![CDATA[Business]]></category>
		<category><![CDATA[commentary]]></category>
		<category><![CDATA[products]]></category>
		<category><![CDATA[saas]]></category>

		<guid isPermaLink="false">http://kylecordes.com/?p=826</guid>
		<description><![CDATA[Almost every day at some point I wander over to Hacker News, which has some great discussion, along with some less great discussion, among people pursuing or aspiring to pursue a software startup or similar business. Likewise with local events (like ITEN STL offers), and even more so the Business of Software conference earlier this [...]]]></description>
			<content:encoded><![CDATA[<p>Almost every day at some point I wander over to <a href="http://news.ycombinator.com/">Hacker News</a>, which has some great discussion, along with some less great discussion, among people pursuing or aspiring to pursue a software startup or similar business. Likewise with local events (like <a href="http://www.itenstl.org/">ITEN STL</a> offers), and even more so the Business of Software conference earlier this month. (<a href="http://kylecordes.com/2010/three-events-october">experiences</a>)</p>
<p>I <a href="http://kylecordes.com/2010/mwm-sold">used to have</a> a software product business myself, a vertical market SaaS firm. Now that I&#8217;ve been out of that for over a year, the thing I miss most is the feeling of being &#8220;in the arena&#8221;, of having a speculative product out there for people to buy. To be <strong>out there</strong> is both terrifying and exhilarating. I have heard it said that there are &#8220;product people&#8221; and &#8220;consulting people&#8221;, and looking back it is clear to me that I am mostly in the Product category.</p>
<p>Unlike some product people (like <a href="http://unicornfree.com/">Amy Hoy</a>, whom I admire greatly!) I don&#8217;t think it&#8217;s necessary to swear off one thing to do the other. Consulting (building software for clients) is very satisfying, especially when working with a team of great people (and a group of very competent customers) like we have at <a href="http://oasisdigital.com/">Oasis Digital</a>.</p>
<p>So while I&#8217;m going to keep building software for other people, I&#8217;m also going to go back to the marketplace with speculative products. This time it will be products in the plural, some subset of:</p>
<ul>
<li>Web/SaaS software</li>
<li>iPad software</li>
<li>iPhone / iPod Touch software</li>
<li>Android software (by year-end the stores will be piled high with Android tablets)</li>
<li>Or possibly HTML5/etc software to address all of the above</li>
<li>Backend / data / system management software</li>
<li>Or even, possibly, locally installed desktop software</li>
</ul>
<p>I apologize for the vagueness of this list; but I agree with Derek Sivers about <a href="http://sivers.org/zipit">keeping one&#8217;s specific goals to oneself</a> so my voluminous and tedious notes on exactly what products to offer, will remain offline.</p>
   ]]></content:encoded>
			<wfw:commentRss>http://kylecordes.com/2010/in-the-arena/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

<!-- Dynamic page generated in 1.195 seconds. -->
<!-- Cached page generated by WP-Super-Cache on 2012-02-04 01:50:56 -->
<!-- Compression = gzip -->
