tag:blogger.com,1999:blog-90539452008-04-29T09:42:23.277+01:00Agile Application Development: Romilly Cocking's ReviewRomillyhttp://www.blogger.com/profile/04944907795639823332noreply@blogger.comBlogger49125tag:blogger.com,1999:blog-9053945.post-20153895437142327932008-04-28T09:50:00.012+01:002008-04-28T10:46:18.842+01:00TiddlyWiki to MindMap converterKnowledge is my stock in trade, and I use <a href="http://www.tiddlywiki.com/">TiddlyWiki</a> and <a href="http://www.buzanworld.com/">Mind Mapping</a> a lot.<br /><br />Like all Wikis, TiddlyWiki is a great tool for capturing ideas and facts in text and linking them to other relevant topics. It's not so good at showing you the big picture.<br /><br />Mind Maps (tm) are a great way of presenting the big picture, but programs like <a href="http://freemind.sourceforge.net/wiki/index.php/Main_Page">FreeMind</a> and <a href="http://www.mindjet.com/">MindManager</a> (tm) only show the notes for a single branch at a time.<br /><br />What if you think of each tool as giving a <span style="font-style: italic;">different view on the same data</span>? Then you could get the best of both worlds.<br /><br />There's already a <a href="http://dahukanna.net/wiki/tiddlywiki.htm">hypergraph extension</a> for TiddlyWiki which allows you to see a visual representation of wiki contents but I prefer a more conventional Mind Map that I can edit.<br /><br />I'm currently experimenting with a simple <a href="http://www.python.org/">Python</a> script which converts a TiddlyWiki into a FreeMind Mind Map. The converter works well for small wikis and I'm currently researching how best to structure larger maps.<br /><br />The converter isn't ready for prime time yet, and documentation is minimal, but it's evolving fast. If you're interested please drop me a note ( at romilly dot cocking at gmail dot com) and I'll send you a copy.Romillyhttp://www.blogger.com/profile/04944907795639823332noreply@blogger.comtag:blogger.com,1999:blog-9053945.post-75862436878478963232008-04-25T16:26:00.003+01:002008-04-25T16:36:29.316+01:00History memeMom, <a href="http://www.tbray.org/ongoing/When/200x/2008/04/15/History-Meme">Tim made me do it...</a><br /><br /><pre><span style="font-family:courier new;">romilly@samba:~$ history | awk<br />'{a[$2]++}END{for(i in a){print a[i] " " i}}'<br />| sort -rn | head</span><br /><span style="font-family:courier new;">106 ls</span><br /><span style="font-family:courier new;">96 sudo</span><br /><span style="font-family:courier new;">52 cd</span><br /><span style="font-family:courier new;">22 nano</span><br /><span style="font-family:courier new;">16 man</span><br /><span style="font-family:courier new;">16 find</span><br /><span style="font-family:courier new;">16 exit</span><br /><span style="font-family:courier new;">13 chmod</span><br /><span style="font-family:courier new;">12 cat</span><br /><span style="font-family:courier new;">10 scp</span></pre>and, on the Virtual server that hosts samba,<br /><br /><pre><span style="font-family:courier new;">romilly@pc031:~$ history | awk<br />'{a[$2]++}END{for(i in a){print a[i] " " i}}'<br /> | sort -rn | head<br />111 ls<br />78 cd<br />76 sudo<br />32 exit<br />23 top<br />21 ping<br />18 df<br />13 du<br />11 scp<br />11 man</span></pre>Romillyhttp://www.blogger.com/profile/04944907795639823332noreply@blogger.comtag:blogger.com,1999:blog-9053945.post-2788318049547907292008-04-15T11:52:00.003+01:002008-04-15T12:12:39.466+01:00Layers considered harmful: design to interfacesMark Dalgarno recently published <a href="http://blog.software-acumen.com/2008/04/11/snowflakes-and-architecture-layers-considered-harmful-steve-love-at-accu-2008/">an excellent summary</a> of a session presented by Steve Love at <a href="http://accu.org/index.php/conferences/accu_conference_2008/accu2008_sessions">ACCU.</a><br /><br />The talk offers a critique of the traditional doctrine that architectures should be <span style="font-style: italic;">layered</span>. Instead, Love proposes a style based on <span style="font-style: italic;">designing to interfaces</span>. That's music to my ears: it's exactly the approach we take in our new <span style="font-style: italic;">TDD with jMock2</span> course.<br /><br />Love's presentation is <a href="http://accu.org/index.php/conferences/accu_conference_2008/accu2008_sessions">available as a pdf</a>. The first half consists of visuals alone; the second half combines the same visuals with notes.Romillyhttp://www.blogger.com/profile/04944907795639823332noreply@blogger.comtag:blogger.com,1999:blog-9053945.post-9179514646036193112008-04-06T11:30:00.005+01:002008-04-15T11:51:33.964+01:00Testing Hibernate-based Persistent objects without Spring<a href="http://nat.truemesh.com/">Nat Pryce</a> just pointed me at an excellent article on <span style="font-style: italic;"><a href="http://www.time4tea.net/wiki/display/MAIN/Testing+Persistent+Objects+Without+Spring">Testing Persistent Objects Without Spring</a></span> by James Richardson.<br /><br />It shows both the integration test and the code under test.<br /><br />Lots of good ideas/good practice.<br /></span>Romillyhttp://www.blogger.com/profile/04944907795639823332noreply@blogger.comtag:blogger.com,1999:blog-9053945.post-86315646484782266782008-03-28T14:19:00.006Z2008-03-28T15:10:00.503ZTesting RIAs with WebDriverIf you need to test Rich Internet Applications from Java, take a look at <a href="http://code.google.com/p/webdriver/">Webdriver</a>.<br /><br />Things I like about it:<br /><br /><ul><li>It uses real browsers to run the tests, quirks and all</li><li>It's got a <font style="font-style: italic;">literate testing</font> interface based on <a href="http://code.google.com/p/hamcrest/">Hamcres</a>t and inspired by <a href="https://lift.dev.java.net/">LiFT</a>.</li></ul>Here's a very simple example.It's doing simple tests on a static html site:<br /><div class="highlight"><pre><span class="k">public</span> <span class="k">class</span> <span class="nc">HomePageTest</span> <span class="k">extends</span> <span class="n">HamcrestWebDriverTestCase</span> <span class="o">{</span><br /> <br /> <span class="nd">@Override</span><br /> <span class="k">protected</span> <span class="n">WebDriver</span> <span class="nf">createDriver</span><span class="o">()</span> <span class="o">{</span><br /> <span class="k">return</span> <span class="k">new</span> <span class="nf">HtmlUnitDriver</span><span class="o">();</span><br /> <span class="o">}</span><br /> <br /> <span class="k">public</span> <span class="kt">void</span> <span class="nf">testHomePageHasTitleAndHeading</span><span class="o">()</span><br /> <span class="k">throws</span> <span class="n">Exception</span> <span class="o">{</span><br /> <span class="n">goTo</span><span class="o">(</span><span class="s">"http://test.intranet"</span><span class="o">);</span><br /> <span class="n">assertPresenceOf</span><span class="o">(</span><span class="n">title</span><span class="o">()</span><br /> <span class="o">.</span><span class="na">with</span><span class="o">(</span><span class="n">text</span><span class="o">(</span><span class="n">startsWith</span><span class="o">(</span><span class="s">"Agile"</span><span class="o">))));</span><br /> <span class="n">assertPresenceOf</span><span class="o">(</span><span class="n">title</span><span class="o">()</span><br /> <span class="o">.</span><span class="na">with</span><span class="o">(</span><span class="n">text</span><span class="o">(</span><span class="n">containsString</span><span class="o">(</span><span class="s">"Cocking and Co."</span><span class="o">))));</span><br /> <span class="n">assertPresenceOf</span><span class="o">(</span><span class="n">heading</span><span class="o">(</span><span class="mi">1</span><span class="o">)</span><br /> <span class="o">.</span><span class="na">with</span><span class="o">(</span><span class="n">text</span><span class="o">(</span><span class="n">equalTo</span><span class="o">(</span><span class="s">"Agile Application Development"</span><span class="o">))));</span><br /> <span class="o">}</span><br /><span class="o">}</span><br /></pre></div><br /><br /><br />This won't quite work out of the box, as there is no heading finder, but adding one is easy:<br /><br /><div class="highlight"><pre><font class="k">public</font> <font class="k">class</font> <font class="nc">HeadingFinder</font> <font class="k">extends</font> <font class="n">HtmlTagFinder</font> <font class="o">{</font><br /> <font class="k">private</font> <font class="k">final</font> <font class="kt">int</font> <font class="n">level</font><font class="o">;</font><br /><br /> <font class="k">public</font> <font class="nf">HeadingFinder</font><font class="o">(</font><font class="kt">int</font> <font class="n">level</font><font class="o">)</font> <font class="o">{</font><br /> <font class="k">this</font><font class="o">.</font><font class="na">level</font> <font class="o">=</font> <font class="n">level</font><font class="o">;</font><br /> <font class="o">}</font><br /><br /> <font class="nd">@Override</font><br /> <font class="k">protected</font> <font class="n">String</font> <font class="nf">tagDescription</font><font class="o">()</font> <font class="o">{</font><br /> <font class="k">return</font> <font class="s">"heading level "</font><font class="o">+</font><font class="n">level</font><font class="o">;</font><br /> <font class="o">}</font><br /><br /> <font class="nd">@Override</font><br /> <font class="k">protected</font> <font class="n">String</font> <font class="nf">tagName</font><font class="o">()</font> <font class="o">{</font><br /> <font class="k">return</font> <font class="s">"h"</font><font class="o">+</font><font class="n">level</font><font class="o">;</font><br /> <font class="o">}</font><br /><br /> <font class="k">public</font> <font class="k">static</font> <font class="n">HeadingFinder</font> <font class="nf">heading</font><font class="o">(</font><font class="kt">int</font> <font class="n">level</font><font class="o">)</font> <font class="o">{</font><br /> <font class="k">return</font> <font class="k">new</font> <font class="nf">HeadingFinder</font><font class="o">(</font><font class="n">level</font><font class="o">);</font><br /> <font class="o">}</font><br /><font class="o">}</font><br /></pre></div><br />It's fairly new, but there are now pre-built binaries available.Romillyhttp://www.blogger.com/profile/04944907795639823332noreply@blogger.comtag:blogger.com,1999:blog-9053945.post-25678119786526996462008-03-25T10:00:00.004Z2008-03-26T17:55:02.835ZCategory Theory/Haskell learning group in LondonPeter Marks organised a BOF (Birds of a feather) session on Category Theory at Spa2008. To my surprise about twelve of us turned up. We discovered a shared intuition (bizarre though it seems) that Category Theory will somehow shape the <font style="font-style: italic;">next big thing</font> in application development. Less surprisingly, we also discovered a common enthusiasm for Haskell.<br /><br />We want to build on this. Most of us are based in London, or can reach it easily. We plan to meet regularly (about once a month) to explore these ideas and to help each other to learn.<br /><br />I'll post more about this as soon as we have a date and location for our first meeting.Romillyhttp://www.blogger.com/profile/04944907795639823332noreply@blogger.comtag:blogger.com,1999:blog-9053945.post-74391785693975873342008-03-25T09:56:00.005Z2008-03-26T20:35:15.849ZSpa2008 retrospectveI'm back from Spa2008, and my head is buzzing.<br /><br />I felt this was the best Spa conference in recent years. As chairman I'm biased, but I'm not responsible for the quality. That's down to the programme chairs (Eoin Woods and Ivan Moore) and to Andy Moorley who organised things perfectly.<br /><br />I went to (and really enjoyed):<br /><ul><li>Mirror, Mirror on the wall - why me? <span style="font-style: italic;">Chris Cooper-Bland and </span><span style="font-style: italic;">Portia Tung</span><br /></li><li>Thou Shalt Integrate by the Sweat of Thy Brow... <span style="font-style: italic;">Robert James and Eoin Woods</span></li><li>The Need for Speed <span style="font-style: italic;">Paul Dyson and John Nolan</span><br /></li><li>Awesome Acceptance Testing <span style="font-style: italic;">Dan North and Joe Walnes</span><br /></li><li>Spanish Guitar Recital <span style="font-style: italic;">David Harvey</span></li><li>Is Software Practice Advancing? <span style="font-style: italic;">John Daniels and friends</span></li><li>A few things I learned in 50 years of programming <span style="font-style: italic;">L Peter Deutsch</span><br /></li><li>Big Ball of Money, Big Ball of Mud: Economics and Legacy Code <span style="font-style: italic;">Michael Feathers</span><br /></li><li>Closing the Knowing Doing Gap <span style="font-style: italic;">Allan Kelly and Lise Hvatum</span></li></ul>Now it's time to start thinking about Spa2009!Romillyhttp://www.blogger.com/profile/04944907795639823332noreply@blogger.comtag:blogger.com,1999:blog-9053945.post-23817521771444673202008-02-26T11:36:00.004Z2008-02-28T08:40:30.899ZFewer, better peopleI've just read <a href="http://martinfowler.com/bliki/CheaperTalentHypothesis.html">Martin Fowler's post about the Cheaper Talent Hypothesis</a>. It's an issue that most of us have encountered.<br /><br />If you're in IT, feel underpaid, and think that you're above average (as > 50% of us do), you'll have wondered why you aren't rewarded in keeping with your worth.<br /><br />I suspect the main reason that good developers are undervalued is that most people think that software is easy to write. Since many IT projects fail, the implication is that we can't very good at what we do.<br /><br />The conclusion is false because the premise is false. Writing good software is one of the hardest things that people do. I'd love to find some way to allow non-developers to find that out for themselves.<br /><br />IBM used to run introductory programming courses which included a session called <span style="font-style: italic;">keep the alien alive</span>. The instructor played a dumb alien who obeyed spoken instructions literally; the class had to tell him/her how to drink a glass of water. It was surprisingly hard to do, and the instructor usually got soaked. But it really brought home the fact that programming is hard.<br /><br />How could we update this for the 21st century?Romillyhttp://www.blogger.com/profile/04944907795639823332noreply@blogger.comtag:blogger.com,1999:blog-9053945.post-59970466123145216682007-10-16T12:23:00.000+01:002007-10-16T15:44:21.854+01:00Jython lives!It's good to see that Jython is under active development again.<br /><br />I use cPython a lot. I'd pretty much stopped using Jython because it does not currently support language features that I find essential - decimals, generators and list comprehensions, for example.<br /><br />The project seemed to be dormant, but <a href="http://www.jython.org/Project/roadmap.html#id2">Jython 2.2</a> has just been released, and it looks like <a href="http://www.theserverside.com/news/thread.tss?thread_id=46661#238687">Jython 2.5</a><a href="http://www.theserverside.com/news/thread.tss?thread_id=46661#238687"> is on the way</a>, with all the critical features that I need. Excellent news!Romillyhttp://www.blogger.com/profile/04944907795639823332noreply@blogger.comtag:blogger.com,1999:blog-9053945.post-82084370832873279582007-09-24T18:32:00.002+01:002008-03-26T17:51:32.233ZDownload all pdfs in a web pageA while ago I found an out-of-print book with a web-page that listed a series of downloadable pdfs.<br /><br />Since there were 17 chapters and several other sections, I didn't want to right-click my way through the list so I wrote a quick Python script to do it for me.<br /><br />This must be a Python idiom. I've had to re-invent it so often, I thought I'd blog it so that I -and you - will never have to create it from scratch again.<br /><br />Here it is.<br /><br /><pre><span style="font-family:Lucida,Courier New;"><span style="color: rgb(192, 0, 0);">import</span> <span style="color: rgb(0, 0, 0);">urllib</span><span style="color: rgb(0, 0, 192);">,</span> <span style="color: rgb(0, 0, 0);">re</span><span style="color: rgb(0, 0, 192);">,</span> <span style="color: rgb(0, 0, 0);">sys</span><br /><span style="color: rgb(0, 128, 0);"># download each pdf linked to in a web-page.<br /></span><span style="color: rgb(0, 128, 0);"># assumes that the urls are all relative,<br /></span><span style="color: rgb(0, 128, 0);"># which is usually the case<br /></span><span style="color: rgb(0, 0, 0);">pdflink</span> <span style="color: rgb(0, 0, 192);">=</span> <span style="color: rgb(0, 0, 0);">re</span><span style="color: rgb(0, 0, 192);">.</span><span style="color: rgb(0, 0, 0);">compile</span><span style="color: rgb(0, 0, 192);">(</span><span style="color: rgb(0, 64, 128);">r'<a href="(.*\.pdf)">'</span><span style="color: rgb(0, 0, 192);">)</span><br /><span style="color: rgb(0, 0, 0);">baseURL</span> <span style="color: rgb(0, 0, 192);">=</span> <span style="color: rgb(0, 0, 0);">sys</span><span style="color: rgb(0, 0, 192);">.</span><span style="color: rgb(0, 0, 0);">argv</span><span style="color: rgb(0, 0, 192);">[</span><span style="color: rgb(0, 128, 192);">1</span><span style="color: rgb(0, 0, 192);">]</span><br /><span style="color: rgb(0, 0, 0);">page</span> <span style="color: rgb(0, 0, 192);">=</span> <span style="color: rgb(0, 0, 0);">urllib</span><span style="color: rgb(0, 0, 192);">.</span><span style="color: rgb(0, 0, 0);">urlopen</span><span style="color: rgb(0, 0, 192);">(</span><span style="color: rgb(0, 0, 0);">baseURL</span><span style="color: rgb(0, 0, 192);">+</span><span style="color: rgb(0, 64, 128);">"contents.html"</span><span style="color: rgb(0, 0, 192);">)</span><br /><br /><span style="color: rgb(192, 0, 0);">for</span> <span style="color: rgb(0, 0, 0);">line</span> <span style="color: rgb(192, 0, 0);">in</span> <span style="color: rgb(0, 0, 0);">page</span><span style="color: rgb(0, 0, 192);">.</span><span style="color: rgb(0, 0, 0);">readlines</span><span style="color: rgb(0, 0, 192);">(</span><span style="color: rgb(0, 0, 192);">)</span><span style="color: rgb(0, 0, 192);">:</span><br /> <span style="color: rgb(0, 0, 0);">match</span> <span style="color: rgb(0, 0, 192);">=</span> <span style="color: rgb(0, 0, 0);">pdflink</span><span style="color: rgb(0, 0, 192);">.</span><span style="color: rgb(0, 0, 0);">search</span><span style="color: rgb(0, 0, 192);">(</span><span style="color: rgb(0, 0, 0);">line</span><span style="color: rgb(0, 0, 192);">)</span><br /> <span style="color: rgb(192, 0, 0);">if</span> <span style="color: rgb(0, 0, 0);">match</span><span style="color: rgb(0, 0, 192);">:</span><br /> <span style="color: rgb(0, 0, 0);">filename</span> <span style="color: rgb(0, 0, 192);">=</span> <span style="color: rgb(0, 0, 0);">match</span><span style="color: rgb(0, 0, 192);">.</span><span style="color: rgb(0, 0, 0);">group</span><span style="color: rgb(0, 0, 192);">(</span><span style="color: rgb(0, 128, 192);">1</span><span style="color: rgb(0, 0, 192);">)</span><br /> <span style="color: rgb(192, 0, 0);">print</span> <span style="color: rgb(0, 64, 128);">"downloading %s"</span> <span style="color: rgb(0, 0, 192);">%</span> <span style="color: rgb(0, 0, 0);">filename</span><br /> <span style="color: rgb(0, 0, 0);">urllib</span><span style="color: rgb(0, 0, 192);">.</span><span style="color: rgb(0, 0, 0);">urlretrieve</span><span style="color: rgb(0, 0, 192);">(</span><span style="color: rgb(0, 0, 0);">baseURL</span><span style="color: rgb(0, 0, 192);">+</span><span style="color: rgb(0, 0, 0);">filename</span><span style="color: rgb(0, 0, 192);">,</span> <span style="color: rgb(0, 0, 0);">filename</span><span style="color: rgb(0, 0, 192);">)</span><span style="color: rgb(0, 0, 0);"></span></span></pre>Romillyhttp://www.blogger.com/profile/04944907795639823332noreply@blogger.comtag:blogger.com,1999:blog-9053945.post-76936406060107658532007-09-24T15:00:00.000+01:002007-09-24T15:21:09.639+01:00Google soft-launches social bookmarking tool<span style="text-decoration: underline;">Is </span><a href="http://www.google.com/s2/sharing/resources/static/html/help.html">Google shared stuff</a> the latest hot thing? It's a new social bookmarking tool.<br /><br />It's available now, although you won't yet find it in the list of <a href="http://www.google.co.uk/intl/en/options/index.html">Google services and tools</a>, nor on the Google labs page.<br /><br />As well as sharing with your friends, the new bookmarklet allows you to share your links via several third-party sites, including <a href="http://www.facebook.com/">Facebook</a>, <a href="http://digg.com/">digg</a>, <a href="http://reddit.com/">reddit</a> and <a href="http://del.icio.us/">del.icio.us</a>.<br /><br />In itself, it wouldn't be worldshaking; but<br /><ol><li>It's from Google</li><li>There are rumors of a soon-to-be-released Google api for social networking.<br /></li></ol>Romillyhttp://www.blogger.com/profile/04944907795639823332noreply@blogger.comtag:blogger.com,1999:blog-9053945.post-81762901945636412892007-09-22T07:36:00.000+01:002007-09-22T08:16:44.603+01:00Count Blog subscriptions with this Python scriptIf you blog, you're probably keen to know the size of your readership. Many of your subscribers will use an RSS aggregation service, and these days there are lots of feed aggregators. How do you <span style="font-weight: bold;">count the subscribers</span>?<br /><br />This short <span style="font-weight: bold;">Python script</span> does just that.<br /><br />If you can access the httpd logs of the server that hosts your blog, you'll find that many aggregators send you a subscriber count when they check for new blog entries.<br /><br />A log entry for a typical aggregator request looks like this:<br /><br /><pre>65.214.44.29 - - [21/Sep/2007:04:12:34 +0100]<br /> "GET /atom.xml HTTP/1.1" 200 0 "-"<br /> "Bloglines/3.1 (http://www.bloglines.com; 10 subscribers)"</pre><br /><br />The Python script below filters out lines that contain the string "subscribers", extracts the Ip address and subscriber count, and calculates the total number of subscriptions.<br /><br />The script is very simple, but there are a couple of wrinkles.<br /><br />A singe log file can include multiple requests from a given aggregator. The script puts counts into a dictionary keyed by the aggregator's ip address, so the total count includes the latest value for each aggregator.<br /><br />In theory, you could get a request that included the string 'subscriber' from some other source. (For example, someone might visit a URL for newsletter subscribers.)<br />The script has a fudge to treat such requests as if they came from a dummy aggregator with no subscribers.<br /><br />Here's the script:<br /><br /><pre><font face="Lucida,Courier New"><font color="#008000"># count blog subscribers from httpd log file <br /></font><font color="#C00000">import</font> <font color="#000000">re</font><br /><br /><font color="#000000">ip</font> <font color="#0000C0">=</font><font color="#004080">r"^(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})"</font><br /><font color="#000000">anything</font> <font color="#0000C0">=</font> <font color="#004080">".*"</font><br /><font color="#000000">count</font> <font color="#0000C0">=</font> <font color="#004080">r"\s(\d+)\s"</font><br /><font color="#000000">subscriber</font> <font color="#0000C0">=</font> <font color="#004080">"subscriber"</font><br /><font color="#000000">subscription_entry</font> <font color="#0000C0">=</font> <font color="#000000">re</font><font color="#0000C0">.</font><font color="#000000">compile</font><font color="#0000C0">(</font><font color="#000000">ip</font><font color="#0000C0">+</font><font color="#000000">anything</font><font color="#0000C0">+</font><font color="#000000">count</font><font color="#0000C0">+</font><font color="#000000">subscriber</font><font color="#0000C0">)</font><br /><br /><font color="#C00000">def</font> <font color="#000000">ipc</font><font color="#0000C0">(</font><font color="#000000">line</font><font color="#0000C0">)</font><font color="#0000C0">:</font><br /> <font color="#000000">match</font> <font color="#0000C0">=</font> <font color="#000000">subscription_entry</font><font color="#0000C0">.</font><font color="#000000">search</font><font color="#0000C0">(</font><font color="#000000">line</font><font color="#0000C0">)</font><br /> <font color="#C00000">if</font> <font color="#000000">match</font><font color="#0000C0">:</font><br /> <font color="#C00000">return</font> <font color="#000000">match</font><font color="#0000C0">.</font><font color="#000000">group</font><font color="#0000C0">(</font><font color="#0080C0">1</font><font color="#0000C0">,</font><font color="#0080C0">2</font><font color="#0000C0">)</font><br /> <font color="#C00000">else</font><font color="#0000C0">:</font><br /> <font color="#008000"># just in case the line contains 'subscriber'<br /></font> <font color="#008000"># but does not match the regular expression<br /></font> <font color="#000000">null_entry</font> <font color="#0000C0">=</font> <font color="#0000C0">(</font><font color="#004080">"0.0.0.0"</font><font color="#0000C0">,</font> <font color="#0080C0">0</font><font color="#0000C0">)</font><br /> <font color="#C00000">return</font> <font color="#000000">null_entry</font><br /><br /><font color="#C00000">def</font> <font color="#000000">total_counts</font><font color="#0000C0">(</font><font color="#000000">ips_and_counts</font><font color="#0000C0">)</font><font color="#0000C0">:</font><br /> <font color="#008000"># there may be multiple log entries for a given aggregator<br /></font> <font color="#008000"># so we use a dictionary and just keep the last value <br /></font> <font color="#008000"># which is the latest one for each aggregator<br /></font> <font color="#000000">dict</font> <font color="#0000C0">=</font> <font color="#0000C0">{</font><font color="#0000C0">}</font><br /> <font color="#C00000">for</font> <font color="#0000C0">(</font><font color="#000000">ip</font><font color="#0000C0">,</font> <font color="#000000">count</font><font color="#0000C0">)</font> <font color="#C00000">in</font> <font color="#000000">ips_and_counts</font><font color="#0000C0">:</font><br /> <font color="#000000">dict</font><font color="#0000C0">[</font><font color="#000000">ip</font><font color="#0000C0">]</font> <font color="#0000C0">=</font> <font color="#000000">int</font><font color="#0000C0">(</font><font color="#000000">count</font><font color="#0000C0">)</font><br /> <font color="#C00000">return</font> <font color="#000000">sum</font><font color="#0000C0">(</font><font color="#000000">dict</font><font color="#0000C0">.</font><font color="#000000">values</font><font color="#0000C0">(</font><font color="#0000C0">)</font><font color="#0000C0">)</font><br /><br /><font color="#C00000">def</font> <font color="#000000">countSubscribersInLogFile</font><font color="#0000C0">(</font><font color="#000000">filename</font><font color="#0000C0">)</font><font color="#0000C0">:</font><br /> <font color="#000000">file</font> <font color="#0000C0">=</font> <font color="#000000">open</font><font color="#0000C0">(</font><font color="#000000">filename</font><font color="#0000C0">)</font><br /> <font color="#000000">counts</font> <font color="#0000C0">=</font> <font color="#0000C0">[</font><font color="#000000">ipc</font><font color="#0000C0">(</font><font color="#000000">line</font><font color="#0000C0">)</font> <font color="#C00000">for</font> <font color="#000000">line</font> <font color="#C00000">in</font> <font color="#000000">file</font> <font color="#C00000">if</font> <font color="#000000">subscriber</font> <font color="#C00000">in</font> <font color="#000000">line</font><font color="#0000C0">]</font><br /> <font color="#000000">total</font> <font color="#0000C0">=</font> <font color="#000000">total_counts</font><font color="#0000C0">(</font><font color="#000000">counts</font><font color="#0000C0">)</font><br /> <font color="#000000">file</font><font color="#0000C0">.</font><font color="#000000">close</font><font color="#0000C0">(</font><font color="#0000C0">)</font><br /> <font color="#C00000">return</font> <font color="#000000">total</font><br /><br /><font color="#C00000">if</font> <font color="#000000">__name__</font> <font color="#0000C0">==</font> <font color="#004080">"__main__"</font><font color="#0000C0">:</font><br /> <font color="#C00000">import</font> <font color="#000000">os</font><font color="#0000C0">,</font> <font color="#000000">sys</font><br /> <font color="#000000">filename</font> <font color="#0000C0">=</font> <font color="#000000">sys</font><font color="#0000C0">.</font><font color="#000000">argv</font><font color="#0000C0">[</font><font color="#0080C0">1</font><font color="#0000C0">]</font><br /> <font color="#000000">details</font> <font color="#0000C0">=</font> <font color="#0000C0">(</font><font color="#000000">countSubscribersInLogFile</font><font color="#0000C0">(</font><font color="#000000">filename</font><font color="#0000C0">)</font><font color="#0000C0">,</font> <font color="#000000">filename</font><font color="#0000C0">)</font><br /> <font color="#C00000">print</font> <font color="#004080">"%d subscriptions in %s"</font> <font color="#0000C0">%</font> <font color="#000000">details</font><font color="#000000"></font></font></pre>Romillyhttp://www.blogger.com/profile/04944907795639823332noreply@blogger.comtag:blogger.com,1999:blog-9053945.post-42663466365150131972007-09-10T11:21:00.000+01:002007-09-10T11:28:09.477+01:00BuildersNat Price has posted an excellent overview of <a href="http://nat.truemesh.com/archives/000714.html">Test Data Builders</a>. (Don't be put off by the image!)<br /><br />Sadly, he doesn't (yet) say much about the problem of <a href="http://www.cocking.co.uk/blog/2007/07/unit-testing-builders.html">unit testing builders</a>, though he does point out that Builder classes may well find their way into production code.<span style="font-style: italic;"> Nat, that's a hint...</span>Romillyhttp://www.blogger.com/profile/04944907795639823332noreply@blogger.comtag:blogger.com,1999:blog-9053945.post-57217032353129447192007-09-10T09:39:00.001+01:002007-09-10T10:23:20.396+01:00XPDay7 is shaping up; now on to SPA2008!The programme committee for <a href="http://www.xpday.org/">XPDay7</a> met last week to review session proposals. We'd received an outstanding collection of submissions, so there was no problem in filling the program with quality sessions. The hard part, as usual, was to decide which ones we would <span style="font-style: italic;">not </span>include.<br /><br />The meeting went very smoothly. <a href="http://www.mcs.vuw.ac.nz/%7Eangela/">Angela Martin</a> and <a href="http://ivan.truemesh.com/">Ivan Moore</a> are joint program chairs this year. They put a lot of hard work into preparation, and it really paid off.<br /><br />If you've submitted a proposal for XPDay7, expect to hear from Angela or Ivan soon.<br /><br />I'm now bending my mind to <a href="http://www.spaconference.org/spa2008/index.php">SPA2008</a>. Ivan Moore and <a href="http://www.eoinwoods.info/">Eoin Woods</a> are joint program chairs. As conference chair, I'm as keen as they are to see another outstanding programme.<br /><br />If you submitted a proposal for XPDay7, consider <a href="http://www.spaconference.org/spa2008/index.php?page=lead-a-session">submitting a session for SPA</a>. We like a mix of new and proven sessions, so acceptance for XPay7 shouldn't stop you from submitting a similar proposal for SPA. Not should rejection - there were excellent submissions for which we just had no room, and they might well fit in the (longer) SPA programme.<br /><br />The <span style="font-weight: bold;">SPA deadline</span> is Monday 17th September, but you don't need to submit finished material - just a proposal.Romillyhttp://www.blogger.com/profile/04944907795639823332noreply@blogger.comtag:blogger.com,1999:blog-9053945.post-86606572016388486992007-09-09T15:16:00.000+01:002007-09-09T15:55:17.179+01:00Backing up vital data with Amazon S3I finally got around to trying <a href="http://www.amazon.com/S3-AWS-home-page-Money">Amazon S3</a> for data backup.<br /><br />Just in case you've missed out on S3, it's a commercial network-based data storage service offered by Amazon. They claim to use the same technology for S3 that lies behind the Amazon stores.<br /><br />S3 comes with no service level guarantees and there have been some reports of occasional unavailability and/or slow transfer. I'm not too worried; the things that are critical to me are data security and cost.<br /><br />I'm using the J<a href="http://jets3t.s3.amazonaws.com/index.html">etS3t</a> java(tm) tool kit to manage the interaction with the S3 service. The <span style="font-style: italic;">cockpit</span> application gives a GUI view of what's in your S3 buckets; the <span style="font-style: italic;">synchronize </span>application gives a simple command line interface that allows you to keep data on S3 in step with data on your machine(s), and retrieve that data when necessary.<br /><br />You need to be a little careful, as synchronization can delete data as well as add or update it. To mitigate this, there is a <span style="font-family: courier new;">--noaction</span> option which allows you to see what <span style="font-style: italic;">would </span>happen to your data without actually changing anything.<br /><br /><span style="font-weight: bold;">Minor snags</span><br /><br />I've hit a couple of minor snags so far; neither are caused by the S3 service itself, but you need to be aware of them.<br /><br />The first arose when I tried to back up a large amount of data. I'm keen to keep a copy of my cvs repository off-site; it's well backed-up, but all the recent backups are in my home office. If we had a fire or a burglary I'd be in real trouble.<br /><br />I realised soon after the upload started that it would take a while. The repository is about 2.7Gb and although I have fast broadband, my <span style="font-style: italic;">upstream </span>speed is only 256 kb/s. The upload took <span style="font-style: italic;">25 hours</span>!<br /><br /><span style="font-weight: bold;">Smart synchronization</span><br /><br />Synchronize is smart enough not to upload files if they are unchanged. I figured that the next upload would take a few minutes at most. The second snag arose when I tried to check that.<br /><br />Part way through the synchronize application bombed with an <span style="font-family: courier new;">out of memory</span> error. I've now modified the script to give it 512M of heap space, and it runs just fine. And now a burglary would be inconvenient but not disastrous.Romillyhttp://www.blogger.com/profile/04944907795639823332noreply@blogger.comtag:blogger.com,1999:blog-9053945.post-68844351033467483192007-09-07T13:20:00.000+01:002007-09-09T15:14:52.832+01:00Measuring cultural differences<span id="_user_rdqnewsletter@mindtoolsservices.com" style="color: rgb(51, 0, 51);">James Manktelow has just published an interesting article about <a href="http://www.mindtools.com/pages/article/newLDR_66.htm">measuring and understanding cul</a></span><a href="http://www.mindtools.com/pages/article/newLDR_66.htm">tural differences</a>. It's based on <a href="http://www.geert-hofstede.com/">Geert Hofstede</a>'s work on <span style="font-style: italic;">cultural dimensions</span>.<br /><br />Hofstede has identified five key dimensions which can be used to classify and understand local cultures. His analysis is based on a data base collected by IBM in the 60's and 70's surveying the values of employees in more than 70 countries.<br /><br /><span style="font-weight: bold;">Hofstede's C</span><span style="font-weight: bold;">ultural Dimensions</span><br /><br />Hofstede analyses culture in these dimensions:<br /><ul><li>Power Distance</li><li>Individualism</li><li>Masculinity</li><li>Uncertainty Avoidance and</li><li>Long-Term Orientation</li></ul>It looks as if these measures would form a useful framework for analysing and understanding the culture of the organisations we work for.Romillyhttp://www.blogger.com/profile/04944907795639823332noreply@blogger.comtag:blogger.com,1999:blog-9053945.post-72697539128157185682007-09-07T10:57:00.000+01:002007-09-07T11:09:19.646+01:00Introducing Agile - Gerry Weinberg's approach<a href="http://www.davidpeterson.co.uk/">David Petersen</a> just sent me a link to a great interview:<span id="MainPortalLoader__ctl38_lblTitle" class="ContentTitle"> <a href="http://www.pmboulevard.com/Default.aspx?page=View%20Content&cid=2369&parent=5970">"5Qs on Agile</a> with <a href="http://secretsofconsulting.blogspot.com/2007/09/introducing-new-technology-agile.html">Gerald M. Weinberg"</a>.<br /><br />The interview includes a neat way of getting people to want to adopt Agile techniques, rather than trying to force them.<br /><br />Weinbeg is one of my favourite authors, but I wasn't subscribed to his blogs. I am now.<br /><br />His writing blog has another interesting <a href="http://weinbergonwriting.blogspot.com/2007/08/avoiding-whole-agenteditor-shenanigans.html">post about self-publishing</a>.<br /></span>Romillyhttp://www.blogger.com/profile/04944907795639823332noreply@blogger.comtag:blogger.com,1999:blog-9053945.post-13825016909690702682007-08-31T14:21:00.000+01:002007-08-31T14:31:42.299+01:00Virtual Appliances: only run them if you trust them!I forgot to add an important warning to yesterday's post about <a href="http://www.cocking.co.uk/blog/2007/08/virtual-appliance-simple-way-to-install.html">Virtual Applicances</a>!<br /><br />When you start up a virtual appliance it will probably try to get an IP address on your private network via DHCP. If the Virtual Appliance contains malicious code, it could then do all kinds of nasty things.<br /><br />The bottom line: as with <span style="font-style: italic;">any</span> software that you install behind your firewall, <span style="font-weight: bold;">don't run a virtual appliance unless you trust the source you got it from.</span>Romillyhttp://www.blogger.com/profile/04944907795639823332noreply@blogger.comtag:blogger.com,1999:blog-9053945.post-86935169665202064452007-08-30T16:17:00.000+01:002007-08-30T22:18:04.591+01:00The Virtual Appliance: a simple way to install complex softwareThis morning I saw an email asking for suggestions for a cheap or low-cost web <a href="http://www.refreshedmedia.com/glossary/content-management-system.html">content management system</a>. There was one other important requirement - the software would be installed, managed and used by "semi-technical people".<br /><br />A couple of people suggested <a href="http://drupal.org/"><span style="font-weight: bold;">drupal</span>.</a> I've heard good things about <span style="font-weight: bold;">drupal</span>, so I took a quick look at the website. Here's a sample of what hits you on the installation page:<br /><code><br />Drupal requires a web server, PHP4 (4.3.3 or greater) or PHP5 (<a href="http://www.php.net/" title="http://www.php.net/" rel="nofollow">http://www.php.net/</a>) and either MySQL (<a href="http://www.mysql.com/" title="http://www.mysql.com/" rel="nofollow">http://www.mysql.com/</a>) or PostgreSQL (<a href="http://www.postgresql.org/" title="http://www.postgresql.org/" rel="nofollow">http://www.postgresql.org/</a>).<br /></code><br />That's hardly ideal for <span>semi-technical people</span>.<br /><br />Once <span style="font-weight: bold;">drupal</span> is installed, however, it seems easy to configure and use. What my friend's users need is a <span style="font-style: italic;">simple way to install the application in the first place</span>.<br /><br />The best approach I can think of is to install a <a href="http://www.vmware.com/appliances/"><span style="font-style: italic;">Virtual Applianc</span>e</a>.<br /><br />A Virtual Appliance is a virtual machine image which you can run using VMware, Xen or Parallels. It contains a complete application, pre-configured and ready to run.<br /><br />Using a Virtual Appliance with the free VMware player takes just 5 steps:<br /><ol><li><a href="http://www.vmware.com/download/player/">Download VMware Player</a>.</li><li>Install it. (on Windows, that's a one-click operation).<br /></li><li>Download and unzip a suitable Virtual Appliance.</li><li>Start the Player and<br /></li><li>Start the Appliance.</li></ol>Now your chosen application is up and ready for use.<br /><br />I tried out the <a href="http://www.jumpbox.com/jumpbox-for-the-drupal-content-management-system">drupal appliance from JumpBox</a>. It took me about 5 minutes to install and start using it. (I had a bit of a head-start because I already had VMware player installed).<br /><br />If you know someone who wants user-friendly software but who lacks the technical expertise to install it, look and see if you can find a virtual appliance to suit.<br /><br />More and more software (open source and commercial) is being offered this way, and it's also a great way to distribute software that<span style="font-style: italic;"> you've</span> written or configured.Romillyhttp://www.blogger.com/profile/04944907795639823332noreply@blogger.comtag:blogger.com,1999:blog-9053945.post-86479236575033417192007-08-27T17:52:00.000+01:002007-09-10T07:04:46.184+01:00Automated end-to-end testing made easier with VMWare ServerAutomated testing is one of the most important practices in Agile Development. I like to have a hierarchy of automated tests that cover the whole system as deployed and all of its component parts, right down to unit tests that tell me whether each class is fulfilling its contract.<br /><br /><br /><span style="font-weight: bold;">Starting with end-to-end tests</span><br /><br />There's a lot published about unit testing and acceptance tests, but much less about end-to-end testing. That's disappointing, given that <a href="http://www.mockobjects.com/2007/07/start-with-working-system.html">end-to-end tests are arguably the first thing you should work on when developing a new application</a>.<br /><br /><span style="font-weight: bold;">The need for a clean deployment environment</span><br /><br />End-to-end testing gives you a chance to check out your deployment process and verify that the deployed application works in the target environment. Sometimes, though, a badly planned testing process can lull you into a false sense of security; most of us have encountered applications that work well in their test environment but fail when deployed to a clean machine.<br /><br />It usually takes too much time and effort to create a fresh testing environment from scratch every time you want to do an end-to-end test. There is a simple fast alternative using VMWare Server.<br /><br /><span style="font-weight: bold;">VMware server to the rescue</span><br /><br /><a href="http://www.vmware.com/products/server/">VMware server</a> is a free (as in beer) version of VMware's virtualisation software. I run it on an Ubuntu server, and use it to create a clean environment for applications that I'm developing. It has a snapshot capability that allows me to capture a clean "before deployment" image, and restore that in a few seconds prior to running a test. Best of all, there's an external scripting interface which allows you to automate the process.<br /><br />You can download VMware Server for free (after registration). I also use their commercial <a href="http://www.vmware.com/products/ws/">VMware workstation</a> product; the two play well together, as you'd expect, but you can do everything you need for end-to-end testing with the free product.Romillyhttp://www.blogger.com/profile/04944907795639823332noreply@blogger.comtag:blogger.com,1999:blog-9053945.post-36773125830903374652007-07-19T07:15:00.001+01:002007-07-19T07:46:02.006+01:00JavaScript - are you serious?One of the sessions at Monday's <a href="http://bcs-spa.org/minispa2007.html">miniSPA</a> conference was <a href="http://bcs-spa.org/minispa2007sessions.html#javascript">Serious JavaScript</a> led by <a href="http://www.google.com/search?q=Peter+Marks&sourceid=navclient-ff&ie=UTF-8&rlz=1B2GGGL_enGB203GB203">Peter Marks</a> and <a href="http://www.spaconference.org/cgi-bin/wiki.pl?browse=DavidHarvey">David Harvey</a>.<br /><br />I missed the original session at SPA2007, and I was very glad to get a chance to see it second time round. I found it fascinating and alarming.<br /><br />It was fascinating because the presenters brought out some of JavaScript's real strengths as a development language. One example: JavaScript supports functions as first class objects, which allows smart developers to do all kinds of clever and useful things.<br /><br />The session was alarming because it showed how seriously JavaScript is marred by arbitrary and counter-intuitive semantics.<br /><br />Time after time the session leaders asked the audience to predict the results of simple JavaScript expressions. Time after time we predicted incorrectly (and sometimes the presenters did too).<br /><br />The language seems to have been designed around the <span style="font-style: italic;">principle of <span style="font-weight: bold;">most</span> surprise</span>.<br /><br />People are suggesting that JavaScript is going to be the next big language, and it looks like a fair few people at Google are in that camp, including <a href="http://steve-yegge.blogspot.com/">Steve Yegge</a>. If so, heaven help us all. Power and unpredictability make a very dangerous combination.Romillyhttp://www.blogger.com/profile/04944907795639823332noreply@blogger.comtag:blogger.com,1999:blog-9053945.post-16570404405090301112007-07-18T20:40:00.000+01:002007-08-14T07:51:31.654+01:00miniSPA and jMock2I spent yesterday at <a href="http://bcs-spa.org/minispa2007.html">miniSPA</a>. It's a selection of popular presentations from last year's SPA conference; we run it to attract new participants and new session leaders.<br /><br />This year's miniSPA was brilliantly organised by <a href="http://ivan.truemesh.com/">Ivan Moore</a> and <a href="http://www.spaconference.org/cgi-bin/wiki.pl?AndyMoorley">Andy Moorley</a>. Ivan is programme chair for SPA2008. Andy runs the conference, organises miniSPA, and generally keeps the whole world turning as it should.<br /><br />I was at miniSPA in two capacities; as next year's conference chair, and as a presenter from last year. <a href="http://nat.truemesh.com/">Nat Pryce</a> and I ran a tutorial on<a href="http://bcs-spa.org/minispa2007sessions.html#jmock"> Test Driven Development with jMock2,</a> which went really well. We've offered to run it again in November at <a href="http://www.xpday.org/">XPDay7</a>.<br /><br />I'm about to analyse the feedback and first impressions are very positive. SPA is a remarkable conference. If you haven't been, <a href="http://www.spaconference.org/spa2008/index.php">take a look at the website</a> and think about going next year. If you want to go next year, <a href="http://www.spaconference.org/spa2008/index.php?page=lead-a-session">think about submitting a session proposal</a>.Romillyhttp://www.blogger.com/profile/04944907795639823332noreply@blogger.comtag:blogger.com,1999:blog-9053945.post-89986585318251910212007-07-11T07:05:00.000+01:002007-07-11T07:28:54.987+01:00Unit testing buildersShould one unit-test test Builder classes? If so, how?<br /><br />A well-designed application is a composed network of simple components. Many developers use one or more <a href="http://c2.com/cgi/wiki?BuilderPattern">builder classes</a> to construct applications.<br /><br />Builders can get quite complex.<br /><br />In many cases we want a single component to be shared by several client components. It's easy to get this wrong. If we do so, we may build a network on which all dependencies appear to be satisfied, but we have actually created multiple copies of components when a single instance should be shared.<br /><br />Builders often use lazy initialization, in which case they have state. This introduces additional opportunities for error.<br /><br />Since it's easy to get builders wrong, we need to test them. End-to-end tests will usually tell us if we've build out application without all the necessary parts, but they don't pinpoint the problem, and they may not tell us if we've mistakenly introduced multiple objects instead of sharing a single one.<br /><br />This suggests that we need to write unit tests for builders, but that's often difficult. The classes that are built will hide their implementation (as they should) so unit tests cannot easily verify that the right internal components are there inside them.<br /><br />I'm coming to the conclusion that builder tests need to break encapsulation. That's normally a major code smell, but the nature of builders seems to leave no alternative.Romillyhttp://www.blogger.com/profile/04944907795639823332noreply@blogger.comtag:blogger.com,1999:blog-9053945.post-58081985881207213792006-12-02T09:22:00.000Z2007-08-31T15:14:55.235+01:00Is measurement evil?<span class="post-footers">A while back Dave Snowden of the <a href="http://www.cognitive-edge.com/">Cognitive Edge</a> (formerly Cynefin) <a href="http://www.cognitive-edge.com/2006/08/the_consequences_of_measuremen.php">posted a well-aimed comment</a> about the UK Government's folly in trying to fix their outcome-based measures.<br /><br /></span><div style="text-align: left;"><span class="post-footers">I first met Dave Snowden when he presented a keynote at <a href="http://xpday5.xpday.org/">XPDay5</a>. I was bowled over by his talk, as were many of the audience.<br /><br />Not so <a href="http://www.gilb.com/">Tom Gilb</a>, who was sitting next to me in the talk. Perhaps I shouldn't have been surprised: most of Tom's professional life has been focused on helping organisations to improve thorough quantification and measurement.<br /><br />Both Dave and Tom are brilliant thinkers and I have been pondering ever since how two such clever people could hold such diametrically opposed views.</span><br /></div><span class="post-footers"><br />I had a delightful talk about this with <a href="http://www.clarkeching.com/">Clarke Ching</a> at <a href="http://xpday6.xpday.org/">XPDay6</a>. which helped to clarify my ideas.</span> I've tried to summarize my understanding below.<span class="post-footers"><br /></span><ol><li><span class="post-footers">If I am trying to manage others, it's useless for me <span style="font-style: italic;">merely to set them measures</span>. My team will game<span style="font-style: italic;"> </span>them. I'll get what I measure. It will not be what I want. (I think that's at the core of Dave Snowden's position. It's a sufficiently common view that <a href="http://amarinda.com/">Duncan Pierce </a>and Jason Gorman ran a <a href="http://xpday5.xpday.org/sessions.php#DoYouGetWhatYouMeasure">session</a> about it and XPDay5.)<br /></span></li><li><span class="post-footers">If I am a customer trying to define my requirements, it is sensible to <span style="font-style: italic;">quantify the qualities that I require</span> of my supplier's product or service. (I think that's at the core of Tom Gilb's position).<br /></span></li></ol><span class="post-footers">In order for 2. to work, I must be able to:<br /></span><ul><li><span class="post-footers">quantify the </span><span class="post-footers">qualities that I require</span></li><li><span class="post-footers">agree scales of measure for those qualities</span></li><li><span class="post-footers">agree realistic and achievable targets based on those scales of measure</span></li><li><span class="post-footers">monitor progress towards those targets (weekly if possible)</span></li><li><span class="post-footers">and negotiate changes to both the measures and the targets as appropriate.</span></li></ul><span class="post-footers">This process relies on certain norms of behaviour by both parties. If either party seeks to cheat the other the process will break down. I think that this leads to the final precondition for Gilb's approach to work:<span style="font-style: italic;"><br /></span></span><ul><li><span class="post-footers"><span>Either party must be able to terminate the relationship at any time without direct financial penalty.</span></span></li></ul><span class="post-footers">Dave Snowden can produce plenty of examples where these conditions were not met and outcome-based measures were disastrous.<br /><br />Tom Gilb can produce plenty of examples where these conditions were met and the results were excellent.<br /><br />Conclusions:<br /></span><ul><li><span class="post-footers">both Dave Snowden and Tom Gilb have something valuable to tell us!</span></li><li><span class="post-footers">when we use measures to manage a supplier relationship, we must make sure that </span><span class="post-footers"><span style="font-style: italic;">either party must be able to terminate the relationship at any time without direct financial penalty.</span></span></li></ul><span class="post-footers"><br /><br /><br /><br /><br /><br /></span>Romillyhttp://www.blogger.com/profile/04944907795639823332noreply@blogger.comtag:blogger.com,1999:blog-9053945.post-65382493909475793702006-11-28T16:17:00.000Z2006-11-28T16:49:20.140ZXPDay6 - better than ever...<a href="http://www.xpday.org/">XPDay6</a> is nearly over, and it's been great.<br /><br />One of my favorite sessions was <a href="http://www.clarkeching.com/">Clarke Ching's</a> <a href="http://beta.blogger.com/post-create.g?blogID=9053945#Embracing_Change:_An_Introduction_to">Embracing Change: An Introduction to Agile Software Development</a>. Clarke has given similar presentations at XPDay for several years. They've all been good and they keep getting better.<br /><br />Another was a goldfish bowl session Facilitated by <a href="http://nat.truemesh.com/">Nat Pryce</a> and Jonathan Clarke asking <a href="http://beta.blogger.com/post-create.g?blogID=9053945#Why_Is_Simple_So_Difficult_Facilitated">Why Is Simple So Difficult?</a><br /><br />It's hard to define simplicity; it's much easier to define or detect complexity (and then avoid it).<br /><br />Lots of good ideas in the session; I liked <a href="http://joe.truemesh.com/blog/">Joe Walnes</a>' comment that you shouldn't <span style="font-style: italic;">do</span> the simplest thing - you should <span style="font-style: italic;">have </span>the simplest thing (but it may be very difficult creating that simple thing).<br /><br />I introduced Roy Sykes' 3am rule. This defines what I call simple code. It's the sort of code you'd hope to find if you have been called out of bed at 3am to fix a critical defect in production code.<br /><br />My favorites session today was on <a href="https://lift.dev.java.net/">LiFT</a> - a framework for literate testing. It can be used as an alternative to <a href="http://fit.c2.com/">FIT</a>, but it can also be used to implement readable FIT fixtures. I'm hoping to give it a spin on my current project.<br /><br />I really enjoyed the pub session afterwards. (Thanks, <a href="http://www.google.com/">Google</a>). Quote of the day - to Angela Martin, as she was taking photos of us all:<br /><br />"I see you're taking a picture of me while I'm sober. I hope you have a fast film."<br /><br />Ah well - off to the Old Bank Of England in Fleet Street for the post-conference <a href="http://www.xpdeveloper.com/xpdwiki/Wiki.jsp?page=ExtremeTuesdayClub">Extreme Tuesday</a> with more free drinks - thanks, <a href="http://www.kizoom.com/">Kizoom</a>!Romillyhttp://www.blogger.com/profile/04944907795639823332noreply@blogger.com