<?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>The Blog of Justice &#187; Programming</title>
	<atom:link href="http://blog.strafenet.com/category/programming/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.strafenet.com</link>
	<description>Since 2004</description>
	<lastBuildDate>Mon, 30 Jan 2012 20:33:10 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Working with Terrible Code, Part One: CKEditor is not to be trusted (writing a CKEditor plugin)</title>
		<link>http://blog.strafenet.com/2011/12/20/understanding-terrible-code-part-one-ckeditor-is-not-to-be-trusted/</link>
		<comments>http://blog.strafenet.com/2011/12/20/understanding-terrible-code-part-one-ckeditor-is-not-to-be-trusted/#comments</comments>
		<pubDate>Wed, 21 Dec 2011 00:10:47 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[Chris]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://blog.strafenet.com/?p=2031</guid>
		<description><![CDATA[Understanding Terrible Code, Part One: Writing a CKEditor Plugin Exposition: Why should you care about a random text editor? Modding CKEditor is a well-designed exercise in self-flagellation. CKEditor is a text editor plugin that works with rich text (bold, italics, tables, links, etc.). If you&#8217;ve ever used Gmail or Hotmail, you&#8217;ve used something similar.  CKEditor [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: center;"><strong>Understanding Terrible Code, Part One:</strong></p>
<p style="text-align: center;"><strong>Writing a CKEditor Plugin</strong></p>
<p>Exposition: Why should you care about a random text editor?</p>
<p><strong>Modding CKEditor is a well-designed exercise in self-flagellation.</strong></p>
<p><strong></strong><a href="http://ckeditor.com/demo">CKEditor</a> is a text editor plugin that works with rich text (bold, italics, tables, links, etc.). If you&#8217;ve ever used Gmail or Hotmail, you&#8217;ve used something similar.  CKEditor is relatively easy to <em>use</em>, powerful and has lots of features, and it&#8217;s used <a href="http://ckeditor.com/who-is-using-ckeditor">everywhere</a>. But while the code is well written and well documented, at a macro level there are terrible design things going on, and if you want to <em>modify</em> it, you&#8217;ll want to shoot yourself shortly thereafter.</p>
<p>Since I&#8217;ve been wrestling with it for quite a while now, I wanted to share my thoughts:</p>
<ul>
<li><strong>In case you happen to be forced to alter CKEditor as well.</strong> Hopefully this will be a useful breadcrumb trail.</li>
<li><strong>To convince myself I&#8217;m not faking it.</strong> CKEditor has well written source, so someone could argue &#8220;maybe they&#8217;re doing it well and you just don&#8217;t get it.&#8221;<br />
This is perfectly valid. The best way to figure out if I&#8217;m faking it is to actually try and explain <em>why it&#8217;s bad</em>, and see if this post turns into &#8220;CKEditor is an architectural marvel&#8221; in the process.</li>
<li><strong>Complaining is whining unless you can explain <em>why</em></strong>, and how to make things better.</li>
<li>I need to understand this stuff myself, and <strong>nothing helps with understanding like trying to explain</strong>.</li>
<li>Because I&#8217;ve been staring at this for days and need to say something.</li>
</ul>
<h2>Act One: Parallel Universe APIs</h2>
<p>Half of CKEditor code essentially replicates JavaScript DOM APIs and jQuery. Let&#8217;s use the most radical example of CKEditor manipulation &#8211; the dialog architecture.</p>
<p>CKEditor dialogs are used for special properties. If you want to add a link, you would create a dialog to set the URL.</p>
<p>What language do you think dialogs would be designed in? <em>Presumably a language that is used to lay things out in a web browser.</em> Hmmm&#8230;what language do we use for that&#8230;HT nope, you&#8217;re right, it&#8217;s JavaScript:</p>
<blockquote><p>The new dialog system in CKEditor is to be written from scratch. One of the key things in CKEditor is that it doesn&#8217;t rely on HTML pages to run. Everything is created on the fly in JavaScript. In this way, we avoid limitations about cross domain serving of the editor code, like CDN solutions, and enhance the editor performance.</p>
<p><a href="http://docs.cksource.com/FCKeditor_3.x/Design_and_Architecture/Dialog_System#Dialog_Definition">http://docs.cksource.com/FCKeditor_3.x/Design_and_Architecture/Dialog_System#Dialog_Definition</a></p></blockquote>
<p>We&#8217;ll get back to the benefits CKEditor claims later, but let&#8217;s think about this. You&#8217;re laying out a mini-web page. You&#8217;re a web developer and probably lay out web pages all the time. You read <a href="http://www.alistapart.com/">A List Apart</a> obsessively; you understand the difference between content (HTML), presentation (CSS), and behavior (JavaScript), and the benefits of <a href="http://www.alistapart.com/articles/separationdilemma/">separating</a> them.</p>
<p>And then you see this:</p>
<p><iframe style="border: none; width: 100%;" src="http://pastebin.com/embed_iframe.php?i=ccbncmPy" width="320" height="360"></iframe></p>
<p>(This is actual dialog code that CKEditor uses to show a link dialog.)</p>
<p>Is that HTML? Yup &#8211; it looks like a &lt;select&gt; &#8211; there&#8217;s a list of options (items), and an id, and even a label.<br />
Is that JavaScript? Yup &#8211; it&#8217;s got an onChange, a setup, and a commit, whatever that is.</p>
<p>This confuzzlement is compounded by the fact that there are about 1000 (<a href="http://svn.ckeditor.com/CKEditor/trunk/_source/plugins/link/dialogs/link.js">literally, see for yourself</a>) lines of this JavaScript/HTML hybrid. If you separated this into HTML and JavaScript, it would be easy to read, not indented <del>six</del> ten tabs in, and it wouldn&#8217;t take you an hour of sorting to figure out what a dialog that&#8217;s basically a handful of selects and some text fields is doing.</p>
<p>By the way, there&#8217;s CSS too:</p>
<blockquote>
<pre>		var basicCss =
			'background:url(' + CKEDITOR.getUrl( this.path + 'images/anchor.gif' ) + ') no-repeat ' + side + ' center;' +
			'border:1px dotted #00f;';</pre>
</blockquote>
<p>Let&#8217;s establish some of the downsides of this mixed-content architecture:</p>
<ul>
<li>Wading a thousand four-hundred line morass of mixed behavior and content every time you want to change things</li>
<li>No way to test the layout of your dialog without loading all of CKEditor (as opposed to HTML, which can be tested by anyone with a web browser)</li>
<li>You have to relearn all your HTML/JavaScript/CSS ninja skills in a weird JS hybrid</li>
<li>Oh and if you miss a brace, it&#8217;s not like missing an angle bracket &#8211; everything dies. JS is brittle. Did I mention you have to reload all of CKEditor to test your fixes?</li>
</ul>
<p>So how about the benefits? The CKEditor docs claim that you can do cross domain* loading (for content delivery networks, etc.). While there are plenty of things wrong with the solution, the CDN problem is serious and it would be irresponsible to ignore it. Is there another way we can allow CDN loading without replacing all of our HTML with JavaScript?</p>
<p>One option: Write HTML for the dialogs, but convert it into escaped JavaScript internally. Escaped HTML is ugly, but if we compile it, we needn&#8217;t use it except in production.</p>
<p>This rant is just barely getting started, but I&#8217;ll stop here for the moment.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.strafenet.com/2011/12/20/understanding-terrible-code-part-one-ckeditor-is-not-to-be-trusted/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using code coverage to decide what to deprecate</title>
		<link>http://blog.strafenet.com/2011/12/09/using-code-coverage-to-decide-what-to-deprecate/</link>
		<comments>http://blog.strafenet.com/2011/12/09/using-code-coverage-to-decide-what-to-deprecate/#comments</comments>
		<pubDate>Fri, 09 Dec 2011 16:39:12 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[Chris]]></category>
		<category><![CDATA[Politics]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://blog.strafenet.com/?p=2007</guid>
		<description><![CDATA[A recent post on building a slimmer jQuery got me thinking about the process of deciding what to cut. From a code perspective, it&#8217;s easier to add new features than remove old ones. From a user perspective, it&#8217;s much, much easier to add new features than remove old ones. Nobody knows about your new feature, [...]]]></description>
			<content:encoded><![CDATA[<p>A recent post on<a href="http://blog.jquery.com/2011/11/08/building-a-slimmer-jquery/"> building a slimmer jQuery</a> got me thinking about the process of deciding what to cut.</p>
<p>From a code perspective, it&#8217;s easier to add new features than remove old ones.</p>
<p>From a user perspective, <em>it&#8217;s <strong>much, much</strong> easier to add new features than remove old ones.</em></p>
<p><em></em><strong>Nobody</strong> knows about your new feature, but there are at least three people who love that button you added to the toolbar two years ago. Even if no one else cares, they&#8217;ll make sure to post angry requests on your forums asking why you got rid of it. If you&#8217;re not careful, they&#8217;ll accuse your company of &#8220;not caring about its users,&#8221; or they might even say you &#8220;used to be great, but ever since they got successful they&#8217;ve started to go downhill&#8221;&#8230;ever hear that before? [1]</p>
<p>At the same time, it&#8217;s important to cut features, or you end up sliding down this curve:</p>
<p><img class="alignnone" title="Featuritis" src="http://headrush.typepad.com/photos/uncategorized/featuritis.jpg" alt="" width="440" height="343" /></p>
<p>So how do you decide what to cut?</p>
<h1>Why Not Just Count?</h1>
<p>One of the great things about analytics is getting real data about who&#8217;s using what. Every month, Google Analytics sends me an email that tells me exactly what people are reading on this blog. (Hint: It&#8217;s not the minesweeper articles)</p>
<p>That gave me an idea: Why not generate similar analytics for a library like jQuery?</p>
<p>There&#8217;s a nice list of sites using jQuery available here:</p>
<p><a href="http://docs.jquery.com/Sites_Using_jQuery">http://docs.jquery.com/Sites_Using_jQuery</a></p>
<p>Let&#8217;s take a site and see what it&#8217;s actually using:</p>
<p><a href="http://blog.strafenet.com/wp-content/uploads/2011/12/jQuery-on-Match.png"><img class="size-medium wp-image-2008 alignnone" title="jQuery on Match" src="http://blog.strafenet.com/wp-content/uploads/2011/12/jQuery-on-Match-300x240.png" alt="" width="300" height="240" /></a></p>
<p><em>(Speaking of wanting to stick to old things, Match.com uses jQuery 1.2&#8230;)</em></p>
<p>Match.com&#8217;s landing page is simple enough that we can do an actual list of what calls they make to jQuery, which I&#8217;ve uploaded <a href="http://blog.strafenet.com/wp-content/uploads/2011/12/jQuery-Usage.txt">here</a>.</p>
<p>From this, we can tell that the standard selector function $() gets used a lot, as does readCookie and addClass. From there, the next step is to figure out what they&#8217;re actually calling.</p>
<p>In the case of jQuery, this is not too hard in principle. Get a version of jQuery, add a line that increments a counter every time a function is used, and inject it into your favorite website. It&#8217;s a little too involved for this post, but perhaps in the future (earlier if someone decides to jump in and do it!)</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>[1] Back in the 90s, Microsoft obsessed about making sure everything from the past worked, even if it mean<a href="http://www.joelonsoftware.com/articles/APIWar.html"> keeping broken things</a> from earlier versions of Windows:</p>
<blockquote><p>The Windows testing team is huge and one of their most important responsibilities is guaranteeing that everyone can safely upgrade their operating system, no matter what applications they have installed, and those applications will continue to run, even if those applications do bad things or use undocumented functions or rely on buggy behavior that happens to be buggy in Windows <em>n</em> but is no longer buggy in Windows <em>n</em>+1. In fact if you poke around in the AppCompatibility section of your registry you&#8217;ll see a whole list of applications that Windows treats specially, emulating various old bugs and quirky behaviors so they&#8217;ll continue to work.</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://blog.strafenet.com/2011/12/09/using-code-coverage-to-decide-what-to-deprecate/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Exceptions</title>
		<link>http://blog.strafenet.com/2011/10/08/the-exceptions/</link>
		<comments>http://blog.strafenet.com/2011/10/08/the-exceptions/#comments</comments>
		<pubDate>Sat, 08 Oct 2011 04:50:03 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[Business/The Software Industry]]></category>
		<category><![CDATA[Chris]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://blog.strafenet.com/?p=1991</guid>
		<description><![CDATA[The scenario: A simple prototype in JavaScript, so I could test play an MVP of my new game. The problem: Why is this d_mn thing taking so long? &#160; Ever since I started working on my own, I&#8217;ve spend far more time figuring out how to motivate myself. Because I&#8217;m working in a startup, I [...]]]></description>
			<content:encoded><![CDATA[<p>The scenario: A simple prototype in JavaScript, so I could test play an MVP of my new game.</p>
<p><em>The problem: Why is this d_mn thing taking so long?</em></p>
<p>&nbsp;</p>
<p>Ever since I started working on my own, I&#8217;ve spend far more time figuring out how to motivate myself. Because I&#8217;m working in a startup, I make sure to do just the minimum amount of work to make a viable product, so that I can save time and work on other things.</p>
<p>And yet, I find myself staring into space, going on Google Reader, Hacker News, playing games, or anything I can find aside from work.</p>
<p>As I&#8217;m talking with a friend online, we make some observations:</p>
<ul>
<li>While the eventual result is interesting, the work I&#8217;m doing is boring.</li>
<li>The reason I&#8217;m bored is because the work is easy.</li>
<li><strong>Therefore, if I want to be more productive, I need to make my work harder.</strong></li>
</ul>
<p>I throw out the disorderly, simple, get it done code that everyone says you should write for a prototype. I make things organized. I put all my variables into neat, sensible structures that follow design principles. <em>I use a regular expression to replace 6 lines that I could&#8217;ve done by hand in five minutes.</em></p>
<p><em></em>All of a sudden, I&#8217;m getting work done again.</p>
<p>What gives?</p>
<p>&#8211;</p>
<p>I&#8217;ve talked with scores of startups over the years, and they consistently err on the side of overbuilding rather than underbuilding. Fancy prototypes take months to code, months that are wasted if your idea of a customer is the two people you told at the startup meetup you went to last week that said it looked kind of cool; people create entire frameworks to build sites that could be done in the time it takes to write a shell script (that installs WordPress).</p>
<p>Thus, the rule to build fast and build cheap was born.</p>
<p>Am I some kind of unlikely exception? Perhaps. But after giving it more thought, I realized that the need to make some things hard is not surprising, and not unique.</p>
<p>&#8211;</p>
<p>Are you working at a startup?</p>
<p>Why?</p>
<p>The pay is (sometimes) lower and the responsibilities are (often) greater. Most of the programmers I know working on their own projects are <em>exceptionally goo</em>d at programming. The hackers aren&#8217;t hanging out at the back of the bell curve. They can pass FizzBuzz, they know it, and that&#8217;s exactly why they&#8217;re finding a place where they live or die by their skills.</p>
<p>So it&#8217;s not entirely surprising that, if you pick people who are fairly competent at coding, so competent that they want to go to a place where they may be solely responsible for the technical success of the product they build, that they might just prefer not to always have simple, somnambulist-friendly code assignments.</p>
<p>Now, as with any essay that argues a point, you can poke holes in this thesis. Perhaps, you might say, the original rule isn&#8217;t against giving yourself a technical challenge from time to time, but rather as a safety railing to stop the people who want to make Pandora Craigslist Farmville with an extra layer on top so you can tag your singing cows with pictures from your last missed connection. And that&#8217;s a fair point.</p>
<p><span style="text-decoration: underline;">What we do</span> thrives on exceptions. I wouldn&#8217;t be able to think of a good example, but by chance, I read of one in the NYT yesterday:</p>
<blockquote><p>When asked what market research went into the iPad, Mr. Jobs replied: “None. It’s not the consumers’ job to know what they want.”</p></blockquote>
<p>Do what works.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.strafenet.com/2011/10/08/the-exceptions/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to use dbgsrv, the Process Server</title>
		<link>http://blog.strafenet.com/2011/04/04/using-dbgsrv-the-process-server/</link>
		<comments>http://blog.strafenet.com/2011/04/04/using-dbgsrv-the-process-server/#comments</comments>
		<pubDate>Mon, 04 Apr 2011 22:59:26 +0000</pubDate>
		<dc:creator>Tim</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Tim]]></category>

		<guid isPermaLink="false">http://blog.strafenet.com/?p=1902</guid>
		<description><![CDATA[If you&#8217;ve ever used Debugging Tools for Windows, you&#8217;ve probably used remote debugging. Users of windbg/ntsd are usually familiar with the &#8220;.server&#8221; command and connecting to remote debugging sessions using &#8220;Connect to Remote Session&#8221; in windbg. Knowing this, what good is the dbgsrv utility that comes with the Debugging Tools for Windows? How is it different [...]]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;ve ever used <a href="http://msdn.microsoft.com/en-us/windows/hardware/gg463009.aspx">Debugging Tools for Windows</a>, you&#8217;ve probably used remote debugging. Users of windbg/ntsd are usually familiar with the &#8220;.server&#8221; command and connecting to remote debugging sessions using &#8220;Connect to Remote Session&#8221; in windbg. Knowing this, what good is the dbgsrv utility that comes with the Debugging Tools for Windows? How is it different from a normal remote debugging session?</p>
<p>For anyone familiar with dbgsrv, it is similar in purpose and function to <a href="http://msdn.microsoft.com/en-us/library/xf8k2h6a.aspx">msvsmon, the visual studio remote debugging monitor</a>. Both applications are &#8220;process servers&#8221; for their respective debugging environment. Running dbgsrv on a remote machine allows developers to attach to any process on that machine, or launch processes under the debugger.</p>
<p>Using dbgsrv is slightly mysterious, as the UI for using it is a bit cryptic in WinDbg. I&#8217;m going to run through a few examples to show how useful dbgsrv can be.</p>
<p>To start, we need to get dbgsrv running on the machine you want to debug. Usually, this will be a test computer that you want to debug from your development computer. If you want to follow along the examples, you can use a single machine, although this scenario isn&#8217;t very useful for real world debugging. To start dbgsrv, run it from the command line giving it parameters to pick a transport to use. Usually, tcp is the easiest when not working with domain-joined machines:</p>
<p><code>dbgsrv -t tcp:port=31337</code></p>
<p>If there are no errors, dbgsrv will start silently and start listening for connections. (You may see a firewall dialog at this point). To use the process server from windbg, use the &#8220;Connect to Remote Stub&#8230;&#8221; menu item from the File menu:</p>
<p><img src="http://blog.strafenet.com/wp-content/uploads/2011/04/remoteStub.png" alt="Screenshot of Connect to Remote Stub in Windbg" /></p>
<p>The connection string should match what you&#8217;ve started dbgsrv with. For instance, if dbgsrv is running on my computer named &#8220;timtst&#8221;, I would connect to &#8220;tcp:port=31337,server=timtst&#8221;. After accepting the connection string in this dialog, there will be no indication of failure or success until you actually try to use it. Once the connection string is entered, you can try to attach to a process using File-&gt;Attach to Process, or using F6. If the connection was successful, you will see a list of processes on your test computer, or an error if the connection was not successful.</p>
<p>To use the same functionality in cdb/ntsd, you can use the &#8220;premote&#8221; command line argument. For instance, to use the same dbgsrv instance as in the previous example to attach to process ID 4000, you can use the following command with ntsd:</p>
<p><code>ntsd -premote tcp:port=31337,server=timtst -p 4000</code></p>
<p>Using ntsd also lets you start a process under the debugger through a process server:</p>
<p><code>ntsd -premote tcp:port=31337,server=timtst C:\MyTestApp.exe</code></p>
<p>Note that the path given refers to a path on the remote machine running dbgsrv, not the machine running ntsd. This functionality is not available in windbg.</p>
<p>There is an excellent write-up with more information about dbgsrv at <a href="http://www.nynaeve.net/?p=35">nynaeve.net</a></p>
<p>If you&#8217;ve found this interesting, I highly recommend the book <a href="http://www.amazon.com/gp/product/0321374460/ref=as_li_ss_tl?ie=UTF8&#038;tag=thebloofjus01-20&#038;linkCode=as2&#038;camp=217145&#038;creative=399369&#038;creativeASIN=0321374460">Advanced Windows Debugging</a><img src="http://www.assoc-amazon.com/e/ir?t=thebloofjus01-20&#038;l=as2&#038;o=1&#038;a=0321374460&#038;camp=217145&#038;creative=399369" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" /><br />
 by Daniel Pravat. As one of the most informative books about the Windows Debugging toolset, it has a host of information about dbgsrv and the rest of the tools.</p>
<p><iframe src="http://rcm.amazon.com/e/cm?lt1=_blank&#038;bc1=000000&#038;IS2=1&#038;bg1=FFFFFF&#038;fc1=000000&#038;lc1=0000FF&#038;t=thebloofjus01-20&#038;o=1&#038;p=8&#038;l=as4&#038;m=amazon&#038;f=ifr&#038;ref=ss_til&#038;asins=0321374460" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"></iframe></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.strafenet.com/2011/04/04/using-dbgsrv-the-process-server/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Travelling down a stack of dependency woes &#8211; How to parse HTML in Windows with Python</title>
		<link>http://blog.strafenet.com/2010/08/09/travelling-down-a-stack-of-dependency-woes-how-to-parse-html-in-windows-with-python/</link>
		<comments>http://blog.strafenet.com/2010/08/09/travelling-down-a-stack-of-dependency-woes-how-to-parse-html-in-windows-with-python/#comments</comments>
		<pubDate>Tue, 10 Aug 2010 02:40:32 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[Chris]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://blog.strafenet.com/?p=887</guid>
		<description><![CDATA[I was hoping I could parse HTML in Python in Windows. As it turned out, every step I tried ended up leading to another step. In case you are about to lose an entire day dealing with all these steps, I wrote them here. Problem 1: Beautiful Soup isn&#8217;t supported anymore Beautiful Soup is the [...]]]></description>
			<content:encoded><![CDATA[<p>I was hoping I could parse HTML in Python in Windows. As it turned out, every step I tried ended up leading to another step.  In case you are about to lose an entire day dealing with all these steps, I wrote them here.</p>
<ol>
<li><em>Problem 1: Beautiful Soup isn&#8217;t supported anymore</em><br />
Beautiful Soup is the de facto HTML parser. Beloved by Python programmers, it&#8217;s capable of dealing with broken and messy HTML. Sadly, the libraries that it used are being replaced, and the main developer <a href="http://www.crummy.com/software/BeautifulSoup/3.1-problems.html">doesn&#8217;t have time to work on it anymore</a>.<br />
Solution: This was the easiest problem to deal with. I asked the New York Python Meetup, and they all recommended lxml.</li>
<li><em>Problem 2: lxml doesn&#8217;t have a Python 2.7 build</em><br />
The easy solution &#8211; &#8220;easy_install lxml&#8221; &#8211; is supposed to get an egg file precompiled with lxml&#8217;s dependencies (at least, says the INSTALL file in the download).<br />
There were two problems:<br />
1. It doesn&#8217;t<br />
2. None of the .exes on the site are for Python 2.7.<br />
Solution: As it turns out, there&#8217;s a way around this dilemma; someone&#8217;s posted a <a href="http://codespeak.net/pipermail/lxml-dev/2010-July/005574.html">script</a> to build it online. It&#8217;s only for 32-bit though, it seems, but I gave it a short spin anyway.</li>
<li><em>Problem 3: Cython error</em><br />
Solution: <a href="http://www.lfd.uci.edu/~gohlke/pythonlibs/#cython">This fix was easy</a>.</li>
<li><em>Problem 4: &#8220;vcvarsall.bat&#8221; missing</em><br />
As it turns out, building many Python packages requires vcvarsall.bat, which is probably a compiling tool of some kind in Microsoft&#8217;s toolchain. The <a href="http://code.google.com/p/rdflib/issues/detail?id=104#c4">fix</a> that comes up in search engine results involve <a href="http://blog.eddsn.com/2010/05/unable-to-find-vcvarsall-bat/">hacking in a different compiler</a> (gcc from MinGW), which I suspected might cause other incompatibilities.<br />
Solution: After talking with a friend from Microsoft, I determined that downloading and installing the Windows SDK would be a good place to start. Though that didn&#8217;t work, I did end up installing Visual Studio C++ Express, which did include vcvarsall.bat.</li>
<li><em>Problem 5: &#8220;vcvarsall.bat&#8221; missing</em><br />
For some unknown reason, even after adding vcvarsall to the path,  the error still came up.<br />
Solution: It was at this point that I realized that the build script was for 32-bit. If I was going to go through the trouble of trying it, maybe it would be worth trying a 32-bit precompiled exe, which I ended up discovering on the <a href="http://www.lfd.uci.edu/~gohlke/pythonlibs/">same site</a> I visited earlier.</li>
<li><em>Problem 6: Installation didn&#8217;t work</em><br />
Even though the install went find and &#8220;import lxml&#8221; worked without a hitch, the lxml package was strangely empty &#8211; there was nothing in it!<br />
Solution: I went through site-packages and cleaned it out &#8211; there were two separate lxmls in there from my previous experiments. Removing one of them cleared it all up.</li>
</ol>
<p>(I recently had an experience where I couldn&#8217;t beta test some software because it was built for 32-bit, but my computer was 64-bit. As it turned out, that didn&#8217;t apply here.)</p>
<p>Possible lesson: If something is unlikely to work, but is easy and quick, try it anyway.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.strafenet.com/2010/08/09/travelling-down-a-stack-of-dependency-woes-how-to-parse-html-in-windows-with-python/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Which programming language and which framework should I use?</title>
		<link>http://blog.strafenet.com/2009/09/19/which-programming-language-should-i-use/</link>
		<comments>http://blog.strafenet.com/2009/09/19/which-programming-language-should-i-use/#comments</comments>
		<pubDate>Sat, 19 Sep 2009 17:31:07 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[Chris]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://blog.strafenet.com/?p=837</guid>
		<description><![CDATA[Frameworks like Ruby on Rails are great because they make it easy to write code &#8211; in a way that makes sense for the problem of websites. Programming languages are great because they make it easy to write code &#8211; in a way that makes it easier for us to understand. In the end though, [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: center;">Frameworks like Ruby on Rails are great because they make it easy to write code &#8211; in a way that makes sense for the problem of websites.</p>
<p style="text-align: center;">Programming languages are great because they make it easy to write code &#8211; in a way that makes it easier for us to understand.</p>
<p style="text-align: center;">In the end though, all of these abstractions were not written with <strong>your</strong> problem in mind, but a generic, off-the-shelf problem that you don&#8217;t actually have.</p>
<p style="text-align: center;">Thus, write with any language you want. But write in a way that&#8217;s appropriate to your problem, and write in a way that&#8217;s appropriate to you.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.strafenet.com/2009/09/19/which-programming-language-should-i-use/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Don&#8217;t Work on the Wrong Machine</title>
		<link>http://blog.strafenet.com/2008/08/28/dont-work-on-the-wrong-machine/</link>
		<comments>http://blog.strafenet.com/2008/08/28/dont-work-on-the-wrong-machine/#comments</comments>
		<pubDate>Fri, 29 Aug 2008 03:35:27 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[Business/The Software Industry]]></category>
		<category><![CDATA[Chris]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://blog.strafenet.com/2008/08/28/dont-work-on-the-wrong-machine/</guid>
		<description><![CDATA[Fred Brooks: Build one to throw away My version: Build every one to throw away. Fred Brooks&#8217; classic The Mythical Man-Month made this observation developing a new piece of software &#8211; inevitably, many of the problems that will need to be solved won&#8217;t be known until you try to solve them. The first try will [...]]]></description>
			<content:encoded><![CDATA[<p>Fred Brooks: <a href="http://en.wikipedia.org/wiki/The_Mythical_Man-Month#The_Pilot_System">Build one to throw away</a></p>
<p>My version: Build <strong>every </strong>one to throw away.</p>
<p>Fred Brooks&#8217; classic <em>The Mythical Man-Month</em> made this observation developing a new piece of software &#8211; inevitably, many of the problems that will need to be solved won&#8217;t be known until you try to solve them. The first try will incorporate many feelings of should-have and would-have that will be fixed on the second try.</p>
<p><img src="http://s.wsj.net/public/resources/images/P1-AK471A_CARTE_20080208185227.jpg" alt="Carter made a bench!" width="245" height="123" /></p>
<p>This is much like a journeyman craftsman building his or her first <a href="http://online.wsj.com/article/SB120252109283355793.html">bench</a>, or planting their first garden. The first try is a learning experience. There is no way around this, nor should there be &#8211; learning is often best by doing. <strong>The valuable asset is the experience of the builder</strong>, not the product.</p>
<p>But we don&#8217;t live in the Middle Ages, the age of guilds. We live in the post-Industrial Age. Factory owners don&#8217;t consider hoarding all the toys or cars or electronics they produce as an asset. Henry Ford&#8217;s genius was to redesign not just the golden eggs, but the machine that lays them.</p>
<p>As programmers, we are not working on a code base. <em>We are working on a machine that produces code</em>. The machine is made up of us, our experiences, the tools we build to make code (which can be made out of code themselves!). This is where results come from, and we should spend our time tuning this machine by <a href="http://www.codinghorror.com/blog/archives/001160.html">producing more</a>, not protecting what we have.</p>
<p><em>Does this mean that we should <a href="http://www.joelonsoftware.com/articles/fog0000000069.html">throw out old code</a>?</em> By no means! Old code is one of the most efficient resources we have for producing new code. But every process of manufacture in the past has been made into a more automatic and refined process. How could we consider ourselves any different?</p>
<p><em>Does this mean that we should code like crap?</em> By no means! As was once said, &#8220;If you write the first one to throw out, you will end up throwing out the second one as well.&#8221; The point is, write good code, but be willing to write new code &#8211; the point is to make not good code, but a good code factory.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.strafenet.com/2008/08/28/dont-work-on-the-wrong-machine/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Mulberry: Tribute to the Greatest E-mail Program of All Time</title>
		<link>http://blog.strafenet.com/2008/05/21/mulberry-tribute-to-the-greatest-e-mail-program-of-all-time/</link>
		<comments>http://blog.strafenet.com/2008/05/21/mulberry-tribute-to-the-greatest-e-mail-program-of-all-time/#comments</comments>
		<pubDate>Wed, 21 May 2008 05:19:26 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[Chris]]></category>
		<category><![CDATA[General/Misc.]]></category>
		<category><![CDATA[Product Design]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[UI Design]]></category>

		<guid isPermaLink="false">http://blog.strafenet.com/2008/05/21/mulberry-tribute-to-the-greatest-e-mail-program-of-all-time/</guid>
		<description><![CDATA[For years I have used and loved Mulberry, perhaps the best e-mail client in existence. So I was greatly saddened to hear that Cyrusoft, the company behind Mulberry, declared bankruptcy a year ago. [more (full article)] I was just as much shocked as dismayed. Mulberry was hawked by so many colleges that I assumed its [...]]]></description>
			<content:encoded><![CDATA[<p>For years I have used and loved Mulberry, perhaps the best e-mail client in existence. So I was greatly saddened to hear that Cyrusoft, the company behind Mulberry, declared bankruptcy a year ago.</p>
<p><a href="http://www.christopherliu.net/mulberry_greatest/">[more (full article)]</a></p>
<p>I was just as much shocked as dismayed. Mulberry was hawked by <a href="http://www.cmu.edu/computing/mulberry/" title="CMU/Mulberry">s</a>o many colleges that I assumed its destiny was all but sealed. College students, as early adopters, would all be exposed to Mulberry and see how wonderful it was, and they&#8217;d take it to their jobs, promoting an almost viral spread.</p>
<p>I guess the Thunderbird/Outlook duopoly was just too strong for Cyrusoft to handle. However, all is not lost, as Mulberry is available for free now.</p>
<p><a href="http://www.christopherliu.net/mulberry_greatest/">Let&#8217;s take a look at all the wonderful features of this program! (full article)</a></p>
<p>[originally started a long time ago]</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.strafenet.com/2008/05/21/mulberry-tribute-to-the-greatest-e-mail-program-of-all-time/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Security in UI</title>
		<link>http://blog.strafenet.com/2008/03/15/security-in-ui/</link>
		<comments>http://blog.strafenet.com/2008/03/15/security-in-ui/#comments</comments>
		<pubDate>Sat, 15 Mar 2008 18:55:37 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[Chris]]></category>
		<category><![CDATA[General/Misc.]]></category>
		<category><![CDATA[Product Design]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[UI Design]]></category>

		<guid isPermaLink="false">http://blog.strafenet.com/2008/03/15/security-in-ui/</guid>
		<description><![CDATA[One of the most common ways to secure a computer is by using a username/password combination. (In fact, we don&#8217;t have to look far to find an example). However, this system is clunky, primarily because it requires you to remember or write down the user name and password for every site (or alternatively use the [...]]]></description>
			<content:encoded><![CDATA[<p>One of the most common ways to secure a computer is by using a username/password combination. (In fact, we don&#8217;t have to look far to find <a href="http://blog.strafenet.com/wp-login.php" title="Example of login">an example</a>). However, this system is clunky, primarily because it requires you to remember or write down the user name and password for every site (or alternatively use the same password everywhere).</p>
<p>Security is not just about locking down a system from a list of attacks. The way you design a UI dictates how people behave, and people&#8217;s behavior is responsible for 90% of attacks. [citation needed] <em>Defaults matter</em>. No one forgets to lock an automatically locking door.</p>
<p>The fact is, while a security system must be set up to prevent hacking attacks, guesswork, and theft, it must also be designed in such a way that leads people to behave more securely. When you have a system where keys are hard to create but easy to copy, naturally, people will end up using the same keys at eBay that they do at Flickr.</p>
<p>The need to &#8220;educate users&#8221; is an indication of design failure.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.strafenet.com/2008/03/15/security-in-ui/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>~One Paragraph Blog: How scary is the rewrite?</title>
		<link>http://blog.strafenet.com/2008/02/18/one-paragraph-blog-how-scary-is-the-rewrite/</link>
		<comments>http://blog.strafenet.com/2008/02/18/one-paragraph-blog-how-scary-is-the-rewrite/#comments</comments>
		<pubDate>Mon, 18 Feb 2008 05:52:49 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
				<category><![CDATA[Chris]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://blog.strafenet.com/2008/02/18/one-paragraph-blog-how-scary-is-the-rewrite/</guid>
		<description><![CDATA[Do you work in software engineering? Have you ever heard a coworker say, &#8220;I&#8217;d do X, but then I&#8217;d have to rewrite everything?&#8221; Truth is, it&#8217;s easier to rewrite everything than make small changes sometimes. How could I justify something so outlandish? Simple. The difficulty of a change (how many hiccups, how many bugs) depends [...]]]></description>
			<content:encoded><![CDATA[<p>Do you work in software engineering? Have you ever heard a coworker say, &#8220;I&#8217;d do X, but then I&#8217;d have to rewrite everything?&#8221; Truth is, it&#8217;s <em>easier to rewrite everything than make small changes</em> sometimes.</p>
<p>How could I justify something so outlandish? Simple. The difficulty of a change (how many hiccups, how many bugs) depends not so much on its scope as it does on how well planned it is. Inevitably, we <strong>underestimate</strong> how much planning <strong>small changes</strong> take, and <strong>overestimate </strong>when we see <strong>big, scary changes</strong>. Does this mean rewrite is easy? Of course not. But it&#8217;s not impossible, or as costly as we think, and just the opposite is true for minor changes.</p>
<p>*The usual caveats: If you have a problem that can be solved with a small change, I recommend sticking to that before resorting to bigger changes. But once you start seeing so-called small changes multiply, you may have hit the <a href="http://blog.strafenet.com/2008/01/23/todays-one-paragraph-blog-the-stall-point/"><em>stall point</em></a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.strafenet.com/2008/02/18/one-paragraph-blog-how-scary-is-the-rewrite/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
<!-- This Quick Cache file was built for (  blog.strafenet.com/category/programming/feed/ ) in 0.26631 seconds, on Feb 5th, 2012 at 12:03 pm UTC. -->
<!-- This Quick Cache file will automatically expire ( and be re-built automatically ) on Feb 5th, 2012 at 1:03 pm UTC -->
