<?xml version='1.0' encoding='UTF-8'?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/'><id>tag:blogger.com,1999:blog-8918867</id><updated>2008-05-31T21:39:03.180+10:00</updated><title type='text'>Experiments in Software Design</title><link rel='alternate' type='text/html' href='http://www.trontos.com/dsouth/blog/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/8918867/posts/default?start-index=26&amp;max-results=25'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8918867/posts/default'/><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://trontos.com/dsouth/blog/atom.xml'/><author><name>Doug</name><uri>http://www.blogger.com/profile/00713655468090655252</uri><email>noreply@blogger.com</email></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>101</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-8918867.post-5221768955432545813</id><published>2008-05-31T13:17:00.005+10:00</published><updated>2008-05-31T21:39:03.210+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JAOO'/><category scheme='http://www.blogger.com/atom/ns#' term='ErikMeijer'/><title type='text'>Brisbane JAOO - Conference Day 2 - Morning Keynote</title><content type='html'>The morning keynote was given by Erik  Meijer,&lt;em&gt;Why Functional Programming (Still) Matters&lt;/em&gt;.&lt;br /&gt;&lt;br /&gt;Creating software is all about abstraction, which is reducing information and retaining only relevant information. Unfortunately  the industry has been abstracting the wrong details for the last 50 years...&lt;br /&gt;&lt;br /&gt;There are 5 Dilemmas:&lt;br /&gt;&lt;br /&gt;1) Useful versus Useless&lt;br /&gt;&lt;br /&gt;I'm not sure I really understood the point Erik was trying to make here, but it was along the lines of the things that makes programs useful are the things that make them vulnerable to misuse, such as data as code and component interaction leads to &lt;a href="http://en.wikipedia.org/wiki/Cross-site_scripting"&gt;XSS&lt;/a&gt;, buffer overruns, virus and &lt;a href="http://en.wikipedia.org/wiki/Blue_Screen_of_Death"&gt;BSOD&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;2) Rich versus Reach&lt;br /&gt;&lt;br /&gt;Flash, Silverlight and Java are rich (proprietary) whereas HTTP, HTML and JavaScript have reach (open standards). Whatever :)&lt;br /&gt;&lt;br /&gt;3) Local versus Remote&lt;br /&gt;&lt;br /&gt;Local is easy and remote hard. Local is what is taught in school. Remote is interesting and more like real life development. Erik defined attributes of local as:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;compositional&lt;/li&gt;&lt;li&gt;sequential deterministic&lt;/li&gt;&lt;li&gt;implicit&lt;/li&gt;&lt;li&gt;synchronous&lt;/li&gt;&lt;li&gt;homogenous&lt;/li&gt;&lt;/ul&gt;and remote as :&lt;br /&gt;&lt;ul&gt;&lt;li&gt;concurrent&lt;/li&gt;&lt;li&gt;nondeterministic&lt;/li&gt;&lt;li&gt;explicit&lt;/li&gt;&lt;li&gt;asynchronous&lt;/li&gt;&lt;li&gt;heterogenous&lt;/li&gt;&lt;li&gt;noncompositional&lt;/li&gt;&lt;/ul&gt;4) Change versus Inertia&lt;br /&gt;&lt;br /&gt;Geeks like to build cool things. People just want to get things done. Marketing tries to make people believe that the cool new things that the geeks built are the things they need to get stuff done.&lt;br /&gt;&lt;br /&gt;Geeks p(success) = F(10 X improvement * Moore's Law)&lt;br /&gt;People p(success) = F(perceived crisis / perceived pain of adoption)&lt;br /&gt;&lt;br /&gt;see "&lt;a href="http://www.amazon.com/Change-Function-Technologies-Others-Crash/dp/1591841321"&gt;The Change Function&lt;/a&gt;"&lt;br /&gt;&lt;br /&gt;The fifth dilemma seems to be Erik's main point...&lt;br /&gt;&lt;br /&gt;5) Pure versus Impure&lt;br /&gt;&lt;br /&gt;Erik gives an example of some code (in C#?) that does a couple of queries including output that outputs in an order that is non-intuitive. The issue is that the code can be read as local yet the code is remote and the side effect of this is that things don't occur in the order that they have been coded.&lt;br /&gt;&lt;br /&gt;Another couple of examples (C# again?) shows an unchecked exception happening beyond where it would appear it should occur and a file being disposed before it is used, again local versus remote.&lt;br /&gt;&lt;br /&gt;The main point of all of these examples is that there are side effects occurring that are not obvious from the code, i.e. the relevant information has been abstracted away.&lt;br /&gt;&lt;br /&gt;Erik continues highlighting side effects by stating that even object creation has side effects, i.e. two different heap spaces are set aside for two different objects of the same class.&lt;br /&gt;&lt;br /&gt;Code has side effects which are not obvious from reading the code, that is the side effects of code are as important as the parameters and the return value.  But you can't get rid of side effects.&lt;br /&gt;&lt;br /&gt;Erik states that Fundamentalist Functional Programming is the answer (pure functions with explicit effects) where a functional language is defined as a language where functions are first-class citizens and given a function and a set of parameters, the function returns the same value ever time it is called with the set of parameters (equality-preserving, i.e no side effects). I believe it is here that he also makes the point that parameter evaluation should be lazy, but I have to admit that where this was mentioned or the importance of it was lost to me.&lt;br /&gt;&lt;br /&gt;Monads allow the declaration of a functions side effects and he gives a few examples of what this means the mapping to and from functions with monads.&lt;br /&gt;&lt;br /&gt;Then Erik considers whether or not normal programmers can understand what is required and can functional programs interact with legacy code. He gives some examples though all a little bit underwhelming in convince me that either is possible without much pain and gnashing of teeth.&lt;br /&gt;&lt;br /&gt;He concludes by giving a litmus test for determining whether or not a language is a fundamental functional language and suggests buying a Haskel book and helping to persuade MS to produce a fundamental functional language.&lt;br /&gt;&lt;br /&gt;While I found the talk interesting, it was rather unconvincing in its final conclusions for me. I'm in no rush to run out and buy yet another language book and I doubt I'll ever tell anyone what language they should implement. Erik's real crisis is just a perceived crisis and I doubt the industry would change to Haskel anytime soon based on the evidence from this talk. In the end, this talk just seems like an intellectual exercise to get people to think...</content><link rel='alternate' type='text/html' href='http://www.trontos.com/dsouth/blog/2008/05/brisban-jaoo-conference-day-2-morning.html' title='Brisbane JAOO - Conference Day 2 - Morning Keynote'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8918867&amp;postID=5221768955432545813' title='0 Comments'/><link rel='replies' type='application/atom+xml' href='http://trontos.com/dsouth/blog/atom.xml' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8918867/posts/default/5221768955432545813'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8918867/posts/default/5221768955432545813'/><author><name>Doug</name><uri>http://www.blogger.com/profile/00713655468090655252</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-8918867.post-7463382614618405890</id><published>2008-05-30T20:05:00.003+10:00</published><updated>2008-05-31T13:17:36.831+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JAOO'/><title type='text'>Brisbane  JAOO - Conference Day 3</title><content type='html'>Day three, pretty much the same as day 2, which is a good thing. I'll follow up later, but two snipets of the day.&lt;br /&gt;&lt;br /&gt;Bob Martin talking about Clean Code: "Code in a try block is living in a fantasy world where nothing goes wrong."&lt;br /&gt;&lt;br /&gt;End of the day chatting with &lt;a href="http://jaoo.com.au/brisbane-2008/speaker/Erik+Meijer"&gt;Erik&lt;/a&gt;, &lt;a href="http://jaoo.com.au/brisbane-2008/speaker/Gregor+Hohpe"&gt;Gregor&lt;/a&gt;, &lt;a href="http://jaoo.com.au/brisbane-2008/speaker/Patrick+Linskey"&gt;Patrick&lt;/a&gt; and &lt;a href="http://jaoo.com.au/brisbane-2008/speaker/Joe+Albahari"&gt;Joe&lt;/a&gt; and then being invited out for dinner! (Sadly I was too tired to take up the offer :( ).</content><link rel='alternate' type='text/html' href='http://www.trontos.com/dsouth/blog/2008/05/brisbane-jaoo-conference-day-3.html' title='Brisbane  JAOO - Conference Day 3'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8918867&amp;postID=7463382614618405890' title='0 Comments'/><link rel='replies' type='application/atom+xml' href='http://trontos.com/dsouth/blog/atom.xml' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8918867/posts/default/7463382614618405890'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8918867/posts/default/7463382614618405890'/><author><name>Doug</name><uri>http://www.blogger.com/profile/00713655468090655252</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-8918867.post-8958241917647842272</id><published>2008-05-29T20:45:00.005+10:00</published><updated>2008-05-30T20:05:47.476+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JAOO'/><title type='text'>Brisbane  JAOO - Conference Day 2</title><content type='html'>Wow, what a wonderful blur of a day it's been. Reflecting back on the day feels like looking over a few days in time so much has happened. Two interesting and informative keynotes and six sessions all with good knowledge to take away.&lt;br /&gt;&lt;br /&gt;If I had to pick one session as a favorite, it would have to be Erik Dörnenburg's and Gregor Hohpe's &lt;a href="http://jaoo.com.au/brisbane-2008/presentation/Software+Visualization+and+Model+Generation"&gt;Software Visualization and Model Generation&lt;/a&gt;. Simple ideas that can have a big impact on helping to manage large amounts of data. Basically they presented a simple pattern for using different tools to help visualize data. I'll post more details on this and other presentation over the next week or so.</content><link rel='alternate' type='text/html' href='http://www.trontos.com/dsouth/blog/2008/05/brisban-jaoo-conference-day-2.html' title='Brisbane  JAOO - Conference Day 2'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8918867&amp;postID=8958241917647842272' title='1 Comments'/><link rel='replies' type='application/atom+xml' href='http://trontos.com/dsouth/blog/atom.xml' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8918867/posts/default/8958241917647842272'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8918867/posts/default/8958241917647842272'/><author><name>Doug</name><uri>http://www.blogger.com/profile/00713655468090655252</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-8918867.post-2520690488994936703</id><published>2008-05-28T19:41:00.009+10:00</published><updated>2008-05-30T20:05:15.179+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JAOO'/><title type='text'>Brisbane JAOO - Tutorials Day 1</title><content type='html'>So today was my first day at &lt;a href="http://jaoo.com.au/brisbane-2008/conference/"&gt;JAOO&lt;/a&gt;. And I loved it. I attended two vey good tutorials: &lt;a href="http://www.wirfs-brock.com/"&gt;Rebbeca Wirfs-Brock&lt;/a&gt;'s The Art of Telling Your Design Story and &lt;a href="http://www.objectmentor.com/omTeam/martin_r.html"&gt;"Uncle" Bob&lt;/a&gt;'s "Advanced Principles of Agile Object Oriented Class and Component Design. Both presenters were engaging and definitely knew their subjects.&lt;br /&gt;&lt;br /&gt;From the first tutorial, the key point was figuring out what to remove from a story to help more effectively get your point across to your audience. There were a lot of good points across the tutorial and good information that can be used beyond just telling a design story.&lt;br /&gt;&lt;br /&gt;I really did enjoy the second tutorial. Bob is animated, full of energy and happy to digress slightly into entertaining and informative rants. He's completely shattered (in a good way) my view on OO modeling and the "&lt;a href="http://en.wikipedia.org/wiki/Is-a"&gt;is-a&lt;/a&gt;" and "&lt;a href="http://en.wikipedia.org/wiki/Has-a"&gt;has-a&lt;/a&gt;" relationships with excellent concrete examples. He gave us solid categorizations for defining problems with software designs. He made us reconsider what OO really means and I now have some interesting metrics to take back to our team to analyze the state of our codebase. Not to mention the design patterns he has for encouraging good design and fending off software rot. If I have some time and motivation in the future, I'll go into a lot more detail of what I learned from this tutorial.&lt;br /&gt;&lt;br /&gt;Oh, and being in the same room with the likes of "Uncle" Bob, &lt;a href="http://www.michaelfeathers.com/"&gt;Micheal Feathers&lt;/a&gt; and Martin Fowler, I'm really enjoying it...</content><link rel='alternate' type='text/html' href='http://www.trontos.com/dsouth/blog/2008/05/brisban-jaoo-tutorials-day-1.html' title='Brisbane JAOO - Tutorials Day 1'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8918867&amp;postID=2520690488994936703' title='0 Comments'/><link rel='replies' type='application/atom+xml' href='http://trontos.com/dsouth/blog/atom.xml' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8918867/posts/default/2520690488994936703'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8918867/posts/default/2520690488994936703'/><author><name>Doug</name><uri>http://www.blogger.com/profile/00713655468090655252</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-8918867.post-1380272799809341071</id><published>2008-05-27T16:13:00.004+10:00</published><updated>2008-05-27T20:45:15.060+10:00</updated><title type='text'>Better than simian-check</title><content type='html'>&lt;a href="http://www.redhillconsulting.com.au/products/simian/"&gt;Simian&lt;/a&gt; is great for helping to maintain code quality and enforcing the &lt;a href="http://en.wikipedia.org/wiki/Don%27t_repeat_yourself"&gt;DRY&lt;/a&gt; principle, especially in a green field project. And while not as helpful, it can help to implement the idea of "making things no worse" in a brown field project. However, its goodness only extends in one dimension for a two dimensional problem.&lt;br /&gt;&lt;br /&gt;A team can mandate that the number of duplications within the codebase shall be no more than some threshold. That's one dimension. But what about duplications that already occur below the threshold? simian-check does nothing to ensure that the level of duplication below the threshold doesn't entropy. Simian is good for legacy codebases, but there is plenty of room for improvement.&lt;br /&gt;&lt;br /&gt;This is something I've been mildly aware of for several years now, but I haven't been actively trying to find a way to solve it until recently. I had some slack time and was feverishly working at refactoring our legacy codebase to reduce our simian-check threshold another notch. Having reduced the count by one, I took a quick survey of what would be required to reduce it by yet another notch. At that moment I half panicked half had a flash of insight (most like I had the insight quickly followed by a brief moment of terror).&lt;br /&gt;&lt;br /&gt;If you've never had to play in a large legacy codebase, you may not have ever run into the situation I just found myself. Since simian had not been running on this system, there was a lot of duplication. The more the threshold was lowered for the simian-check, the more work (i.e. more duplications to be removed) was required to lower the threshold one more notch. And the increase in work is more than linear.&lt;br /&gt;&lt;br /&gt;My insight was this; I had a finite amount of time in which to lower the duplication count. If I couldn't do &lt;span style="font-weight: bold;"&gt;all&lt;/span&gt; off the work within that time, the threshold would remain the same. It was quite possible that I could remove half the duplications and then return sometime later and find that I had double the work to do. While that's possible, it's not very probably. I had seen the second dimension to the simian-check. My fear from that initial thought got the wheels in my head in motion.&lt;br /&gt;&lt;br /&gt;The solution is very simple. The simian-report is a an xml file, so I wrote a SAX2 &lt;a href="http://java.sun.com/j2se/1.4.2/docs/api/org/xml/sax/helpers/DefaultHandler.html"&gt;DefaultHandler&lt;/a&gt; that was able to parse the number of duplications at the different threshold levels. Putting this into a trivial ant task then gave us a task to help make things no worse even at levels below what the simian-check was doing! Within the first week, the new legacy-check was breaking the build (where the simian-check would never have) and focusing the teams attention on how to make things better.</content><link rel='alternate' type='text/html' href='http://www.trontos.com/dsouth/blog/2008/05/better-than-simian-check.html' title='Better than simian-check'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8918867&amp;postID=1380272799809341071' title='2 Comments'/><link rel='replies' type='application/atom+xml' href='http://trontos.com/dsouth/blog/atom.xml' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8918867/posts/default/1380272799809341071'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8918867/posts/default/1380272799809341071'/><author><name>Doug</name><uri>http://www.blogger.com/profile/00713655468090655252</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-8918867.post-5776510491818116263</id><published>2008-05-04T11:39:00.002+10:00</published><updated>2008-05-04T11:49:50.580+10:00</updated><title type='text'>Scala</title><content type='html'>I've been spending a bit of my spare time learning &lt;a href="http://www.scala-lang.org"&gt;Scala&lt;/a&gt;. I like it because:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;It compiles to Java bytecode&lt;/li&gt;&lt;li&gt;It can use any of the Java API's - the years of investment I have in them translates seamlessly to Scala development and I'm productive almost immediately&lt;/li&gt;&lt;li&gt;Functions are first class citizens of the language allowing for &lt;a href="http://en.wikipedia.org/wiki/Higher-order_function"&gt;higher order functions&lt;/a&gt; leading to a more expressive language&lt;/li&gt;&lt;/ol&gt;It has a some other benefits, but I haven't fully learned the  language just yet, so it's hard to say I like it because of things I haven't experienced.&lt;br /&gt;&lt;br /&gt;The main drawback at the moment is lack of IDE support. I'm using the scala eclipse plugin, but it is primitive compared to the Java support I'm used to in eclipse.</content><link rel='alternate' type='text/html' href='http://www.trontos.com/dsouth/blog/2008/05/scala.html' title='Scala'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8918867&amp;postID=5776510491818116263' title='0 Comments'/><link rel='replies' type='application/atom+xml' href='http://trontos.com/dsouth/blog/atom.xml' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8918867/posts/default/5776510491818116263'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8918867/posts/default/5776510491818116263'/><author><name>Doug</name><uri>http://www.blogger.com/profile/00713655468090655252</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-8918867.post-5132126214625342088</id><published>2008-04-29T10:57:00.003+10:00</published><updated>2008-04-29T12:17:12.772+10:00</updated><title type='text'>The quality of the code you write today...</title><content type='html'>... will affect your ability to write quality code for the new features you need tomorrow.&lt;br /&gt;&lt;br /&gt;If you haven't been writing quality code, how can you expect to write new code with any degree of quality? I hypothesize that the affect of this isn't linear, but exponential.</content><link rel='alternate' type='text/html' href='http://www.trontos.com/dsouth/blog/2008/04/quality-of-code-you-write-today.html' title='The quality of the code you write today...'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8918867&amp;postID=5132126214625342088' title='0 Comments'/><link rel='replies' type='application/atom+xml' href='http://trontos.com/dsouth/blog/atom.xml' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8918867/posts/default/5132126214625342088'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8918867/posts/default/5132126214625342088'/><author><name>Doug</name><uri>http://www.blogger.com/profile/00713655468090655252</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-8918867.post-7239579255856359282</id><published>2008-04-28T20:22:00.002+10:00</published><updated>2008-04-28T20:28:55.877+10:00</updated><title type='text'>No difference between permanent and contracting...</title><content type='html'>I started out contracting for a long time until eventually moving into a permanent position. At the time, on reflecting on everything, I couldn't see any major difference between the two. I've always maintained there isn't a big difference in the long run.&lt;br /&gt;&lt;br /&gt;But there is one thing I've just started to realize that I miss. That's the downtime (when there is some) between jobs. Now I take holidays, and even though I know I'll still have a job when it is done, I don't have the time to learn new technology like I would during downtime.&lt;br /&gt;&lt;br /&gt;Holidays are for de-stressing and catching up with family. Downtime was the time to re-skill and explore. Or more likely, I had more free time to develop my professional skills and interests.</content><link rel='alternate' type='text/html' href='http://www.trontos.com/dsouth/blog/2008/04/no-difference-between-permanent-and.html' title='No difference between permanent and contracting...'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8918867&amp;postID=7239579255856359282' title='0 Comments'/><link rel='replies' type='application/atom+xml' href='http://trontos.com/dsouth/blog/atom.xml' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8918867/posts/default/7239579255856359282'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8918867/posts/default/7239579255856359282'/><author><name>Doug</name><uri>http://www.blogger.com/profile/00713655468090655252</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-8918867.post-4804101230656737158</id><published>2008-04-14T19:59:00.003+10:00</published><updated>2008-04-14T20:18:20.260+10:00</updated><title type='text'>Ironic</title><content type='html'>Seth &lt;a href="http://sethgodin.typepad.com/seths_blog/2008/04/the-wealthy-g-1.html"&gt;makes a interesting point&lt;/a&gt; about something I've noticed for a long time. The main point that I find of value is:&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-weight: bold;"&gt;It's just too long a ramp up time, too frustrating and too uncertain to be the best path to make a living.&lt;/span&gt;&lt;/blockquote&gt;But this applies to more than just writing a blog.&lt;br /&gt;&lt;br /&gt;I believe (and live by the idea) that only the people truly passionate about what they do seem to be the ones that do the best. The ones that are famous/wealthy/successful are the ones that didn't set out to be famous/wealthy/successful. The passion gets you over the ramp up time, the frustration and the uncertainty. And most importantly, the passion gives you the drive to focus on doing what is best for your passion and not necessarily for you ego.&lt;br /&gt;&lt;br /&gt;Personally, I'm passionate about programming to provide value. I'm passionate about quality. I'm passionate about eliminating waste. I'm passionate about flow. I'm passionate about chasing perfection.&lt;br /&gt;&lt;br /&gt;And I do love irony at times...</content><link rel='alternate' type='text/html' href='http://www.trontos.com/dsouth/blog/2008/04/ironic.html' title='Ironic'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8918867&amp;postID=4804101230656737158' title='0 Comments'/><link rel='replies' type='application/atom+xml' href='http://trontos.com/dsouth/blog/atom.xml' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8918867/posts/default/4804101230656737158'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8918867/posts/default/4804101230656737158'/><author><name>Doug</name><uri>http://www.blogger.com/profile/00713655468090655252</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-8918867.post-2051687844478224207</id><published>2008-04-10T12:59:00.003+10:00</published><updated>2008-04-10T13:03:49.058+10:00</updated><title type='text'>What to do...</title><content type='html'>Now that I've got the Google Apps account, I'm struggling a bit about what to do with it. I thought about writing a blog app and blogging to that as well, but &lt;a href="http://bret.appspot.com/entry/experimenting-google-app-engine"&gt;someone&lt;/a&gt; already beat me to that. I have a few ideas, but they are all incomplete and seem to serve no useful purpose. I'm open to suggestions (hint, hint, comment, hint, hint).</content><link rel='alternate' type='text/html' href='http://www.trontos.com/dsouth/blog/2008/04/what-to-do.html' title='What to do...'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8918867&amp;postID=2051687844478224207' title='0 Comments'/><link rel='replies' type='application/atom+xml' href='http://trontos.com/dsouth/blog/atom.xml' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8918867/posts/default/2051687844478224207'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8918867/posts/default/2051687844478224207'/><author><name>Doug</name><uri>http://www.blogger.com/profile/00713655468090655252</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-8918867.post-2193123550491103177</id><published>2008-04-10T12:52:00.002+10:00</published><updated>2008-04-10T12:59:17.451+10:00</updated><title type='text'>Learning Python</title><content type='html'>Thanks to the Google Apps account, I'm now learning Python (to some extent). The first important task when learning a new language is learning to read errors. After a few, I think I know what the interpreter is trying to tell me when it's not happy. But the first time is always the funnest.&lt;br /&gt;&lt;br /&gt;As a complete Python newbie, I initially missed the difference between:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;span class="kwd"&gt;class&lt;/span&gt;&lt;span class="pln"&gt; &lt;/span&gt;&lt;span class="typ"&gt;MainPage&lt;/span&gt;&lt;span class="pun"&gt;(&lt;/span&gt;&lt;span class="pln"&gt;webapp&lt;/span&gt;&lt;span class="pun"&gt;.&lt;/span&gt;&lt;span class="typ"&gt;RequestHandler&lt;/span&gt;&lt;span class="pun"&gt;):&lt;/span&gt;&lt;span class="pln"&gt;&lt;br /&gt; &lt;/span&gt;&lt;span class="kwd"&gt;def&lt;/span&gt;&lt;span class="pln"&gt; get&lt;/span&gt;&lt;span class="pun"&gt;(&lt;/span&gt;&lt;span class="pln"&gt;self&lt;/span&gt;&lt;span class="pun"&gt;):&lt;/span&gt;&lt;span class="pln"&gt;&lt;br /&gt;   self&lt;/span&gt;&lt;span class="pun"&gt;.&lt;/span&gt;&lt;span class="pln"&gt;response&lt;/span&gt;&lt;span class="pun"&gt;.&lt;/span&gt;&lt;span class="pln"&gt;headers&lt;/span&gt;&lt;span class="pun"&gt;[&lt;/span&gt;&lt;span class="str"&gt;'Content-Type'&lt;/span&gt;&lt;span class="pun"&gt;]&lt;/span&gt;&lt;span class="pln"&gt; &lt;/span&gt;&lt;span class="pun"&gt;=&lt;/span&gt;&lt;span class="pln"&gt; &lt;/span&gt;&lt;span class="str"&gt;'text/plain'&lt;/span&gt;&lt;span class="pln"&gt;&lt;br /&gt;   self&lt;/span&gt;&lt;span class="pun"&gt;.&lt;/span&gt;&lt;span class="pln"&gt;response&lt;/span&gt;&lt;span class="pun"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;out&lt;/span&gt;&lt;span class="pun"&gt;.&lt;/span&gt;&lt;span class="pln"&gt;write&lt;/span&gt;&lt;span class="pun"&gt;(&lt;/span&gt;&lt;span class="str"&gt;'Hello, webapp World!'&lt;/span&gt;&lt;span class="pun"&gt;)&lt;/span&gt;&lt;span class="pln"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="kwd"&gt;def&lt;/span&gt;&lt;span class="pln"&gt; main&lt;/span&gt;&lt;span class="pun"&gt;():&lt;/span&gt;&lt;span class="pln"&gt;&lt;br /&gt; application &lt;/span&gt;&lt;span class="pun"&gt;=&lt;/span&gt;&lt;span class="pln"&gt; webapp&lt;/span&gt;&lt;span class="pun"&gt;.&lt;/span&gt;&lt;span class="typ"&gt;WSGIApplication&lt;/span&gt;&lt;span class="pun"&gt;(&lt;/span&gt;&lt;span class="pln"&gt;&lt;br /&gt;                                      &lt;/span&gt;&lt;span class="pun"&gt;[(&lt;/span&gt;&lt;span class="str"&gt;'/'&lt;/span&gt;&lt;span class="pun"&gt;,&lt;/span&gt;&lt;span class="pln"&gt; &lt;/span&gt;&lt;span class="typ"&gt;MainPage&lt;/span&gt;&lt;span class="pun"&gt;)],&lt;/span&gt;&lt;span class="pln"&gt;&lt;br /&gt;                                      debug&lt;/span&gt;&lt;span class="pun"&gt;=&lt;/span&gt;&lt;span class="kwd"&gt;True&lt;/span&gt;&lt;span class="pun"&gt;)&lt;/span&gt;&lt;span class="pln"&gt;&lt;br /&gt; wsgiref&lt;/span&gt;&lt;span class="pun"&gt;.&lt;/span&gt;&lt;span class="pln"&gt;handlers&lt;/span&gt;&lt;span class="pun"&gt;.&lt;/span&gt;&lt;span class="typ"&gt;CGIHandler&lt;/span&gt;&lt;span class="pun"&gt;().&lt;/span&gt;&lt;span class="pln"&gt;run&lt;/span&gt;&lt;span class="pun"&gt;(&lt;/span&gt;&lt;span class="pln"&gt;application&lt;/span&gt;&lt;span class="pun"&gt;)&lt;/span&gt;&lt;span class="pln"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/pre&gt;and&lt;pre&gt;&lt;span class="kwd"&gt;class&lt;/span&gt;&lt;span class="pln"&gt; &lt;/span&gt;&lt;span class="typ"&gt;MainPage&lt;/span&gt;&lt;span class="pun"&gt;(&lt;/span&gt;&lt;span class="pln"&gt;webapp&lt;/span&gt;&lt;span class="pun"&gt;.&lt;/span&gt;&lt;span class="typ"&gt;RequestHandler&lt;/span&gt;&lt;span class="pun"&gt;):&lt;/span&gt;&lt;span class="pln"&gt;&lt;br /&gt; &lt;/span&gt;&lt;span class="kwd"&gt;def&lt;/span&gt;&lt;span class="pln"&gt; get&lt;/span&gt;&lt;span class="pun"&gt;(&lt;/span&gt;&lt;span class="pln"&gt;self&lt;/span&gt;&lt;span class="pun"&gt;):&lt;/span&gt;&lt;span class="pln"&gt;&lt;br /&gt;   self&lt;/span&gt;&lt;span class="pun"&gt;.&lt;/span&gt;&lt;span class="pln"&gt;response&lt;/span&gt;&lt;span class="pun"&gt;.&lt;/span&gt;&lt;span class="pln"&gt;headers&lt;/span&gt;&lt;span class="pun"&gt;[&lt;/span&gt;&lt;span class="str"&gt;'Content-Type'&lt;/span&gt;&lt;span class="pun"&gt;]&lt;/span&gt;&lt;span class="pln"&gt; &lt;/span&gt;&lt;span class="pun"&gt;=&lt;/span&gt;&lt;span class="pln"&gt; &lt;/span&gt;&lt;span class="str"&gt;'text/plain'&lt;/span&gt;&lt;span class="pln"&gt;&lt;br /&gt;   self&lt;/span&gt;&lt;span class="pun"&gt;.&lt;/span&gt;&lt;span class="pln"&gt;response&lt;/span&gt;&lt;span class="pun"&gt;.&lt;/span&gt;&lt;span class="kwd"&gt;out&lt;/span&gt;&lt;span class="pun"&gt;.&lt;/span&gt;&lt;span class="pln"&gt;write&lt;/span&gt;&lt;span class="pun"&gt;(&lt;/span&gt;&lt;span class="str"&gt;'Hello, webapp World!'&lt;/span&gt;&lt;span class="pun"&gt;)&lt;/span&gt;&lt;span class="pln"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span class="kwd"&gt;  def&lt;/span&gt;&lt;span class="pln"&gt; main&lt;/span&gt;&lt;span class="pun"&gt;():&lt;/span&gt;&lt;span class="pln"&gt;&lt;br /&gt;   application &lt;/span&gt;&lt;span class="pun"&gt;=&lt;/span&gt;&lt;span class="pln"&gt; webapp&lt;/span&gt;&lt;span class="pun"&gt;.&lt;/span&gt;&lt;span class="typ"&gt;WSGIApplication&lt;/span&gt;&lt;span class="pun"&gt;(&lt;/span&gt;&lt;span class="pln"&gt;&lt;br /&gt;                                        &lt;/span&gt;&lt;span class="pun"&gt;[(&lt;/span&gt;&lt;span class="str"&gt;'/'&lt;/span&gt;&lt;span class="pun"&gt;,&lt;/span&gt;&lt;span class="pln"&gt; &lt;/span&gt;&lt;span class="typ"&gt;MainPage&lt;/span&gt;&lt;span class="pun"&gt;)],&lt;/span&gt;&lt;span class="pln"&gt;&lt;br /&gt;                                        debug&lt;/span&gt;&lt;span class="pun"&gt;=&lt;/span&gt;&lt;span class="kwd"&gt;True&lt;/span&gt;&lt;span class="pun"&gt;)&lt;/span&gt;&lt;span class="pln"&gt;&lt;br /&gt;   wsgiref&lt;/span&gt;&lt;span class="pun"&gt;.&lt;/span&gt;&lt;span class="pln"&gt;handlers&lt;/span&gt;&lt;span class="pun"&gt;.&lt;/span&gt;&lt;span class="typ"&gt;CGIHandler&lt;/span&gt;&lt;span class="pun"&gt;().&lt;/span&gt;&lt;span class="pln"&gt;run&lt;/span&gt;&lt;span class="pun"&gt;(&lt;/span&gt;&lt;span class="pln"&gt;application&lt;/span&gt;&lt;span class="pun"&gt;)&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;10 minutes into the lexical spec and not only did I get the error here, I got a far better and first hand understand of Python. Now the task is to keep learning...</content><link rel='alternate' type='text/html' href='http://www.trontos.com/dsouth/blog/2008/04/learning-python.html' title='Learning Python'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8918867&amp;postID=2193123550491103177' title='0 Comments'/><link rel='replies' type='application/atom+xml' href='http://trontos.com/dsouth/blog/atom.xml' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8918867/posts/default/2193123550491103177'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8918867/posts/default/2193123550491103177'/><author><name>Doug</name><uri>http://www.blogger.com/profile/00713655468090655252</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-8918867.post-6396063866439475827</id><published>2008-04-09T18:11:00.002+10:00</published><updated>2008-04-09T18:14:52.755+10:00</updated><title type='text'>Google Apps</title><content type='html'>Don't know if I was looking or Google has been generous, but I've got a google apps account. The reaction was, "Quick, grab a new toy." Followed by (ask requesting it), "Um, what am I going to do with this?!?". Apparently, the first thing I'm going to do is learn Python (which doesn't appear to difficult, apart from the lack of semicolons :)).</content><link rel='alternate' type='text/html' href='http://www.trontos.com/dsouth/blog/2008/04/google-apps.html' title='Google Apps'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8918867&amp;postID=6396063866439475827' title='0 Comments'/><link rel='replies' type='application/atom+xml' href='http://trontos.com/dsouth/blog/atom.xml' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8918867/posts/default/6396063866439475827'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8918867/posts/default/6396063866439475827'/><author><name>Doug</name><uri>http://www.blogger.com/profile/00713655468090655252</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-8918867.post-4040851132308562315</id><published>2007-12-06T20:34:00.001+10:00</published><updated>2007-12-06T20:43:59.410+10:00</updated><title type='text'>Estimations - Best, Expected and Worst</title><content type='html'>One of these posts I'll stop mentioning Dave Thomas, but until then...&lt;br /&gt;&lt;br /&gt;Another thing that he mentioned was how to give estimates. Nobody should give a single point estimate. No risk factor is involved. But given a best case, expected case and worst case, it is quite easy to see what is risky and what isn't. With this in mind, we spent quite a few hours today giving high level estimates for our current work using these three points. (Work that we hadn't estimated but had planned to sometime this week. Isn't it nice how things come together sometimes...) I think everyone got something good out of it and our estimates feel a bit more accurate and considered.&lt;br /&gt;&lt;br /&gt;To be honest, as a developer, I feel horrible when I miss an estimate, whether it is longer &lt;span style="font-weight: bold;"&gt;or &lt;/span&gt;shorter than expected. But with three point estimates, as long as we hit the range and are good about being close to our expected I don't think I'll mind missing our expected estimate (which is the only one we gave in the past).</content><link rel='alternate' type='text/html' href='http://www.trontos.com/dsouth/blog/2007/12/estimations-best-expected-and-worst.html' title='Estimations - Best, Expected and Worst'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8918867&amp;postID=4040851132308562315' title='0 Comments'/><link rel='replies' type='application/atom+xml' href='http://trontos.com/dsouth/blog/atom.xml' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8918867/posts/default/4040851132308562315'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8918867/posts/default/4040851132308562315'/><author><name>Doug</name><uri>http://www.blogger.com/profile/00713655468090655252</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-8918867.post-6471658769468216826</id><published>2007-12-05T21:19:00.000+10:00</published><updated>2007-12-05T21:23:12.655+10:00</updated><title type='text'>Feeling the Rhythm</title><content type='html'>When we've been writing tests lately I've caught us occasionally not feeling the rhythm. It's more obvious now and I'm actually stopping and looking for a red bar. And I haven't found it on a at least 2-3 times over the last few days.&lt;br /&gt;&lt;br /&gt;A test without the Red Bar is a waste of everyone's time and instills false confidence/trust that will get shattered eventually.</content><link rel='alternate' type='text/html' href='http://www.trontos.com/dsouth/blog/2007/12/feeling-rhythm.html' title='Feeling the Rhythm'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8918867&amp;postID=6471658769468216826' title='0 Comments'/><link rel='replies' type='application/atom+xml' href='http://trontos.com/dsouth/blog/atom.xml' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8918867/posts/default/6471658769468216826'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8918867/posts/default/6471658769468216826'/><author><name>Doug</name><uri>http://www.blogger.com/profile/00713655468090655252</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-8918867.post-7244266838124808877</id><published>2007-12-05T21:11:00.000+10:00</published><updated>2007-12-05T21:18:22.969+10:00</updated><title type='text'>Dave Thomas sound bites</title><content type='html'>Dave Thomas (the &lt;a href="http://www.davethomas.net/"&gt;SmallTalk&lt;/a&gt; one and not the &lt;a href="http://pragdave.pragprog.com/"&gt;Ruby&lt;/a&gt; one) gave a very interesting presentation tonight with a lot of good information in it. Two things really stood out for me:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Best Wrong Way&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Stories without Acceptance Tests are wishes (I may be paraphrasing slightly)&lt;/li&gt;&lt;/ol&gt;Best Wrong Way means that today we are doing our Best Wrong Way and tomorrow we will find a better Wrong Way. There is no Best Right Way (just like there are no Silver Bullets). A lot like focusing on making things no worse instead of trying to always make things better.&lt;br /&gt;&lt;br /&gt;I think wishes speaks for itself.</content><link rel='alternate' type='text/html' href='http://www.trontos.com/dsouth/blog/2007/12/dave-thomas-sound-bites.html' title='Dave Thomas sound bites'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8918867&amp;postID=7244266838124808877' title='0 Comments'/><link rel='replies' type='application/atom+xml' href='http://trontos.com/dsouth/blog/atom.xml' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8918867/posts/default/7244266838124808877'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8918867/posts/default/7244266838124808877'/><author><name>Doug</name><uri>http://www.blogger.com/profile/00713655468090655252</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-8918867.post-7866468187003696392</id><published>2007-12-05T07:38:00.000+10:00</published><updated>2007-12-05T07:51:26.640+10:00</updated><title type='text'>Almost an Agile conference in Brisbane</title><content type='html'>I mentioned Agile conferences in Brisbane &lt;a href="http://www.trontos.com/dsouth/blog/2007/01/xp-conference-in-brisbane.html"&gt;before&lt;/a&gt; (specifically the lack of), but now it looks like there will be &lt;a href="http://jaoo.com.au/brisbane/conference/"&gt;something&lt;/a&gt; with possibly an Agile track at the end of May, 2008. Thanks to Dave Thomas (not &lt;a href="http://pragdave.pragprog.com/"&gt;the pragmatic one&lt;/a&gt;, &lt;a href="http://www.davethomas.net/"&gt;the other one&lt;/a&gt; :) ), we'll be seeing a major conference with a definite technical focus in Brisbane. Yay! Details of speakers and tracks should be updated some time in January.</content><link rel='alternate' type='text/html' href='http://www.trontos.com/dsouth/blog/2007/12/almost-agile-conference-in-brisbane.html' title='Almost an Agile conference in Brisbane'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8918867&amp;postID=7866468187003696392' title='0 Comments'/><link rel='replies' type='application/atom+xml' href='http://trontos.com/dsouth/blog/atom.xml' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8918867/posts/default/7866468187003696392'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8918867/posts/default/7866468187003696392'/><author><name>Doug</name><uri>http://www.blogger.com/profile/00713655468090655252</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-8918867.post-2992731394144150479</id><published>2007-11-13T20:18:00.000+10:00</published><updated>2007-11-13T20:29:30.707+10:00</updated><title type='text'>Root Cause Analysis</title><content type='html'>I've enjoyed problem solving from a young age. This enjoyment has lead me to the career I currently have and plan to have for some time to come. Yet I've never thought about trying to improve this skill until recently.&lt;br /&gt;&lt;br /&gt;At our quarterly retrospective we identified root cause analysis as the main practice that would bring the team maximum benefit. We've struggled with how to do this and promote it within the team because we haven't found (haven't searched hard enough to find?) much documentation about how to approach applying root cause analysis. So I've just started to be far more critical in my day to day problem solving and I've noticed a big difference in my ability to understand and fix issues.  I feel as if my ability to see &lt;span style="font-weight: bold;"&gt;the&lt;/span&gt; issue has increased by magnitudes and with this I've found it easier to address the root cause and be far more effective in my job.&lt;br /&gt;&lt;br /&gt;I guess there is always room for improvement, even with something that may be considered a strength...</content><link rel='alternate' type='text/html' href='http://www.trontos.com/dsouth/blog/2007/11/root-cause-analysis.html' title='Root Cause Analysis'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8918867&amp;postID=2992731394144150479' title='0 Comments'/><link rel='replies' type='application/atom+xml' href='http://trontos.com/dsouth/blog/atom.xml' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8918867/posts/default/2992731394144150479'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8918867/posts/default/2992731394144150479'/><author><name>Doug</name><uri>http://www.blogger.com/profile/00713655468090655252</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-8918867.post-7510626226412459334</id><published>2007-10-29T19:39:00.000+10:00</published><updated>2007-10-29T20:48:24.183+10:00</updated><title type='text'>Feel the Rhythm</title><content type='html'>TDD means you start by writing failing tests. It's a simple premise, but one I find people new to TDD do not fully appreciate. You need the red bar before you get the good feeling of a green bar. On its own, the green bar is empty and misleading.&lt;br /&gt;&lt;br /&gt;It took a conversation with Steve Hayes before I really got it. Since then, I've been trying to pass the wisdom on, but in the end it is a journey of self discovery. I remember belaboring this point to &lt;a href="http://hamstaa.hbhau.net/"&gt;my manager&lt;/a&gt; one day, though I felt the message wasn't hitting home. Then that week, he wrote a test that didn't fail as he expected it should (yeah, we let him write code from time to time) and I think he got it.&lt;br /&gt;&lt;br /&gt;What prompted this is that today Jack and I were TDDing some new functionality. We'd written two simple tests for some filtering of HTML that we required. The first one tested that the source was not filtered when there was nothing to filter. The second test was a simple test to make sure that the first stage of the expected transformation in the filtering occurred.&lt;br /&gt;&lt;br /&gt;We had a red bar, followed by a green bar for the first test and all felt good in the world. Then we had another red bar that was eventually followed by a green bar and everything was still good in the world. We realized to move forward, we expected attributes on the filtered tags and hence we needed to add a bit to the second test. (Que music of bad things to come, slow fade in.)&lt;br /&gt;&lt;br /&gt;Our first step was to add the attributes to the test that just passed, thus writing a new failing test. Run test, green bar. Green bar!?! Between us, we worked out that an assertion that the team used didn't actually test what we were testing for in our HTML (Its a corner case we never really anticipated well, and not just adding attributes to any ol' tag.) (Que alarm bells ringing, loud and jarring)&lt;br /&gt;&lt;br /&gt;Inspecting the assertion code, there are two comparison methods, one for most situation and one for the special situation we were testing (which we also discovered isn't used by a single test, not one, nada, zip, zilch, goose egg, ...). But we knew that the special situation doesn't work from our investigations into why we still were getting a green bar. (Que loud bomb raid siren)&lt;br /&gt;&lt;br /&gt;We concocted a simple test by just changing one parameter in the normal compare that would cause the test to fail if it was in fact testing the special case. We ran the atomic tests and got a green bar. Yay so far. We ran the integration tests and started to see failing tests. In all, 131 tests have failed. (Que final bad conclusion dramatic music)&lt;br /&gt;&lt;br /&gt;My initial impression was that when we wrote these tests, we weren't feeling the rhythm or the assertion was changed at a later date. I'm willing to bet that it is the former that we failed on.&lt;br /&gt;&lt;br /&gt;Conclusion: no matter how confident you feel, you owe it to yourself, your partner (if you are fortune enough to be pairing), your team and your customer/employer to alway find that red bar. I don't care if you think the test tests what you expect it to, prove it with a red bar.&lt;br /&gt;&lt;br /&gt;Corollary: If you are testing legacy code and your write a test, you'd expect it to pass, which is right, but remember to feel the rhythm and modify the part of the legacy code you think you are testing. No red bar on re-running the test means you're wrong and need to reconsider what you are doing.&lt;br /&gt;&lt;br /&gt;Hopefully, you too will find the rhythm and make the your world a slightly better place to live...</content><link rel='alternate' type='text/html' href='http://www.trontos.com/dsouth/blog/2007/10/feel-rhythm.html' title='Feel the Rhythm'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8918867&amp;postID=7510626226412459334' title='0 Comments'/><link rel='replies' type='application/atom+xml' href='http://trontos.com/dsouth/blog/atom.xml' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8918867/posts/default/7510626226412459334'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8918867/posts/default/7510626226412459334'/><author><name>Doug</name><uri>http://www.blogger.com/profile/00713655468090655252</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-8918867.post-6460042739520779131</id><published>2007-09-10T15:33:00.000+10:00</published><updated>2007-09-10T19:26:09.835+10:00</updated><title type='text'>Oh, the Irony</title><content type='html'>So my feed reader informed me of &lt;a href="http://blogs.atlassian.com/news/2007/09/the_evolution_o.html"&gt;this&lt;/a&gt;, which I saved and just had a look at. ARGH! So, in the beginning, publishing required some arcane markup that only a few technical folks knew how to create. But things are better now, because we can publish in wiki markup! But, but, but ... [sigh]&lt;br /&gt;&lt;br /&gt;Wiki-markup is something that you have to have some technical understanding of to apply correctly. Why not use a &lt;a href="http://www.ephox.com/products/editlive/"&gt;real editor&lt;/a&gt; instead. Yeah, I know that wikis are cool, but I'm sick of using horrible editors.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;UPDATE:&lt;/span&gt; I was so flabbergasted after seeing the video, I grabbed the wrong link in the first paragraph, but that's fixed now. Always check you links. :)</content><link rel='alternate' type='text/html' href='http://www.trontos.com/dsouth/blog/2007/09/oh-irony.html' title='Oh, the Irony'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8918867&amp;postID=6460042739520779131' title='1 Comments'/><link rel='replies' type='application/atom+xml' href='http://trontos.com/dsouth/blog/atom.xml' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8918867/posts/default/6460042739520779131'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8918867/posts/default/6460042739520779131'/><author><name>Doug</name><uri>http://www.blogger.com/profile/00713655468090655252</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-8918867.post-1663530433952514080</id><published>2007-08-22T07:17:00.000+10:00</published><updated>2007-08-22T07:26:56.509+10:00</updated><title type='text'>My New Favorite Refactoring Tool</title><content type='html'>Quite often I spy code that looks similar, but not obviously so[1]. I used to do a side by side comparison to help identify the similarities which would then allow me to refactor successfully. The problem is that a side by side comparison requires me to be very diligent, comparing each line one at a time.&lt;br /&gt;&lt;br /&gt;Now I just use &lt;a href="http://notepad-plus.sourceforge.net/uk/site.htm"&gt;Notepad++&lt;/a&gt; (but any text editor with tabs would do) and load suspected similar snippets in individual tabs. Then it is as simple as flipping between the tabs to see what moves. If things move, consolidate and continue. When they stop moving, I've found my refactoring.&lt;br /&gt;&lt;br /&gt;[1] - we do use &lt;a href="http://www.redhillconsulting.com.au/products/simian/"&gt;Simian&lt;/a&gt;, but it is on a large legacy code base, so the configuration for Simian isn't as tight as I would like it to be.</content><link rel='alternate' type='text/html' href='http://www.trontos.com/dsouth/blog/2007/08/my-new-favorite-refactoring-tool.html' title='My New Favorite Refactoring Tool'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8918867&amp;postID=1663530433952514080' title='0 Comments'/><link rel='replies' type='application/atom+xml' href='http://trontos.com/dsouth/blog/atom.xml' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8918867/posts/default/1663530433952514080'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8918867/posts/default/1663530433952514080'/><author><name>Doug</name><uri>http://www.blogger.com/profile/00713655468090655252</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-8918867.post-8888126612528890462</id><published>2007-08-22T07:14:00.000+10:00</published><updated>2007-08-22T07:17:19.762+10:00</updated><title type='text'>I wish I could ...</title><content type='html'>... blog as well/efficiently/profoundly as Jason Yip. &lt;a href="http://jchyip.blogspot.com/2007/08/prioritise-to-maintain-options.html"&gt;For example&lt;/a&gt;...</content><link rel='alternate' type='text/html' href='http://www.trontos.com/dsouth/blog/2007/08/i-wish-i-could.html' title='I wish I could ...'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8918867&amp;postID=8888126612528890462' title='0 Comments'/><link rel='replies' type='application/atom+xml' href='http://trontos.com/dsouth/blog/atom.xml' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8918867/posts/default/8888126612528890462'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8918867/posts/default/8888126612528890462'/><author><name>Doug</name><uri>http://www.blogger.com/profile/00713655468090655252</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-8918867.post-4775922040411826398</id><published>2007-06-24T07:07:00.000+10:00</published><updated>2007-06-27T20:00:46.410+10:00</updated><title type='text'>Common Music pre-Opus 1, part 1</title><content type='html'>Here's my first attempt at some practical Lisp:&lt;br /&gt;&lt;pre&gt;&lt;span style="font-family:courier new;"&gt;(in-package :cm)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;(defvar *major-scale-intervals* '(0 2 4 5 7 9 11 12))&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;(defvar *minor-scale-intervals* '(0 2 3 5 7 8 11 12))&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;(defvar *major-scale-steps* '(0 4 2 5 4 7 5 9 7 11 9 12))&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;(defun scales &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    (&amp;key (start-root 48)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;     (end-root 72)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;     (duration 0.2)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;     (intervals *major-scale-intervals*))&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;  (let ((collection ())&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    (scale-length 0)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    (scale-notes ()))&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    (do ((root start-root (1+ root))&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;     (start-time 0 (+ start-time (* scale-length duration))))&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    ((&gt; root end-root) (reverse collection))&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;      (setf scale-notes (scale &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;             :root root &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;             :intervals intervals&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;             :duration duration &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;             :start-time start-time))&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;      (setf scale-length (length scale-notes))&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;      (setf collection (append collection scale-notes)))))&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;(defun scale (&amp;amp;key (root 60)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;          (amplitude 1.0)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;          (duration 0.2)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;          (start-time 0)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;          (intervals *major-scale-intervals*))&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;  (apply-notes-to-midi-objects (create-scale-list &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;                :root root &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;                :intervals intervals)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;                   :start-time start-time &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;                   :amplitude amplitude &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;                   :duration duration))&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;(defun apply-notes-to-midi-objects &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    (notes &amp;key &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;     (amplitude 1.0) &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;     (duration 0.2)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;     (start-time 0))&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;  (let ((collection ()))&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    (do ((current-note (car notes) (car rest-of-notes))&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;     (rest-of-notes (cdr notes) (cdr rest-of-notes))&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;     (time start-time (+ time duration)))&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    ((null current-note) (reverse collection))&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;      (setf collection (cons (new midi&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;                   :channel 1&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;                   :keynum current-note&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;                   :time time&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;                   :duration duration&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;                   :amplitude amplitude) collection)))))&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;(defun create-scale-list (&amp;amp;key (root 60) (intervals *major-scale-intervals*))&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;  (let ((notes (mapcar #'(lambda (x) (+ root x)) intervals)))&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    (append notes (cdr (reverse notes)))))&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;The initial aim was to just play a scale, but in the end I've ended up with a function &lt;span style="font-family:courier new;"&gt;apply-notes-to-midi-object&lt;/span&gt; (which is poorly named) that will take a list of keynum values and generate midi events for the given notes in sequence.&lt;br /&gt;&lt;br /&gt;All the functions are short and do one thing. On reflecting on them, I am using &lt;span style="font-family:courier new;"&gt;let&lt;/span&gt; variables when I could have probably included them as part of the &lt;span style="font-family:courier new;"&gt;do&lt;/span&gt; loop. I'm happy with what they do, though I might want to add functionality for choosing instruments as well.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;The Aftermath&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I'm very impressed with the way that Lisp promotes interactive development with the REPL. I wish we had something like this for Java development. I enjoyed the ability to modify and almost instantaneously test and see the results of minor tweaks, leading to more experimental ideas and the encouragement of continual improvement. I look forward to experimenting more with a high level expressive language.</content><link rel='alternate' type='text/html' href='http://www.trontos.com/dsouth/blog/2007/06/common-music-pre-opus-1-part-1.html' title='Common Music pre-Opus 1, part 1'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8918867&amp;postID=4775922040411826398' title='0 Comments'/><link rel='replies' type='application/atom+xml' href='http://trontos.com/dsouth/blog/atom.xml' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8918867/posts/default/4775922040411826398'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8918867/posts/default/4775922040411826398'/><author><name>Doug</name><uri>http://www.blogger.com/profile/00713655468090655252</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-8918867.post-3736745111337848204</id><published>2007-06-17T07:37:00.000+10:00</published><updated>2007-06-17T10:26:09.566+10:00</updated><title type='text'>Common Music</title><content type='html'>Within the last fortnight, I've been bitten by the music bug. More specifically the Midi bug. About 4 years ago, I started writing some Java classes for sending Midi events and started playing around with the idea of writing a sequencer. But that didn't last long and when I went searching for the old code, I came up empty handed.&lt;br /&gt;&lt;br /&gt;Have been bitten and not finding my old source code, I started contemplating how I would go about it this time. Since I've been toying around with Lisp, I considered this from that angle. Thankfully, someone has already done all the &lt;a href="http://commonmusic.sourceforge.net/doc/cm.html"&gt;hard work&lt;/a&gt;. And when I say hard work, this just installed out of the box and I was running tutorial code in minutes. Very nicely done.&lt;br /&gt;&lt;br /&gt;Having previous installed and using &lt;a href="http://common-lisp.net/project/slime/"&gt;SLIME&lt;/a&gt;, I was very happy to see that CM plays nicely with SLIME. I followed the tutorial and &amp;lt;bzzzt&amp;gt;, wrong answer. Everything had gone so smoothly and yet I was stymied. So, I dove into the world of &lt;a href="http://en.wikipedia.org/wiki/Emacs_Lisp"&gt;elisp&lt;/a&gt;. With the help of a couple people on #emacs, I'd traced exactly where the problem was (thanks to &lt;span style="font-family:courier new;"&gt;toggle-debug-on-error&lt;/span&gt; and &lt;span style="font-family:courier new;"&gt;message&lt;/span&gt;). With this, I now had the right google search term, which produced a couple of messages that got me thinking about going back to first principles.&lt;br /&gt;&lt;br /&gt;The long and short of it is that my .emacs file before installing CM was:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;(setq inferior-lisp-program "/usr/bin/sbcl")&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;(add-to-list 'load-path "/usr/local/lisp/slime-latest-cvs/")&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;(require 'slime)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;(slime-setup)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;which just sets up SLIME. I took what was suggested by CM and added the bits they had to give me:&lt;br /&gt;&lt;br /&gt;(setq inferior-lisp-program "/usr/bin/sbcl")&lt;br /&gt;(add-to-list 'load-path "/usr/local/lisp/slime-latest-cvs/")&lt;br /&gt;(add-to-list 'load-path "/usr/local/lisp/cm/")&lt;br /&gt;(load "etc/xemacs/cm.el")&lt;br /&gt;(enable-cm-commands)&lt;br /&gt;(require 'slime)&lt;br /&gt;(slime-setup)&lt;br /&gt;&lt;br /&gt;This setup prevents CM from loading (I'm sure there is an obvious reason for this, but I'm way too inexperienced to see it today). The sad thing is that no one else seems to have run into this problem. I'm special because I already had SLIME installed, but CM is more for musos than people like myself, so they'd install CM first then SLIME and wouldn't have a preconceived .emacs file hanging about.&lt;br /&gt;&lt;br /&gt;So I've fixed this by doing only what the documentation suggests:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;(add-to-list 'load-path "/usr/local/lisp/slime-latest-cvs/")&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;(add-to-list 'load-path "/usr/local/lisp/cm/")&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;(load "etc/xemacs/cm.el")&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;(enable-cm-commands)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;and now &lt;span style="font-family: courier new;"&gt;M-cm&lt;/span&gt; works and brings up CM in SLIME. Sadly, SLIME on its own is now undefined, but then I can just use CM for all my SLIME work...</content><link rel='alternate' type='text/html' href='http://www.trontos.com/dsouth/blog/2007/06/common-music.html' title='Common Music'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8918867&amp;postID=3736745111337848204' title='0 Comments'/><link rel='replies' type='application/atom+xml' href='http://trontos.com/dsouth/blog/atom.xml' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8918867/posts/default/3736745111337848204'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8918867/posts/default/3736745111337848204'/><author><name>Doug</name><uri>http://www.blogger.com/profile/00713655468090655252</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-8918867.post-1339819788241724798</id><published>2007-06-04T14:24:00.000+10:00</published><updated>2007-06-16T17:28:53.934+10:00</updated><title type='text'>XP Boot Camp</title><content type='html'>XP is something that takes a lot of discipline. With high levels of discipline you can achieve higher levels of quality, which I believe will return better than proportional results for the effort invested. The hard part for a lot of people can be striving for the level of discipline&lt;br /&gt;&lt;br /&gt;This is something that I've seen lacking in the vast majority of developers (of which I'd include myself). I've also noticed that on &lt;span style="font-weight: bold;"&gt;the&lt;/span&gt; XP mailing list, there was a small discussion recently regarding the exchange of developers between businesses to encourage the growth of teams and developers. I really like the idea, but I can't see it flying well with most businesses.&lt;br /&gt;&lt;br /&gt;But, I do think it would be very beneficial to the XP community and to the businesses that use XP to create an XP Boot Camp. In a nutshell, set up a non-profit group to work for a charitable cause on an open source project. Businesses that wish to improve the skills of their employees would send them to the XP Boot Camp for 4-6 weeks. During this time, they would work with experienced coaches to ensure that they get the full XP experience. Hopefully, this would allow for feedback all around both from the Boot Camp to the instructees and vice versa. And people would be encouraged to come back over the years to help keep their understanding of XP fresh and to allow them to experience new ways of apply the Extreme bits. And I'd hope that they would gain the insight into the level of discipline required and the benefits of the quality that comes from the high levels of discipline.&lt;br /&gt;&lt;br /&gt;I believe and have seen that there can be a big difference between thinking about XP and doing XP. Worse case scenario when you want to get XP boot strapped,  hire a coach who can put your team through an immersion course. It will save you months, if not years not to mention the value you'll get out of your team sooner.</content><link rel='alternate' type='text/html' href='http://www.trontos.com/dsouth/blog/2007/06/xp-boot-camp.html' title='XP Boot Camp'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8918867&amp;postID=1339819788241724798' title='0 Comments'/><link rel='replies' type='application/atom+xml' href='http://trontos.com/dsouth/blog/atom.xml' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8918867/posts/default/1339819788241724798'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8918867/posts/default/1339819788241724798'/><author><name>Doug</name><uri>http://www.blogger.com/profile/00713655468090655252</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-8918867.post-1561017532319704686</id><published>2007-06-04T11:19:00.000+10:00</published><updated>2007-06-04T13:27:32.589+10:00</updated><title type='text'>Quality to go faster</title><content type='html'>Over the weekend, I was watching a report on the Renault Formula One racing factory and something really struck me. From all of the images and video I've seen of Formula One factories and of the garages at races, they are all very clean and very organized. In addition, these people are trying to out perform one another in terms of innovations and technology. Lots of money is at stake. Quality is very important from a competitive point of view and from a safety point of view. With all of the pressure on them to be fast and accurate, they manage to keep their workplace nice and tidy. What struck was the level of quality that was required to allow these teams to develop high quality work in an extremely competitive environment.&lt;br /&gt;&lt;br /&gt;I believe that the more quality that is achieved with a codebase, the more quickly the needs of the business can be achieved with that codebase. I'm not talking about the exterior quality that the users see in the product/service and I'm not saying that the external quality isn't something that is important. I'm talking about the internal quality, the quality of how the code is used to produce the externally seen features.&lt;br /&gt;&lt;br /&gt;As a business, why should you care about internal quality.&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Maintainability - a codebase of high quality will be easy to read, easy to understand and easy to maintain. Additionally, by definition, the codebase should be low on defects. Add this all up and you should find that less resources are needed for maintenance and support.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Flexibility - a codebase of high quality will be a codebase of many simple solutions combined in simple and elegant ways. This leads to loosely coupled code which is independent of its surrounds. This, in turn, leads to a codebase that is easily modified, requiring less time and resources to add features that will return value.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Retention of Developers - a codebase that is easy to maintain and add features to will allow developers to focus on higher order rather than mundane tasks. Developers prefer challenges to routine (that's what the computer if for, after all). Happy developers will be far less likely to leave leading to less staff turn over.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;Unlike Formula One, the pits and the factories aren't as easy to take our sponsors through and demonstrate to them how their money is being spent. I strongly believe that if we could map our codebases to pit areas than a large majority of businesses would be shocked and would demand that action be taken. (Ideally, I believe this is what they should do. What I believe they would do is something completely different...) In the end, I believe that quality is something worth doing from both a business and a technical point of view and that there are great gains to be made in a business by spending the time to constantly improve its quality. The first step is recognizing that is important.</content><link rel='alternate' type='text/html' href='http://www.trontos.com/dsouth/blog/2007/06/quality-to-go-faster.html' title='Quality to go faster'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8918867&amp;postID=1561017532319704686' title='1 Comments'/><link rel='replies' type='application/atom+xml' href='http://trontos.com/dsouth/blog/atom.xml' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8918867/posts/default/1561017532319704686'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8918867/posts/default/1561017532319704686'/><author><name>Doug</name><uri>http://www.blogger.com/profile/00713655468090655252</uri><email>noreply@blogger.com</email></author></entry></feed>