<?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>hackinghat.com &#187; article</title>
	<atom:link href="http://www.hackinghat.com/index.php/category/article/feed" rel="self" type="application/rss+xml" />
	<link>http://www.hackinghat.com</link>
	<description></description>
	<lastBuildDate>Wed, 19 May 2010 07:48:25 +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>The Spread-able System</title>
		<link>http://www.hackinghat.com/index.php/article/the-spread-able-system</link>
		<comments>http://www.hackinghat.com/index.php/article/the-spread-able-system#comments</comments>
		<pubDate>Tue, 06 Jan 2009 08:23:02 +0000</pubDate>
		<dc:creator>Steve Knight</dc:creator>
				<category><![CDATA[article]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://www.hackinghat.com/index.php/article/the-spread-able-system</guid>
		<description><![CDATA[Spreadsheets are everywhere. They are simple to create and are an immensely powerful tool. Unsurprisingly then this means that a lot of areas of business rely on spreadsheets to function correctly. But spreadsheets are dangerous too. They suffer from, well-known, fundamental flaws. The problem is that spreadsheets are a special type of code, and I&#8217;m [...]]]></description>
			<content:encoded><![CDATA[<p>Spreadsheets are everywhere.   They are simple to create and are an immensely powerful tool.  Unsurprisingly then this means that a lot of areas of business rely on spreadsheets to function correctly.   But spreadsheets are dangerous too.    They suffer from, well-known, fundamental flaws.</p>
<p>The problem is that spreadsheets are a special type of code, and I&#8217;m not talking about the Excel &#8216;macros&#8217; I&#8217;m talking about the formulas.   As such they probably need to be treated the same way as other types of code, but their very nature makes this difficult.   But I&#8217;m getting ahead of myself, let&#8217;s first look at some of what is good and bad about spreadsheets.</p>
<h2>Pros</h2>
<p>Spreadsheets are remarkable for their: </p>
<ul>
<li><strong>Utility</strong> &#8211; we can bend them into almost any shape we want because they give one way to represent almost any business process;</li>
<li><strong>Portability</strong> &#8211; we can pick up our little gobbets of data and logic and relocate them to almost anywhere inside or outside the company, in file-systems, mail servers and web-sites;</li>
<li><strong>Simplicity</strong> &#8211; you don&#8217;t have to explain a spreadsheet to anyone.   They might have to be a proto-genius to figure out how it works but the working knowledge they would need to get started is pre-loaded in their heads and ready-to-run.</li>
</ul>
<h2>Cons</h2>
<p>So they sound pretty useful, and I like to think that I&#8217;m a pragmatic guy, so why do I hate them so much?   Many have noted about the shortcomings of spreadsheets.   The page on spreadsheets at <a href="http://en.wikipedia.org/Spreadsheet">Wikipedia</a> spells it out clearly enough so I&#8217;ll paraphrase:</p>
<ol>
<li><strong>Productivity</strong>  &#8211; Working with spreadsheets requires a lot of &#8220;sheet-shuffling&#8221; to reach the required goal.   The bigger the sheet, the more time is spent copying, cutting and pasting cells around.</li>
<li><strong>Reliability</strong> &#8211; Although what consitutes an error in a spreadsheet is subjective, the paper <a href="http://mba.tuck.dartmouth.edu/spreadsheet/product_pubs_files/Literature.pdf">A Critical Review of the Literature on Spreadsheet Errors&#8221; (pdf)</a> reveals a series of studies (some more recent than others) that have shown that approximately 5% of cells contain errors.</li>
<li><strong>Collaboration</strong> &#8211; Sharing a spreadsheet is difficult.   Having two independent people working on the same sheet and merging their results is as far as I know impossible.</li>
</ol>
<p>The first two items don&#8217;t bother me overly.   Yes, it&#8217;s a problem but then the alternatives aren&#8217;t that great either.   Consider what you would do if you didn&#8217;t have a spreadsheet to fulfill the task.   You&#8217;d either do it with a bit of paper and a calculator (i.e. simulate a spreadsheet) or get a programmer to do the task for you.   Either way the amount of productivity loss/gain and the amount of errors aren&#8217;t going to be that significantly different from using a spreadsheet.   Don&#8217;t get me wrong, I love my fellow programmer, but we make a LOT of mistakes too.   The difference perhaps is that bespoke systems usually end up getting audited (and hence fixed) and spreadsheets often don&#8217;t.   Although this point is probably moot.</p>
<h2>Good + Bad = Too Bad</h2>
<p>My real beef is with what happens when you have the &#8216;pro&#8217; of high portability with the &#8216;con&#8217; of low collaborative power.   <strong>You have no way of knowing which version of the spreadsheet you have is the &#8220;true&#8221; one, and which version is duff</strong>.   Every copy, whether it be inadvertently through forwarding a sheet by email to someone else or explicitly by taking a &#8216;backup&#8217; is a 12 foot tall baby-eating, business-crushing monster waiting to rip you and everyone you love apart.   </p>
<h2>Hug the Monster, Then Run</h2>
<p>The thing is we kind of have to embrace the baby-business-beating monster because it&#8217;s about all we&#8217;ve got.  There are some tasks, as a programmer, that I&#8217;m really happy that you as the non-programmer don&#8217;t bother me with and solve yourself in sheets.    Want to set-up an intra-company phone-book as a spreadsheet so you don&#8217;t have to bother will all that &#8220;Access&#8221; voodoo?  Be my guest, but I&#8217;m watching you.   Want to set-up a spreadsheet to run your fantasy football so you don&#8217;t have to add two numbers together?  Go right ahead, I&#8217;ll even drive you to the game so you don&#8217;t miss the turn.   Want to set up a spreadsheet to calculate payments and and do a mail-merge with the results &#8230; STOP.  RIGHT. NOW.</p>
<p>The truth is though that you might not know that you&#8217;re creating the mother-of-all spreadsheets when you start.   I might not know it either but there will probably come a time when a line is crossed and then I will want to know what you&#8217;ve been doing and who you&#8217;ve been doing it with.   I&#8217;m just like that.</p>
<p>Unless you are small company (and hence don&#8217;t have a lot of choice) you have to be very afraid of trusting anything that might lose you money to a spreadsheet.  You need to be very aware of the risks and the potential-costs you are letting yourself in for.   Here in Europe there is even a <a href="http://www.eusprig.org/index.htm">special interest group</a> dedicated to highlighting the risks of spreadsheets.   Those guys must throw wild parties &#8230;</p>
<h2>The Missing Links</h2>
<p>In my opinion there is something missing,  something that can fill the gap between spreadsheet and system.  </p>
<p>I think we need something that can:</p>
<ol>
<li><strong>Track spreadsheet changes</strong> &#8211; Not knowing which spreadsheet is &#8220;true&#8221; and which lies (by being able to identify revisions of the sheet that have happened after yours was &#8216;branched&#8217;), and not being able to merge sheets is a problem.   Perhaps someone solved it already, if they had that would be great.</li>
<li><strong>Track spreadsheets themselves</strong> &#8211; Having some more information about what sort of corporate-data was being accessed, who was using it and how frequently they ran it might alert us to potential spreadsheet monsters being born.</li>
<li><strong>Narrow the gap</strong> &#8211; Making spreadsheets more like traditional software systems, without significantly castrating the usefulness of the spreadsheet, would be great too.  This is a little like asking for the <a href="http://www.urbandictionary.com/define.php?term=moon%20on%20a%20stick">moon on a stick</a> though.</li>
</ol>
<p>Perhaps I&#8217;ll make something like this one day.   I have to admit it&#8217;s not a terribly exciting project but it has some potential I think.   Perhaps I could spice it up by throwing a party and invite the guys from the &#8220;European Spreadsheet Risks Interest Group&#8221;.   <strong>Now</strong> we&#8217;re talking.    How will I budget for the 7-up, party hats and streamers?    In a spreadsheet of course.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.hackinghat.com/index.php/article/the-spread-able-system/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Educate A Business Person Today!</title>
		<link>http://www.hackinghat.com/index.php/article/educate-a-business-person-today</link>
		<comments>http://www.hackinghat.com/index.php/article/educate-a-business-person-today#comments</comments>
		<pubDate>Fri, 09 May 2008 06:06:42 +0000</pubDate>
		<dc:creator>Steve Knight</dc:creator>
				<category><![CDATA[article]]></category>

		<guid isPermaLink="false">http://www.hackinghat.com/index.php/article/educate-a-business-person-today</guid>
		<description><![CDATA[One recurring theme I have noticed with users of systems I&#8217;ve worked on, is that they aren&#8217;t nearly as stupid as I think. They often try to make sense of the system thrust in-front of them. This is mostly out of necessity since it stands between them and them doing their job, and so they [...]]]></description>
			<content:encoded><![CDATA[<p>One recurring theme I have noticed with users of systems I&#8217;ve worked on, is that they aren&#8217;t nearly as stupid as I think.   They often try to make sense of the system thrust in-front of them.  This is mostly out of necessity since it stands between them and them doing their job, and so they need to make sense of it.   Having written some truly awful systems myself I wish all of them the very best of luck.   </p>
<p>Another, seemingly unrelated observation, is that business people are truly astounded, and often suspicious, of how long it takes to provide a solution to a particular problem.    Writing software is simply hard so that partly explains it.  Sometimes however some of the solutions that are asked for can come quickly.   This might happen if the system was expressly designed to handle new cases of the particular solution being requested or if producing the solution requires little more than a configuration or script change.    Or it might just be dumb luck that the release cycle has worked in their favour.</p>
<h2>Disconnect</h2>
<p>This disconnect between implementation times, with no apparent reason to the business user can cause problems.   Sometimes it feeds the suspicion that they are being &#8216;had&#8217; in some elaborate con:  </p>
<blockquote><p>&#8220;If change &#8216;x&#8217; takes a week then surely change &#8216;y&#8217; should take half as long.   How could it not?  It only takes half as many words to say out loud.   Those guys in IT need firing.&#8221;</p></blockquote>
<p>   When that business person is a manager it can lead to awkward situations for developers:<br />
<blockquote>&#8220;Change &#8216;x&#8217; took a week, change &#8216;y&#8217; will take half as long.   How can it not?  It&#8217;s the only thing that stands between us and product success.  If it doesn&#8217;t I&#8217;ll fire those IT guys&#8221;.</p></blockquote>
<p>The simple truth is that unless a business person has also the developer&#8217;s view of the system they will not be able to make sound judgements about it.    Hell, I have a developers view and not even my judgements are particularly sound.</p>
<p>However humans are pretty adaptable creatures, and rather than telling them the answer we should explain the answer in a way that they can understand.   If they want to listen then educating them has a few potential benefits.   For one thing it might make you look like you care about your users, rather than being that IT jerk who steals everyone&#8217;s food from the refrigerator.   However, if you get your point across without sounding (to them) like a lunatic then you might improve their mental model of how the system actually works.   </p>
<h2>Breed</h2>
<p>There is a breed of programmer out their in the world today that has either evolved or engineered themselves into a situation where they are the only one who &#8216;knows&#8217;.    Yes, you know who you are.   Sometimes they do this as a survival instinct to make themselves indispensable, sometimes because they&#8217;re not great communicators or educators.   These are the people that need to be fired because their value is way-less than they think it is.   They actually harm the productivity of the company by being obstructive or uncommunicative, plus they&#8217;re a real pain-in-the-ass to work with.</p>
<p>Yes you will need to keep a watchful eye on your newly educated fledglings.   Especially the managers, but there&#8217;s nothing knew about that.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.hackinghat.com/index.php/article/educate-a-business-person-today/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Floating Point Flotsam</title>
		<link>http://www.hackinghat.com/index.php/article/floating-point-flotsam</link>
		<comments>http://www.hackinghat.com/index.php/article/floating-point-flotsam#comments</comments>
		<pubDate>Fri, 11 Apr 2008 04:48:42 +0000</pubDate>
		<dc:creator>Steve Knight</dc:creator>
				<category><![CDATA[article]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://www.hackinghat.com/index.php/uncategorized/floating-point-flotsam</guid>
		<description><![CDATA[I have never been particularly clear about when to choose single or double floating point arithmetic. I think I have been operating on a sort of &#8216;trial-and-error&#8217; approach for some time. It seems ludicrous that I should not, after all these years, know exactly when to chose single or double precision arithmetic. The truth is [...]]]></description>
			<content:encoded><![CDATA[<p>I have never been particularly clear about when to choose single or double floating point arithmetic.   I think I have been operating on a sort of &#8216;trial-and-error&#8217; approach for some time.   It seems ludicrous that I should not, after all these years, know exactly when to chose single or double precision arithmetic.  The truth is that I don&#8217;t, and it&#8217;s now time to fix that.  </p>
<p>First, a little background.  I was, for reasons that are too sad to explain, interested in how to calculate (accurately) the time of the Vernal Equinox.   That is the exact time of the year (to the minute &#8211; if possible) that the sun is 90<sup>o</sup> above the earth at the equator.    Anyway, I found some <a href="http://www.hermetic.ch/cal_sw/ve/ve_c.htm">code</a> which is an implementation of an <a href="http://www.willbell.com/math/mc1.htm">astronomical algorithim</a> designed expressly for the purpose of calculating the vernal equinox and is accurate to about 20 minutes.   Which is good enough for now.</p>
<p>Now the next piece of background is that I was also doing this in Lisp and up until now I have let the reader interpret all the literals I enter.   When I tried to do the calculation in the <a href="http://en.wikipedia.org/wiki/REPL">REPL</a> I could get no closer than being in the same part of the day as I was expecting and with the result somewhat rounded to the nearest half day.  After some head scratching it finally occurred to me that the the computation required more significant digits than I really had.   It seems that the formula I was entering was being interpreted as single precision floating point numbers because if I had wanted double&#8217;s I would have suffixed my literal numbers with a &#8216;d&#8217;.   It would seem that <strong>d</strong> could also stand for <strong>D&#8217;uh</strong>.  Seems fair enough.    Time to do some research then &#8230;</p>
<p>You see, according to the <a href="http://en.wikipedia.org/wiki/IEEE_floating-point_standard">IEEE standard 754-1985</a> a single precision floating point number has 23 significant bits and a double has 53 significant bits.   For me to answer the question of how many significant figures I can get in <strong>decimal</strong> would require me to know that the smallest decimal fraction that I can represent in binary is.   This number would be 1/2<sup>23</sup> which is about .00000011920928955078125.   </p>
<p>Now, floating point numbers are represented from a fractional part and an exponent part to give the decimal representation of the number.   Therefore you can never get more accuracy than the smallest binary fraction multiplied by the exponent you have.   This means that the significant figures should be something like: </p>
<p>log10(1/(2^23)) = -6.9
<p>Therefore when a number has 7 significant figures you are already losing a little accuracy, the more significant figures you add the worse it will get.  It was then clear that my astronomical antics were less than stellar since the first literal in the computation has 11 significant figures.   </p>
<p>Indeed whilst I was thinking about this problem it occurred to me that if I wanted to continue using single precision I could split the fractional part from the integer part and continue this way.   However, this is still inferior to a double because it would give me 7 significant figures for both parts and therefore a total of 14 significant figures.   This is inferior because using my shiny new brain I can show that a double will give about 16 signficant figures.  Of course I could have also concluded that double&#8217;s are better than two floats by noting that 23 bits+ 23 bits < 53 bits but that would never have been as much fun.   </p>
<blockquote><table>
<tr>
<th>Type</th>
<th>Word Size</th>
<th>Mantissa</th>
<th>Dec Sig. Figs.</th>
</tr>
<tr>
<td>Single</td>
<td>32</td>
<td>23</td>
<td>7</td>
</tr>
<tr>
<td>Double</td>
<td>64</td>
<td>53</td>
<td>16</td>
</tr>
<tr>
<td>Extended</td>
<td>96</td>
<td>63</td>
<td>19</td>
</tr>
<tr>
<td>Quad-Extended</td>
<td>128</td>
<td>113</td>
<td>34</td>
</tr>
</table>
</blockquote>
<p>You could argue that I could have saved myself 20 minutes of time by looking the <a href="http://threads.seas.gwu.edu/cgi-bin/man2web?program=ieee&#038;section=3">answer up</a> but then again I would never remember the answer unless I proved it to myself first.  So, now my spring occurs at the same time as everyone else&#8217;s and I know why.   Oh it happened already?  Sheeeeiiiitttt.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.hackinghat.com/index.php/article/floating-point-flotsam/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A Version Aversion</title>
		<link>http://www.hackinghat.com/index.php/article/a-version-aversion</link>
		<comments>http://www.hackinghat.com/index.php/article/a-version-aversion#comments</comments>
		<pubDate>Thu, 03 Apr 2008 20:59:56 +0000</pubDate>
		<dc:creator>Steve Knight</dc:creator>
				<category><![CDATA[article]]></category>

		<guid isPermaLink="false">http://www.hackinghat.com/index.php/article/a-version-aversion</guid>
		<description><![CDATA[I like war stories. They remind me that I&#8217;m not alone on this journey. This is a war story. It involves a lot of entrails, questionable surgery and plenty of walking wounded. I carry the scars so perhaps you don&#8217;t have to &#8230; &#8230; when I joined the team the system consisted of: A few [...]]]></description>
			<content:encoded><![CDATA[<p>I like <a href="http://smuglispweeny.blogspot.com/2008/03/tiltons-law-solve-first-problem.html">war stories</a>.   They remind me that I&#8217;m not alone on this journey.   </p>
<p>This is a war story.  It involves a lot of entrails, questionable surgery and plenty of walking wounded.   I carry the scars so perhaps you don&#8217;t have to &#8230;</p>
<p>&#8230; when I joined the team the system consisted of:
<ol>
<li>A few thousand lines of C++ code which ran as 10 process on two Solaris hosts;</li>
<li>Some Java code that ran on an NT4 J2EE server;</li>
<li>A bunch of windows client PCs all running the same (but different to the server) Java VM</li>
<li>A collection of &#8216;glue&#8217; scripts written in shell script and Tcl.</li>
</ol>
<p>   It ran in two locales, and the hardware was broadly equivalent in both, from what I recall.   Now compare this to what we had by the time I left:
<ol>
<li>A larger body C++ code with 15 or so processes<br />
on one Solaris host as well as a set of additional x86 UNIX hosts (of mixed hardware pedigree) that were sprinkled with various flavours of Solaris and Linux (RedHat) that would run between 2-4 processes depending on the number of cores;</li>
<li>2 J2EE servers of the same vendor;</li>
<li>A further 2 J2EE servers of a different vendor (don&#8217;t ask!);</li>
<li>A collection of scripts written in shell script &#038; Python (thankfully we stamped out the Tcl);</li>
<li>3 primary locations each running a 2 different versions of our software and a single satellite location (hanging from a primary location).</li>
</ol>
<p>Each server release involved somewhere around 10 hosts running different hardware, OS &#038; JVM.  It&#8217;s similar and different to the problem that software vendors must have when they need to make their product run on multiple platforms.   However the difference for us was that our software was a distributed system and each component needed to seamlessly <strong>interact</strong> with its peers.   Something that not many software vendors make a habit of, other than Microsoft I suppose.</p>
<p>Against this background was a team of 10 developers in 3 timezones developing software for a constantly changing and fairly lucrative business.   Quickly made enhancements could secure profits, instability and failures might secure losses so it was important to try and keep the system running as smoothly as possible.   However, the large code base (>100,000 lines) and confusing deployment array made every release a roller coaster ride.   In my last two years of the job the release cycle, whilst somewhat improved from when I started, had increased from 1-2 months to almost 6.   This had an unforseen consequence that developers would, out of necessity, place new features onto release branches to be able to get features out faster.    That&#8217;s when the madness started.</p>
<p>There were too many release versions, operating system versions and client library versions to contend with.   Sometimes even trivial changes become enormous chess games where the order of the changes that we made would determine whether the system would actually run or not.  Eventually it was bound to grind to a halt because with that many deployment configurations each release had too many testing dependencies.   There were two problems here, firstly since this was now a very widely distributed system it would be difficult for us to have an accurate test deployment that worked.   Further, making distributed systems work is hard anyway and the more configurations you have to manage the  more complex it&#8217;s going to be.   We were trying to help ourselves by retrospectively adding unit-tests but the coverage was still fairly low and so we could never have very much confidence that a built system was actually going to work.   What we really desperately needed were integration tests but we never quite managed it.</p>
<p>That&#8217;s where <a href="http://www.joelonsoftware.com/items/2008/03/17.html">Joel&#8217;s post</a> from last week comes in.   As described by Joel we essentially had a SEQUENCE-MANY situation.   Where to be sure of stability we had to test many releases against many deployment configurations.   It would be fair to say that we failed to do this adequately.   I sometimes wonder if we could have done it a little better.   </p>
<ol>
<li>
<p><strong>Could We Have Had Tighter Control Over The Hardware?</strong> Unlike the problem of enforcing standards in Web browsers we of course had full control over the deployment environment so we could have mandated a common platform for it.   As enticing as this sounds, talking to system admins now and then would tend to suggest that this is simply not possible if the hardware is to be purchased incrementally.  This is because after you buy the first 2 Dell servers with a standard specification, a month later that specification will have changed.  As more time passes the drift between the hardware is larger.   </p>
<p>If, however, you sourced a job lot of the hardware in the same place at the same time, you could buy extra (for spares and future requirements) and attempt to keep this variable constant.   It would have been expensive to do but it is at least possible in this scenario.   I think that this probably would have reduced the number of different cross-compilations that were required and reduced the number of different JVMs that we had to manage.  The biggest problem though is that we would have, to a certain extent, needed to know the future to be able to predict what sorts and what amounts of hardware we would need when we set out.  That kind of makes it a non-starter, coupled with the fact that I&#8217;ve never actually heard of anyone doing this for real.</p>
</li>
<li>
<p><strong>Could We Have Had Tighter Control Over The Software</strong> This is the thing that concerns me the most and is definitely a place we didn&#8217;t do as well as we should have.   We let people go ahead and implement locale specifc solutions that were unworkable globally but those created internal system dependencies that would later need to be &#8216;undone&#8217;.   Anyone who has ever worked on a system after its release will know it&#8217;s much easier to get it right first time.  This is because if you create an intermediate solution that ends up being used then you have to manage the old intermediate-version &#8216;out&#8217;.</p>
<p>Indeed, there was a story here too.   The original system architect moved on a year or so after I joined.   He used to worry about 80% of the code that got committed, when he left no-one really had his insight into the architecture and the rust quickly set in.  Related to the loss of architect, as already mentioned, was the lack of integration tests.  Both would have helped us to identify which code was bogus and have it fixed before it reached a release stage. </p>
</li>
</ol>
<p>The one thing we did succesfully manage to do was to stop developers changing release branches.  But the effect of that was to make us look like chumps when the business had to be denied features until new releases could be rolled out.  Ho hum.</p>
<p>The idealist in me thinks we could have done a few things to make it work better but the pragmatist thinks that we did what we had to do.   Whilst the idealist in my head makes a lot of noise and gets listened to an awful lot the pragmatist is the one who gets the most results.   When you are faced with a daily tightrope walk, like we were, you have to try and be both idealist and pragmatist.   Choosing the idealist&#8217;s course when you think you can get away with it and the pramatist when you can&#8217;t.   </p>
<p>But when all else fails just hope for the best.   The scars will heal.   Eventually.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.hackinghat.com/index.php/article/a-version-aversion/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Being Dave.  And Robert.   And Lucy.</title>
		<link>http://www.hackinghat.com/index.php/article/being-dave-and-robert-and-lucy</link>
		<comments>http://www.hackinghat.com/index.php/article/being-dave-and-robert-and-lucy#comments</comments>
		<pubDate>Fri, 12 Oct 2007 06:56:21 +0000</pubDate>
		<dc:creator>Steve Knight</dc:creator>
				<category><![CDATA[article]]></category>
		<category><![CDATA[rant]]></category>

		<guid isPermaLink="false">http://www.hackinghat.com/index.php/article/being-dave-and-robert-and-lucy</guid>
		<description><![CDATA[Carrying on the theme of whimsy from last week I had an interesting week this week where I did almost no development at all. You see this week I&#8217;ve been only answering questions. Why? Well I&#8217;m trying to be Dave and I think I might have gone too far. Dave &#8211; a go go Let [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Carrying on the theme of whimsy from last week I had an interesting week this week where I did almost no development at all.</strong>   You see this week I&#8217;ve been only answering questions.   Why?   Well I&#8217;m trying to be Dave and I think I might have gone too far.</p>
<h3>Dave &#8211; a go go</h3>
<p>Let me explain.  Dave is a person, yes.   But Dave is more than a person.   Dave is a way of life.   A way of life that could make you popular and respected where you work but at tremendous personal cost.   </p>
<p>I first met the real Dave about 4 years ago.   A couple of years younger than me he was quite the most dynamic and down-to-earth person I had ever met up until that point.   He was also well respected (by technologists and business people), well liked and quite successful.    </p>
<p>If you could try and categorize what being Dave is about into a well-known personality type then I think he&#8217;d be an <a href="http://www.randsinrepose.com/archives/2003/08/05/incrementalists_completionists.html">incrementalist</a>, but beyond that Dave somehow knows everything, is very easy to talk to, and eager to help.  This combination of traits means Dave ends up answering a lot of questions.  </p>
<p>The most interesting thing about this combination of traits is that once you decide on being Dave you will end up being involved in a lot of things.   The more things you&#8217;re involved in the wider the knowledge of your Dave-ness will spread.  It&#8217;s a vicious circle.</p>
<p>American-slang has a great word for Dave he&#8217;s the <a href="http://www.urbandictionary.com/define.php?term=go-to+guy">go-to-guy</a>.     It sums it up very neatly, but it&#8217;s a bit <a href="http://en.wikipedia.org/wiki/Does_exactly_what_it_says_on_the_tin">Ronseal</a>.   I prefer Dave.  It&#8217;s more about a person, which is exactly what being Dave is all about.</p>
<h3>Robert &#8211; do do do</h3>
<p>But the garden of Dave is not all roses.   Eventually you know too much.   Too many people know-that-Dave-knows and that Dave will help them if Dave doesn&#8217;t know.  In short, every one will want a piece of your Dave-ass.</p>
<p>The late Robert Townsend in his excellent <a href="http://www.amazon.com/Up-Organization-Corporation-Stifling-Strangling/dp/0787987751/ref=pd_bbs_sr_2/104-7184209-8262351?ie=UTF8&#038;s=books&#038;qid=1192170500&#038;sr=8-2">book</a> says:</p>
<blockquote><p>The world is divided into two classes of people: the few people who make good on their promises (even if they don&#8217;t promise as much), and the many who don&#8217;t.  Get in column A and stay there.  You&#8217;ll be very valuable wherever you are</p></blockquote>
<p>Being Dave is counter-productive to this noble aim.   As word spreads that there&#8217;s a new Dave in town your personal productivity will nose-dive and you can&#8217;t promise shit.   You&#8217;ve stopped doing your own work and you&#8217;ve become the grease that keeps the company moving, a facilitator rather than a producer.    </p>
<h3>Lucy &#8211; no no no</h3>
<p>This is where you have to sprinkle a dash of Lucy.   <a href="http://www.ft.com/comment/columnists/lucykellaway">Lucy Kellaway</a> is a columnist for the <a href="http://ft.com">FT</a> and is a commentator on managerial and workplace cults.   Her advice is probably the sagest of all.   <a href="http://www.ft.com/cms/s/1/34f0a04a-36d6-11dc-9f6d-0000779fd2ac.html">Sometimes you just have to say no</a>.   A lot of time and effort can be saved by saying &#8216;No&#8217;.   The trick is to say &#8216;No&#8217; without actually ever saying it.  </p>
<p>Indeed in our insane &#8216;Yes&#8217; culture the only way you can be Dave and Robert, and hold your sanity, is to be Lucy too.   Just as long as your remember who you are you&#8217;ll be just fine.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.hackinghat.com/index.php/article/being-dave-and-robert-and-lucy/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Calculating peak-to-trough drawdown</title>
		<link>http://www.hackinghat.com/index.php/python/calculating-peak-to-trough-drawdown</link>
		<comments>http://www.hackinghat.com/index.php/python/calculating-peak-to-trough-drawdown#comments</comments>
		<pubDate>Fri, 28 Sep 2007 07:39:59 +0000</pubDate>
		<dc:creator>Steve Knight</dc:creator>
				<category><![CDATA[article]]></category>
		<category><![CDATA[finance]]></category>
		<category><![CDATA[programming]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://www.hackinghat.com/index.php/python/calculating-peak-to-trough-drawdown</guid>
		<description><![CDATA[Ok, so this is a little bit technical but it&#8217;s an intriguing puzzle that got me thinking quite hard. So here&#8217;s the problem. Sometimes investors want to be able to judge what the absolute worst case scenario would have been if they&#8217;d invested in something. Look at the following random graph of pretend asset prices: [...]]]></description>
			<content:encoded><![CDATA[<p>Ok, so this is a little bit technical but it&#8217;s an intriguing puzzle that got me thinking quite hard.    So here&#8217;s the problem.   Sometimes investors want to be able to judge what the absolute worst case scenario would have been if they&#8217;d invested in something.    Look at the following random graph of pretend asset prices:</p>
<p><img id="image61" src="http://www.hackinghat.com/wp-content/uploads/2007/09/peak-to-trough.png" alt="Peak-To-Trough" /></p>
<p>You&#8217;ll see that there are two points on the graph (marked in red) where if you had invested at the first point and pulled out on the second point you would have the worst-case loss.  This is the point of this analysis and is a way for investors in the asset to see how bad, &#8216;bad&#8217; has really been in the past.   Clearly past prices are not an indicator of future losses.  <img src='http://www.hackinghat.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>The upper one is the &#8216;peak&#8217; and the lower one is the &#8216;trough&#8217;.   Well, finding these two babys by eye is trivial.   To do it reliably (and quickly) on a computer, is not that straight forward.   Part of the problem is coming up with a consistent natural language of what you want your peak and trough to be.   This took me some time.   I believe what I really want is: the largest positive difference of high minus low where the low occurs after the high in time-order.   This was the best I could do.   This led to the first solution (in Python):</p>
<pre>
<code>
def drawdown(prices):
	maxi = 0
	mini = 0
	for i in range(len(prices))[1:]:
	   maxj = 0
	   max = 0
	   for j in range(i+1, len(prices)):
		if prices[i] - prices[j] > max:
		    maxj = j
		    max = prices[i] - prices[j]
	   if max > prices[maxi] - prices[mini]:
	   	maxi = i
		mini = maxj
	return (prices[maxi], navs[mini])
</code>
</pre>
<p>Now this solution is easy to explain.   It&#8217;s what I have come to know as a &#8216;between&#8217; analysis.   I don&#8217;t know if that&#8217;s the proper term but it harks back to the days when I used to be a number-cruncher for some <a href="http://linkinghub.elsevier.com/retrieve/pii/S0379073800002711">statisticians</a>.   The deal is relatively straight-forward: compare the fist item against every item after it in the list and store the largest positive difference.     If this difference is also the largest seen in the data-set so far then make it the largest positive difference of all points.  At the end you just return the two points you found.   This is a natural way to solve the problem because it looks at all possible start points and assesses what the worst outcome would be.   </p>
<p>The problem with this solution is that it has quadratic complexity.   That is for any data-series of size N the best and worst case will result in N * N-1 iterations, in shorthand this is <a href="http://www.nist.gov/dads/HTML/bigOnotation.html">O(N^2)</a>.   For small n this doesn&#8217;t really matter, but for any decently sized data-series this baby will be slow-as-molasses.  The challenge then is to find an O(N) solution to the problem and to save-those-much-needed-cycles for something really <a href="http://setiathome.berkeley.edu/">important</a>:</p>
<pre>
<code>
def drawdown(prices):
  prevmaxi = 0
  prevmini = 0
  maxi = 0

  for i in range(len(prices))[1:]:
    if prices[i] >= prices[maxi]:
      maxi = i
    else:
      # You can only determine the largest drawdown on a downward price!
      if (prices[maxi] - prices[i]) > (prices[prevmaxi] - prices[prevmini]):
	prevmaxi = maxi
	prevmini = i
      return (prices[prevmaxi], prices[prevmini])
</code>
</pre>
<p>This solution is a bit harder to explain.   We move through the prices and the first part of the &#8216;if&#8217; will find the highest part of the peak so far.    However, the second part of the &#8216;if&#8217; is where the magic happens.   If the next value is less than the maximum  then we see if this difference is larger than any previously encountered difference, if it is then this is our new peak-to-trough.</p>
<p>The purist in me likes that fact that the O(N) solution looks like easier code to understand than the O(N^2) solution.    Although the O(N^2) solution is, I think, an easier concept to grapple with, when it&#8217;s translated into code it just doesn&#8217;t grok.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.hackinghat.com/index.php/python/calculating-peak-to-trough-drawdown/feed</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>You think your code don&#8217;t smell?</title>
		<link>http://www.hackinghat.com/index.php/article/you-think-your-code-dont-smell</link>
		<comments>http://www.hackinghat.com/index.php/article/you-think-your-code-dont-smell#comments</comments>
		<pubDate>Fri, 14 Sep 2007 05:32:53 +0000</pubDate>
		<dc:creator>Steve Knight</dc:creator>
				<category><![CDATA[article]]></category>
		<category><![CDATA[project management]]></category>

		<guid isPermaLink="false">http://www.hackinghat.com/index.php/article/you-think-your-code-dont-smell</guid>
		<description><![CDATA[So, code reviews are great. Get the benefit of some ass-hole telling you that your comments should be C-style (/*) and not C++-style (//) and remind you that the member name &#8216;mSuckThis&#8217; is not suitable, ever. No really, code reviews are great. It&#8217;s just that a lot of times they just don&#8217;t work. The first [...]]]></description>
			<content:encoded><![CDATA[<p>So, code reviews are great.   Get the benefit of some ass-hole telling you that your comments should be C-style (/*) and not C++-style (//) and remind you that the member name &#8216;mSuckThis&#8217; is not suitable, ever.   No really, code reviews are great.   It&#8217;s just that a lot of times they just don&#8217;t work.</p>
<p>The first time I encountered code-review was when my boss of the time had just read some book on how to manage programmers and was keen to inflict it on all his employees.   His code-review process was to take all my work print it out and go through it line-by-line.   Master and student style.</p>
<p>This type of code-review, in the way that he implemented it, was meaningless.   It concentrated on an important but largely automatable aspect of code review and that is: adherence to coding guidelines.   </p>
<p>As I see it there are three types of defect that code review is trying to identify:</p>
<ol>
<li>Adherence to coding guidelines (or lack of it) and <a href="http://ant-contrib.sourceforge.net/tasks/tasks/compilewithwalls.html">inter-package dependencies.</a></li>
<li>Identification of localised errors: &#8220;that loop is infite&#8221;, or &#8220;that algorithim should be log(N) and not N^2&#8243;, &#8220;that module is way too big&#8221;</li>
<li>Identification of non-local errors.   Where local means local to the code-review.   For instance the impact of adding a throw on a widely used method and how that affects all the dependent code paths.</li>
</ol>
<p>I question anyone&#8217;s ability to fully understand the dynamic nature of any reasonable sized piece of software by just looking at a small excerpt.    Every time you review that code you have to &#8216;load&#8217; that supporting information into your head to be able to identify whether the code is totally awesome or tragically bogus.   In my experience defects of a local type (type 2) were sadly rarely identified by code review and defects of a non-local type (type 3) almost never.</p>
<p>The improvement of code-quality I&#8217;m passionate about.   But I don&#8217;t see any realistic way to achieve what I want.   To identify non-local errors you really need your code reviewer to sit next to you during the development or be as deeply involved in the code as you are.   It probably would need a similar approach to reliably find local errors too.   However your reviewer is rarely as involved as that.    It seems that some judicious use of <a href="http://en.wikipedia.org/wiki/Pair_programming">pair programming</a> might be the answer but that comes with its own problems.</p>
<p>It seems that to get the best out of code-reviews you have to be very careful about how you implement them.   Sure, let&#8217;s automate what we can automate and pair program on tricky items but the real code-review needs to be extremely skilfully handled to get the best bang-for-your-buck-chuck.   </p>
]]></content:encoded>
			<wfw:commentRss>http://www.hackinghat.com/index.php/article/you-think-your-code-dont-smell/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Time: the unseen global variable</title>
		<link>http://www.hackinghat.com/index.php/article/time-the-unseen-global-variable</link>
		<comments>http://www.hackinghat.com/index.php/article/time-the-unseen-global-variable#comments</comments>
		<pubDate>Fri, 17 Aug 2007 04:23:11 +0000</pubDate>
		<dc:creator>Steve Knight</dc:creator>
				<category><![CDATA[article]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://www.hackinghat.com/index.php/article/time-the-unseen-global-variable</guid>
		<description><![CDATA[Just about everyone knows that global variables need to be used sparingly. The more you use the more likely you are to capture complex state in places that are hard to maintain. Or something. As well as all the globals you can see and measure there exists a shadowy league of &#8216;unseen&#8217; globals in your [...]]]></description>
			<content:encoded><![CDATA[<p>Just about everyone knows that global variables need to be used sparingly.   The more you use the more likely you are to capture complex state in places that are hard to maintain.  Or something. </p>
<p>As well as all the globals you can see and measure there exists a shadowy league of &#8216;unseen&#8217; globals in your programs.   Some, like environment variables, are clearly designed as global variables and are desirable and understandable.   However, some are wistful and ephemeral and dance round your program like wicked elves.   Time is the biggest and most scarey of these elves.</p>
<p>For most programs you write time probably doesn&#8217;t matter, they are to all intents-and-purposes time-less.   But as soon as you start entering the shadowy world of time, and the even more nebulous one of time-zones and daylight savings, a whole set of other state is being used.    In my experience the programs and components that I have written that have been dependent on time have been some of the most complex to develop and maintain.   This is for a variety of reasons but in summary:
<p style="text-align:center"><strong>time is not constant and can be interpreted in more than one way.</strong></p>
<p>This leads to all manner of difficulties:</p>
<ol>
<li>Code that depends on the current system time &#8216;Now()&#8217; and doesn&#8217;t pass it as a parameter is always going to be fragile.   This is mostly because its behaviour can be non-deterministic unless you properly account for the fact that time is not-constant.   This is especially important because your programs are susceptible to hard-to-spot boundary effects if you write expressions that use Now() more than once and depend on it returning the same value for each call.   Which of course it never will.</li>
<li>Time and date should never, ever, ever be separated from one another.   You get all sorts of tricky errors when you split the two.   Especially when you are performing some sort of time zone or daylight savings calculation where the two should change together but do not.</li>
<li>Some programming languages represent the date (no time) as a date with a time of 00:00:00.   Which is intuitive, but consider then what happens when you load a date (with no time) from a database in the past, when there were daylight savings, into a time when when there are no daylight savings.   In the frame of reference of now your localised past time will now be an hour earlier and so will be in the final hour of the previous day.   This problem clearly applies to timezones also but is because you made the mistake of not having a consistent view of time.</li>
<li>Not only can the meaning of calendar time change after-the-fact (due to time-zones) but it can also be interpreted differently by different <a href="http://en.wikipedia.org/wiki/Hindu_calendar">cultures</a>.   </li>
</ol>
<p>There&#8217;s probably a lot of other time related pickles you can get yourself into.   <img id="image56" src="http://www.hackinghat.com/wp-content/uploads/2007/08/harold_lloyd_help.jpg" alt="If Harold Lloyd was a programmer ..."  size="50%" style="display: block; margin-top: 1em; margin-bottom: 1em; margin-left: auto; margin-right: auto; border: 1px solid"/></p>
<p>You&#8217;d probably not be surprised to hear me say that unit-testing is one way of addressing at least some of these problems.    This does two things.   If you are to get good coverage for your unit-tests you are practically forced to make time a parameter wherever it&#8217;s used, instead of calling Now().  As a direct consequence of this your code can now be called &#8216;As Of&#8217; and you will be able to offer the historical view where appropriate.   </p>
<p>Indeed, I would say that where a piece of sotware has a time-context, then it will only be a matter of time before someone says: &#8220;Ok, that&#8217;s what it says today but what if I want to rerun it for that time in the past 3 weeks ago?&#8221;.</p>
<p>The time-zone and daylight savings problems can be nailed by having a consistent view on the treatment of time.   For instance storing all dates/times as <a href="http://en.wikipedia.org/wiki/Coordinated_Universal_Time">UTC</a> is one thing.   But if you ever need to store a local time then it should be clear what frame of reference is being used to store that time.   So you might need to additionally know: the calendar, the timezone, and the daylight savings rules before you can correctly store a time.</p>
<p>Then and only then will time become your faithful and obedient friend.  </p>
]]></content:encoded>
			<wfw:commentRss>http://www.hackinghat.com/index.php/article/time-the-unseen-global-variable/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Did you learn anything?  I forget &#8230;</title>
		<link>http://www.hackinghat.com/index.php/article/did-you-learn-anything-i-forget</link>
		<comments>http://www.hackinghat.com/index.php/article/did-you-learn-anything-i-forget#comments</comments>
		<pubDate>Fri, 10 Aug 2007 05:36:35 +0000</pubDate>
		<dc:creator>Steve Knight</dc:creator>
				<category><![CDATA[article]]></category>
		<category><![CDATA[training]]></category>

		<guid isPermaLink="false">http://www.hackinghat.com/index.php/article/did-you-learn-anything-i-forget</guid>
		<description><![CDATA[Something that&#8217;s been concerning me for some time is the cost and benefit of courses and seminars. Most employers and employees would perceive programmer&#8217;s training as a positive benefit and I think I&#8217;d have to agree but it seems that there is a common view that all training is good because it&#8217;s personal development. To [...]]]></description>
			<content:encoded><![CDATA[<p>Something that&#8217;s been concerning me for some time is the cost and benefit of courses and seminars.   Most employers and employees would perceive programmer&#8217;s training as a positive benefit and I think I&#8217;d have to agree but it seems that there is a common view that all training is good because it&#8217;s personal development.   To deny that training to an employee would make you a bad employer because you are stunting your employee&#8217;s professional growth.   Well I&#8217;m not so sure.   I&#8217;d even go as far as to say:</p>
<p style="text-align: center"><strong>A lot of technical training is of limited value.</strong</p>
<p>There I said it.   It&#8217;s out.  I&#8217;m probably never going to get to go on a course ever again, ever.</p>
<p>The last purely technical course I went on was a compulsory learn Java course in-or-around 1999 (yes I&#8217;ve been avoiding courses since then).  I remember it not for the content, which was forgettable, but for the fact that I&#8217;d snapped my wrist 1 week before and I could only type with one hand.   The course, however, was custom designed for our company and our tutors had been briefed about what we needed to know.   I would say that this sort of training, i.e. directed, has good benefit but again it only teaches the how.   The why is lost.  </p>
<p>Compare this with the &#8216;shrink-wrapped&#8217; course.   Which is offered by a training company on a technology and is a generic product.   In my experience I probably end up using a small-ish fraction of the material learnt on such courses.   This is because to attract the candidates they need to give the course a broad appeal.   However, the chances are that I&#8217;m going on a course for the broad appeal are low, it&#8217;s more likely I&#8217;m doing it for a very narrow reason.   A narrow reason usually defined by the next biggest project of the moment.  Sure it&#8217;s helpful to know all the aspects of a particular technology, but the things I don&#8217;t need to know right now will very soon be forgotten.</p>
<p>This is not the only problem with shrink-wrapped courses.   There is also a tendency for candidates to choose &#8216;advanced&#8217; courses that are sometimes beyond their current ability, secure in the knowledge that &#8220;it can&#8217;t be that hard&#8221; and they will pick it up.   When this happens the tutor has to work very hard to bring everyone up to the same level so that he/she can teach some of the more advanced aspects.   </p>
<p>So this sort of leraning is inefficient in that the information that needs to be conveyed is often greater than is needed, but there&#8217;s another deeper problem with courses.  In my opinion I think that programmer&#8217;s would sometimes be better schooled if they learnt good approach first and implementation details later.   Take security for instance, almost every application these days needs some sort of built in security.   I&#8217;d argue that it would be useful for programmers to go on a &#8216;security for programmers course&#8217; which covered lots of different security aspects relevant to programmers.  More useful than, say, a technical course suited to a particular technology which attempts to teach security, amongst a lot of other things.   As I&#8217;m starting to learn it&#8217;s the principles that matter, not the implementations.   At least this way you&#8217;ll see the entire security picture and then when faced with a situation which could be a security risk you can say &#8216;here&#8217;s a potential risk&#8217;  now I need to find a way to mitigate it.   </p>
<p>In some ways this sort of training is perhaps best delivered inside the organisation by mentors.   Big-brothers (and sisters) who can guide the novice through the general principles leaving the rookie to grapple with the fine details of the implementation.   Sadly, when you get to my age, big-brothers are most likely to be grand parents so I guess I&#8217;ll just have to keep getting my training from <a href="http://www.amazon.com">Amazon</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.hackinghat.com/index.php/article/did-you-learn-anything-i-forget/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Step back: The Sinclair ZX81</title>
		<link>http://www.hackinghat.com/index.php/article/step-back-the-sinclair-zx81</link>
		<comments>http://www.hackinghat.com/index.php/article/step-back-the-sinclair-zx81#comments</comments>
		<pubDate>Fri, 03 Aug 2007 05:03:23 +0000</pubDate>
		<dc:creator>Steve Knight</dc:creator>
				<category><![CDATA[article]]></category>
		<category><![CDATA[step back]]></category>

		<guid isPermaLink="false">http://www.hackinghat.com/index.php/uncategorized/step-back-the-sinclair-zx81</guid>
		<description><![CDATA[Sometime in 1983 my mother noticed that a high street chemist that also sold photographic and electrical goods was also selling ZX81 computers for Â£20. It wasn&#8217;t christmas or a birthday but she thought that it might be useful for me. It wasn&#8217;t even something that I had asked for. She just thought it might [...]]]></description>
			<content:encoded><![CDATA[<p>Sometime in 1983 my mother noticed that a <a href="http://www.boots.com/index.jsp">high street chemist</a> that also sold photographic and electrical goods was also selling ZX81 computers for Â£20.   It wasn&#8217;t christmas or a birthday but she thought that it might be useful for me.   It wasn&#8217;t even something that I had asked for.   She just thought it might be useful.   </p>
<p>When we halved the polystrene casing we revealed the little black marvel, purest black with it&#8217;s name embossed in red.   In case you ever forgot.   I ran my fingers across its highly sensitive keypad and was sure I was witnessing something special.   The form of the ZX81 is well known but for me as prominent in my memory was the little blue book which was the manual.   <img id="image43" src="http://www.hackinghat.com/wp-content/uploads/2007/07/frontcvr.jpg" alt="ZX81 Manual Front Cover" size="30%" style="float: left; padding: 1em" />   I spent a lot of time reading and referring to the ZX81 basic manual.  The art work as much imprinted on my mind as the little black flashing &nbsp;<span style="background-color: black; color: white; font-family: arial, sans">K</span>&nbsp; that was the &#8216;ear&#8217; of the ZX81.    The cover of the manual is futuristic with two tiny spacecraft parked on top of some space port or something.   Completely stark raving crazy but it&#8217;s futuristic look added to the mystique of this little black box.   One of the great parts about Sinclair research was their marketing.   Their products, although remarkable for the time, were very <a href="http://en.wikipedia.org/wiki/Sinclair_Research_Ltd#Success_and_then_decline:_1981_to_1986">poorly built and unreliable</a>.   But somehow they created desire.  </p>
<p>The most memorable part of the book was a clock program <a href="http://web.ukonline.co.uk/sinclair.zx81/chap19.html">from Chapter 19: Time &#038; Motion</a>.   It&#8217;s hard to say quite what was so magical about this program, but I was awestruck when I ran it.   The chapter doesn&#8217;t very clearly state that the code will draw a clock and a second hand but after typing it and pressing &#8216;RUN&#8217; a numbered-dial slowly appears and then a dot sweeps around the outer-edge of the dial.   For your pleasure I found a <a href="http://www.chuntey.com/eightyone/">ZX81 emulator</a> and typed the program in again and have recreated the magic for you right here.</p>
<p><img id="image46" src="http://www.hackinghat.com/wp-content/uploads/2007/07/clock.PNG" alt="Chapter 19: Time &amp; Motion"       style="clear: left; margin-left: auto; margin-right: auto" /></p>
<p>Pretty heady stuff, I&#8217;m sure you&#8217;ll agree.   Over the next two or so years I spent a lot of time buying Sinclair magazines and typing in programs from them.   It was great.   You bought a magazine that you could read and then you could type in the program and also get a game to play.  All for 60p.   The games mostly blew goats and I spent more time checking my typing than playing the game but that didn&#8217;t really matter.   One of Sir Clive&#8217;s great ideas was to attach keywords to the keys themselves.   This meant that there wasn&#8217;t really any need for a full-parser because the ZX81 knew what to expect and would make the keyboard accept the right keystrokes at the right time.   Whilst not terribly flexible this solution also meant that there was a whole lot less typing.</p>
<p>I can&#8217;t claim that I learned a lot about computers or programming in those halcyon days but my cliche 1,000 mile journey had started with a single cliche&#8217;d step.   </p>
<div style="border: 1px solid; background: silver; margin: 20px; padding: 10px">
<p>Oh Sinclair, oh my Sinclair ZX81,<br />
We used to laugh and have such fun,<br />
During our time together I have no regret,<br />
I cherish the day that we met.</p>
<p>Everything about you was so damn fine,<br />
From your RAM pack wobble to your sleek lines,<br />
But now you do what time says you must,<br />
You sit in a corner and you pick up dust.</p>
</div>
<p>Sniffle.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.hackinghat.com/index.php/article/step-back-the-sinclair-zx81/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

