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

<channel>
	<title>Schauderhaft</title>
	<atom:link href="http://blog.schauderhaft.de/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.schauderhaft.de</link>
	<description>Softwaredevelopment, Projectmanagement, Qualitymanagement and all things &#34;schauderhaft&#34;</description>
	<lastBuildDate>Sun, 06 May 2012 12:44:44 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>Where is your Mentor?</title>
		<link>http://blog.schauderhaft.de/2012/05/06/where-is-your-mentor/</link>
		<comments>http://blog.schauderhaft.de/2012/05/06/where-is-your-mentor/#comments</comments>
		<pubDate>Sun, 06 May 2012 12:44:44 +0000</pubDate>
		<dc:creator>Jens Schauder</dc:creator>
				<category><![CDATA[The Rest]]></category>
		<category><![CDATA[mentor]]></category>

		<guid isPermaLink="false">http://blog.schauderhaft.de/?p=1092</guid>
		<description><![CDATA[Back in the days when I had my lack of experience as an excuse to explain my mistakes I was sometimes wondering: &#8220;Wouldn&#8217;t it be nice to have a mentor?&#8221; What I didn&#8217;t realize until a couple months ago was that my mentors were all around me all the time. My cousin who introduced me [...]]]></description>
			<content:encoded><![CDATA[<p>Back in the days when I had my lack of experience as an excuse to explain my mistakes I was sometimes wondering: &#8220;Wouldn&#8217;t it be nice to have a mentor?&#8221;</p>
<p>What I didn&#8217;t realize until a couple months ago was that my mentors were all around me all the time.</p>
<ul>
<li>My cousin who introduced me to computers</li>
<li>A coworker who pointed out the limitations of VB to me</li>
<li>A coworker in California who tought me lots and lots of things about Oracle databases and how to have fun.</li>
<li>My boss(es) nudging me more or less toward project management</li>
<li>A coworker making it very clear to me that there are alternatives to project management</li>
<li>Another coworker who taught me even more about databases</li>
<li>Dozens, no hundreds of people writing blogs for me to read, questions to be answered or answered questions written by me in various forums.</li>
</ul>
<p>Its just that I never realized they were my mentors (nor did they in many cases). By not realizing this I missed out on some greate opportunities to learn much much more, much much faster than I actually did.</p>
<p>So let me be your mentor for a second and give you a little task:</p>
<p>Think for a moment: Who in your vicinity is where you want to be in a couple of years? Who can help you getting there? Whom are you learning from? Whom could you learn from?</p>
<p>Now use my advice and <a href="/2010/11/01/just-ask/">just ask</a> her to become your mentor.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.schauderhaft.de/2012/05/06/where-is-your-mentor/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Challenges in Requirements Analysis: Finding and Understanding the Correct Terms</title>
		<link>http://blog.schauderhaft.de/2012/04/22/challenges-in-requirements-analysis-finding-and-understanding-the-correct-terms/</link>
		<comments>http://blog.schauderhaft.de/2012/04/22/challenges-in-requirements-analysis-finding-and-understanding-the-correct-terms/#comments</comments>
		<pubDate>Sun, 22 Apr 2012 12:18:04 +0000</pubDate>
		<dc:creator>Jens Schauder</dc:creator>
				<category><![CDATA[Softwaredevelopment]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[requirements analysis]]></category>

		<guid isPermaLink="false">http://blog.schauderhaft.de/?p=1081</guid>
		<description><![CDATA[There are lots of things that make requirements analysis difficult. For this article lets focus on one issue: What is a Train? At first sight this looks like a rather simple question and might be answered by having a look at wikipedia: A railway or railroad train is a connected series of vehicles for rail [...]]]></description>
			<content:encoded><![CDATA[<p>There are lots of things that make requirements analysis difficult. For this article lets focus on one issue:</p>
<p><strong>What is a Train?</strong></p>
<p>At first sight this looks like a rather simple question and might be answered by having a look at <a href="http://en.wikipedia.org/wiki/Train">wikipedia</a>:</p>
<blockquote><p>A railway or railroad train is a connected series of vehicles for rail transport that move along a track (permanent way) to transport cargo or passengers from one place to another place.</p></blockquote>
<p>This is pretty much what most of us understand when we talk about trains. But when we talk with experts in the various domains that involve trains we might come along these definitions:</p>
<p>A train is a collection of wagons that is assembled during a given time before departure.</p>
<p>A train is the abstract thing that has a unique number and travels on specified weekdays at a specified time from one station to another.</p>
<p>A train is the thing that has a unique number and travels on a specific date from one station to another.</p>
<p>A train is the thing that at a given date and time arrives at a given station and leaves a couple of minutes later.</p>
<p>&#8230; and many more</p>
<p>Obviously the various possible definitions of the term train are somewhat related but different. Most of the time experts do have precise words to differentiate between these concepts, but since the different definitions are relevant for different groups of experts each expert calls the concept he is dealing with just &#8216;train&#8217;.</p>
<p>So when you try to gather requirements and designing software you must try to identify these different concepts. How would you do that?</p>
<p><strong>Listen carefully</strong>: Often people use additions to a main term in order to differentiate between different concepts. Examples might be: &#8220;train in preparation&#8221;, &#8220;train at a station&#8221;</p>
<p><strong>Look out for contradictions</strong>: Does somebody describe a train as something repeating every week while another one says something happens at departure? They are probably talking about two different kinds of train.</p>
<p><strong>Collect constraints</strong>: What identifies a train uniquely? A number? A date + a number? A date and a track? How does a train relate to a station? 1:1? 1:2? 1:n? Ask the experts for such constraints, ask them if they agree with the constraints identified by others. Don&#8217;t stop when you have one answer, but verify it over and over again. It really sucks when 95% of your users use one definition and 5% use a different one. It sucks even more when you find out about it on deployment day.</p>
<p><strong>Look at the documents and systems in use right now</strong>: Often header for reports or forms (paper or digital) give cues for constraints. But also intensely used comment field sometimes with obscure DSL  like syntax are pointers to a missing concept. The same holds for abused fields. For example when you have a field that contains mostly the number 10, 20, 30, 40, 50 and 60 sometimes the numbers in between and in few cases the value 999 or 998 I am willing to bet that the records are used for at least two different things and boths aren&#8217;t properly modeled as a number.</p>
<p><strong>Find and use the correct terms<strong: Find specific words for each concept used. Don't make these words up, put talk with your domain experts. Tell them that Smith and Jones both use the term train for different things and ask them what the correct term for each concept is. Make sure everybody on the team understands and uses these terms. This topic by the way is well covered in the book <a href="http://www.amazon.de/gp/product/B00794TAUG/ref=as_li_ss_tl?ie=UTF8&#038;tag=schauderhafte-21&#038;linkCode=as2&#038;camp=1638&#038;creative=19454&#038;creativeASIN=B00794TAUG">Domain-Driven Design: Tackling Complexity in the Heart of Software</a><img src="http://www.assoc-amazon.de/e/ir?t=schauderhafte-21&#038;l=as2&#038;o=3&#038;a=B00794TAUG" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" /></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.schauderhaft.de/2012/04/22/challenges-in-requirements-analysis-finding-and-understanding-the-correct-terms/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>TDD, do we really have to do it?</title>
		<link>http://blog.schauderhaft.de/2012/04/15/tdd-do-we-really-have-to-do-it/</link>
		<comments>http://blog.schauderhaft.de/2012/04/15/tdd-do-we-really-have-to-do-it/#comments</comments>
		<pubDate>Sun, 15 Apr 2012 07:48:06 +0000</pubDate>
		<dc:creator>Jens Schauder</dc:creator>
				<category><![CDATA[Softwaredevelopment]]></category>
		<category><![CDATA[science]]></category>
		<category><![CDATA[TDD]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://blog.schauderhaft.de/?p=1049</guid>
		<description><![CDATA[Many really smart people tell us we have to use TDD if we want to create code that is worth a penny. For example take this article about TDD by Uncle Bob (one of the moderate ones). He describes the benefits of TDD in paragraphs like this: If all your code works every minute, how [...]]]></description>
			<content:encoded><![CDATA[<p>Many really smart people tell us we have to use TDD if we want to create code that is worth a penny. For example take <a href="http://butunclebob.com/ArticleS.UncleBob.TheThreeRulesOfTdd">this article about TDD by Uncle Bob</a> (one of the moderate ones). He describes the benefits of TDD in paragraphs like this:</p>
<blockquote><p>If all your code works every minute, how often will you use a debugger? Answer, not very often. It&#8217;s easier to simply hit Ctrl-Z a bunch of times to get the code back to a working state, and then try to write the last minutes worth again. And if you aren&#8217;t debugging very much, how much time will you be saving? How much time do you spend debugging now? How much time do you spend fixing bugs once you&#8217;ve debugged them? What if you could decrease that time by a significant fraction?</p></blockquote>
<p>But the one thing he does not provide is anything close to a proof. He offers his own experience, which might be distorted for all kinds of things. </p>
<p>Yet with a practice so simple (note: I didn&#8217;t write easy) as TDD and so many people advocating it one would like to see some proof of the benefits of TDD. After writing a little piece about <a href="/2012/02/12/where-is-the-science-in-software-development/">opportunities for more research in software development</a> I was recommended this the book: <a href="http://www.amazon.de/gp/product/B004D4YI6G/ref=as_li_ss_tl?ie=UTF8&#038;tag=schauderhafte-21&#038;linkCode=as2&#038;camp=1638&#038;creative=19454&#038;creativeASIN=B004D4YI6G">Making Software: What Really Works, and Why We Believe It</a><img src="http://www.assoc-amazon.de/e/ir?t=schauderhafte-21&#038;l=as2&#038;o=3&#038;a=B004D4YI6G" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />. It is highly recommended for anybody interested in what works and what doesn&#8217;t work in software development. Just be warned it is a little harder to read than <a target="_blank" href="http://www.amazon.de/gp/feature.html/?ie=UTF8&#038;site-redirect=de&#038;tag=schauderhafte-21&#038;linkCode=ur2&#038;docId=1000624893&#038;camp=1638&#038;creative=19454">Harry Potter</a><img src="https://www.assoc-amazon.de/e/ir?t=schauderhafte-21&#038;l=ur2&#038;o=3" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" /></p>
<p>There actually is a chapter about TDD in it. The result: Not a clear win. I&#8217;m not even trying to put the details in here, but the result is basically: Although they tried they couldn&#8217;t prove TDD to be as effective as many people claimed. But they also showed it is not as costly as many people claimed. And I think they mist at least one point: TDD can teach you a lot about software development and software design on the micro level.</p>
<p>So what is the answer to the question in the title: Do we have to do TDD?</p>
<p>Nope, don&#8217;t think so. There are alternatives, like writing your tests after the code. But I recommend TDD to everybody to try it at least for some time. Its a great chance to learn a lot.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.schauderhaft.de/2012/04/15/tdd-do-we-really-have-to-do-it/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Advanced Database Constraints: Don&#8217;t Look for a Second</title>
		<link>http://blog.schauderhaft.de/2012/04/08/advanced-database-constraints-dont-look-for-a-second/</link>
		<comments>http://blog.schauderhaft.de/2012/04/08/advanced-database-constraints-dont-look-for-a-second/#comments</comments>
		<pubDate>Sun, 08 Apr 2012 07:31:28 +0000</pubDate>
		<dc:creator>Jens Schauder</dc:creator>
				<category><![CDATA[Softwaredevelopment]]></category>
		<category><![CDATA[constraints]]></category>
		<category><![CDATA[deferred]]></category>
		<category><![CDATA[sql]]></category>

		<guid isPermaLink="false">http://blog.schauderhaft.de/?p=1062</guid>
		<description><![CDATA[One of the powers of RDBMS as we use them today are constraints. I use unique indexes, not null constraints and foreign keys on a regular basis and if you do any work with RDBMSs you probably do as well. From time to time one comes at a point where you think “it would be [...]]]></description>
			<content:encoded><![CDATA[<p>One of the powers of RDBMS as we use them today are constraints. I use unique indexes, not null constraints and foreign keys on a regular basis and if you do any work with RDBMSs you probably do as well.</p>
<p>From time to time one comes at a point where you think “it would be nice to enforce this with some kind of constraint”, but you can’t. Well maybe you just didn’t try hard enough. This is the second part of the <a href="/2012/03/25/advanced-database-constraints-there-can-be-only-one/">mini series</a> about somewhat special constraints for (Oracle) databases. </p>
<p>Let&#8217;s assume you want to model a system of superheroes an villain. Each superhero has an arch_villain and each villain has an arch superhero. Thats simple, isn&#8217;t it?</p>
<div class="geshi no sql">
<ol>
<li class="li1">
<div class="de1"><span class="kw1">CREATE</span> <span class="kw1">TABLE</span> super_hero <span class="br0">&#40;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; id number<span class="br0">&#40;</span><span class="nu0">10</span><span class="br0">&#41;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; name varchar2<span class="br0">&#40;</span><span class="nu0">200</span><span class="br0">&#41;</span> <span class="kw1">NOT</span> <span class="kw1">NULL</span> <span class="kw1">UNIQUE</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; arch_villain_id number<span class="br0">&#40;</span><span class="nu0">10</span><span class="br0">&#41;</span> <span class="kw1">NOT</span> <span class="kw1">NULL</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; CONSTRAINT super_hero_pk <span class="kw1">PRIMARY</span> <span class="kw1">KEY</span> <span class="br0">&#40;</span>id<span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">CREATE</span> <span class="kw1">TABLE</span> villain &nbsp; <span class="br0">&#40;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; id number<span class="br0">&#40;</span><span class="nu0">10</span><span class="br0">&#41;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; name varchar2<span class="br0">&#40;</span><span class="nu0">200</span><span class="br0">&#41;</span> <span class="kw1">NOT</span> <span class="kw1">NULL</span> <span class="kw1">UNIQUE</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; arch_hero_id number<span class="br0">&#40;</span><span class="nu0">10</span><span class="br0">&#41;</span> <span class="kw1">NOT</span> <span class="kw1">NULL</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; CONSTRAINT villain_pk <span class="kw1">PRIMARY</span> <span class="kw1">KEY</span> <span class="br0">&#40;</span>id<span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">ALTER</span> <span class="kw1">TABLE</span> super_hero</div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">ADD</span> constraint arch_villain_fk</div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">FOREIGN</span> <span class="kw1">KEY</span><span class="br0">&#40;</span>arch_villain_id<span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">REFERENCES</span> villain<span class="br0">&#40;</span>id<span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">ALTER</span> <span class="kw1">TABLE</span> villain</div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">ADD</span> constraint arch_hero_fk</div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">FOREIGN</span> <span class="kw1">KEY</span><span class="br0">&#40;</span>arch_hero_id<span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">REFERENCES</span> super_hero<span class="br0">&#40;</span>id<span class="br0">&#41;</span>;</div>
</li>
</ol>
</div>
<p>Not so fast. Try to insert a row into these tables. It doesn&#8217;t work. Before you can insert the first super hero you have to insert a first villain to serve as a arch villain for our super hero. But this arch villain needs a super hero first for use as arch super hero. A vicious circle.</p>
<p>Looks like we have to drop at least one of our constraints. Actually no. We can make it a deferred constraint like so:</p>
<div class="geshi no sql">
<ol>
<li class="li1">
<div class="de1"><span class="kw1">CREATE</span> <span class="kw1">TABLE</span> super_hero <span class="br0">&#40;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; id number<span class="br0">&#40;</span><span class="nu0">10</span><span class="br0">&#41;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; name varchar2<span class="br0">&#40;</span><span class="nu0">200</span><span class="br0">&#41;</span> <span class="kw1">NOT</span> <span class="kw1">NULL</span> <span class="kw1">UNIQUE</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; arch_villain_id number<span class="br0">&#40;</span><span class="nu0">10</span><span class="br0">&#41;</span> <span class="kw1">NOT</span> <span class="kw1">NULL</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; CONSTRAINT super_hero_pk <span class="kw1">PRIMARY</span> <span class="kw1">KEY</span> <span class="br0">&#40;</span>id<span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">CREATE</span> <span class="kw1">TABLE</span> villain &nbsp; <span class="br0">&#40;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; id number<span class="br0">&#40;</span><span class="nu0">10</span><span class="br0">&#41;</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; name varchar2<span class="br0">&#40;</span><span class="nu0">200</span><span class="br0">&#41;</span> <span class="kw1">NOT</span> <span class="kw1">NULL</span> <span class="kw1">UNIQUE</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; arch_hero_id number<span class="br0">&#40;</span><span class="nu0">10</span><span class="br0">&#41;</span> <span class="kw1">NOT</span> <span class="kw1">NULL</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; CONSTRAINT villain_pk <span class="kw1">PRIMARY</span> <span class="kw1">KEY</span> <span class="br0">&#40;</span>id<span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">ALTER</span> <span class="kw1">TABLE</span> super_hero</div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">ADD</span> constraint arch_villain_fk</div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">FOREIGN</span> <span class="kw1">KEY</span><span class="br0">&#40;</span>arch_villain_id<span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">REFERENCES</span> villain<span class="br0">&#40;</span>id<span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">deferrable initially deferred;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">ALTER</span> <span class="kw1">TABLE</span> villain</div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">ADD</span> constraint arch_hero_fk</div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">FOREIGN</span> <span class="kw1">KEY</span><span class="br0">&#40;</span>arch_hero_id<span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">REFERENCES</span> super_hero<span class="br0">&#40;</span>id<span class="br0">&#41;</span></div>
</li>
<li class="li1">
<div class="de1">deferrable initially deferred;</div>
</li>
</ol>
</div>
<p>Now we can enter our data in a pretty natural way:</p>
<div class="geshi no sql">
<ol>
<li class="li1">
<div class="de1"><span class="kw1">INSERT</span> <span class="kw1">INTO</span> super_hero<span class="br0">&#40;</span>id, name, arch_villain_id<span class="br0">&#41;</span> <span class="kw1">VALUES</span> <span class="br0">&#40;</span><span class="nu0">1</span>, <span class="st0">&#39;Spider-Man&#39;</span>, <span class="nu0">2</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">INSERT</span> <span class="kw1">INTO</span> villain<span class="br0">&#40;</span>id, name, arch_hero_id<span class="br0">&#41;</span> <span class="kw1">VALUES</span><span class="br0">&#40;</span><span class="nu0">2</span>, <span class="st0">&#39;Green Goblin&#39;</span>, <span class="nu0">1</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">commit;</div>
</li>
</ol>
</div>
<p>What happend? Are the constraints still there? Yes they are:</p>
<div class="geshi no sql">
<ol>
<li class="li1">
<div class="de1"><span class="kw1">INSERT</span> <span class="kw1">INTO</span> super_hero<span class="br0">&#40;</span>id, name, arch_villain_id<span class="br0">&#41;</span> <span class="kw1">VALUES</span> <span class="br0">&#40;</span><span class="nu0">1</span>, <span class="st0">&#39;Spider-Man&#39;</span>, <span class="nu0">2</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">INSERT</span> <span class="kw1">INTO</span> villain<span class="br0">&#40;</span>id, name, arch_hero_id<span class="br0">&#41;</span> <span class="kw1">VALUES</span><span class="br0">&#40;</span><span class="nu0">3</span>, <span class="st0">&#39;Green Goblin&#39;</span>, <span class="nu0">1</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1">commit; <span class="co1">&#8211; fails with ORA-02091: transaction rolled back ORA-02291: integrity constraint (USER_1DA56.ARCH_VILLAIN_FK) violated &#8211; parent key not found : commit</span></div>
</li>
</ol>
</div>
<p>But they are only enforced on commit, not after every DML statement like it is done normaly.</p>
<p>Many Java developer know this feature due to a bug in hibernate that causes illegal intermediate inserts/updates. Most database developers know this feature more as a performance tuning tool. When you insert or update millions of rows Oracle has to executes additional statementes in order to verify constraints. This can cost a considerable amount of performance and often can be done much more efficient when one waits until all the data has its final state.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.schauderhaft.de/2012/04/08/advanced-database-constraints-dont-look-for-a-second/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>What Metrics to Use</title>
		<link>http://blog.schauderhaft.de/2012/04/01/what-metrics-to-use/</link>
		<comments>http://blog.schauderhaft.de/2012/04/01/what-metrics-to-use/#comments</comments>
		<pubDate>Sun, 01 Apr 2012 18:04:13 +0000</pubDate>
		<dc:creator>Jens Schauder</dc:creator>
				<category><![CDATA[Quality Management]]></category>
		<category><![CDATA[code analysis]]></category>
		<category><![CDATA[metrics]]></category>
		<category><![CDATA[sonar]]></category>
		<category><![CDATA[test coverage]]></category>

		<guid isPermaLink="false">http://blog.schauderhaft.de/?p=1060</guid>
		<description><![CDATA[When setting up a project with more code than fits one a piece of paper I like to have some code metrics around. The purpose of that metrics is two fold: Identify areas in the code base that need improvement.´ Motivate team members to improve those areas. But what metrics should one use? I tried [...]]]></description>
			<content:encoded><![CDATA[<p>When setting up a project with more code than fits one a piece of paper I like to have some code metrics around.</p>
<p>The purpose of that metrics is two fold:</p>
<ol>
<li>Identify areas in the code base that need improvement.´</li>
<li>Motivate team members to improve those areas.</li>
</ol>
<p>But what metrics should one use? I tried to use <a href="http://www.sonarsource.org/">Sonar</a> but found it to be of very limited use. The problem is that it produces just to many metrics. You can spent hours browsing, slicing and dicing these metrics without really learning anything from it. Once again: Less is more.</p>
<p>I also used <a href="http://erik.doernenburg.com/2008/11/how-toxic-is-your-code/">toxicity</a> and I still like it. But I also learned from the book <a href="http://www.amazon.de/gp/product/B004D4YI6G/ref=as_li_ss_tl?ie=UTF8&#038;tag=schauderhafte-21&#038;linkCode=as2&#038;camp=1638&#038;creative=19454&#038;creativeASIN=B004D4YI6G">Making Software: What Really Works, and Why We Believe It</a><img src="http://www.assoc-amazon.de/e/ir?t=schauderhafte-21&#038;l=as2&#038;o=3&#038;a=B004D4YI6G" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" /> that all these fancy metrics are really pretty much equivalent to lines of code when it comes to predicting faults in your software.</p>
<p>So here is my first code metric I recommend: <strong>Size</strong>. I don&#8217;t think it matters to much what exact measure you use, but you should have a measure of size for the various artifacts in your project. For a typical java project you might end up with:</p>
<ul>
<li>Number of classes per package</li>
<li>Lines of Code per class</li>
<li>Lines of Code per method</li>
</ul>
<p>The second metric I&#8217;d like to see in my projects is <strong>Test Coverage</strong>. I don&#8217;t expect test coverage to be a useful predictor of faults in the software, but writing unit test teaches you a lot about modular design and if you know about modular design and have to write tests for your code I expect this combination to result in the application of modular design. That&#8217;s why I have an eye on test coverage. Oh and good tests might actually help in maintenance. There are tons of different kinds of test coverage metrics. I&#8217;d choose the one that is most difficult to get to 100% and is provided by your tooling. I&#8217;d expect that to be either path or branch coverage.</p>
<p>In the book <a href="http://www.amazon.de/gp/product/B004D4YI6G/ref=as_li_ss_tl?ie=UTF8&#038;tag=schauderhafte-21&#038;linkCode=as2&#038;camp=1638&#038;creative=19454&#038;creativeASIN=B004D4YI6G">Making Software: What Really Works, and Why We Believe It</a><img src="http://www.assoc-amazon.de/e/ir?t=schauderhafte-21&#038;l=as2&#038;o=3&#038;a=B004D4YI6G" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" /> there is a chapter in which metrics are analysed for their ability to predict faults in software. One of the metrics that actually works is the amount of change: If you change a file a lot it is more likely to contain bugs. Therefore I&#8217;d like to have <strong>The Number Of Commits During the last N days</strong> as a code metric. Unfortunately I have no easy way to make that available to a project team, but I assume for now this is just because I haven&#8217;t looked yet.</p>
<p>I think with these three metrics you should be all set for the first purpose I mentioned above.</p>
<p>But what about the motivational part. Is a test coverage of 85% motivating? I don&#8217;t think so. What I found motivating in the past is the visualization of metrics over time. Measure the three metrics mentioned above for every day and make a graph out of it. Display it on the start page of your CI build. I find this part especially nice for systems that aren&#8217;t in a very healthy state as far as code quality is concerned. It is very frustrating to look at the toxicity of your project and thinK: Oh man we have to get rid of 5739 points of toxicity. But when you can change that in: &#8220;Cool while adding this feature I refactored this class and now the toxicity is ten points lower then a week ago it becomes actually motivating. At least for number geeks like me.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.schauderhaft.de/2012/04/01/what-metrics-to-use/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Advanced Database Constraints: There Can Be Only One</title>
		<link>http://blog.schauderhaft.de/2012/03/25/advanced-database-constraints-there-can-be-only-one/</link>
		<comments>http://blog.schauderhaft.de/2012/03/25/advanced-database-constraints-there-can-be-only-one/#comments</comments>
		<pubDate>Sun, 25 Mar 2012 16:17:56 +0000</pubDate>
		<dc:creator>Jens Schauder</dc:creator>
				<category><![CDATA[Softwaredevelopment]]></category>
		<category><![CDATA[constraints]]></category>
		<category><![CDATA[Oracle]]></category>
		<category><![CDATA[sql]]></category>

		<guid isPermaLink="false">http://blog.schauderhaft.de/?p=1004</guid>
		<description><![CDATA[One of the powers of RDBMS as we use them today are constraints. I use unique indexes, not null constraints and foreign keys on a regular basis and if you do any work with RDBMSs you probably do as well. From time to time one comes at a point where you think &#8220;it would be [...]]]></description>
			<content:encoded><![CDATA[<p>One of the powers of <a href="http://en.wikipedia.org/wiki/RDBMS">RDBMS</a> as we use them today are constraints. I use unique indexes, not null constraints and foreign keys on a regular basis and if you do any work with RDBMSs you probably do as well.</p>
<p>From time to time one comes at a point where you think &#8220;it would be nice to enforce this with some kind of constraint&#8221;, but you can&#8217;t. Well maybe you just didn&#8217;t try hard enough. This is the first in a little series of articles pointing out some tricks you can do with database constraints.</p>
<p>I&#8217;ll talk Oracle here since that is what I know best, but many of these things are possible in other systems as well.</p>
<p>Lets assume we have a person table and a hobby table which holds the hobbies of a person:</p>
<div class="geshi no sql">
<ol>
<li class="li1">
<div class="de1"><span class="kw1">CREATE</span> <span class="kw1">TABLE</span> person <span class="br0">&#40;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; id number <span class="kw1">PRIMARY</span> <span class="kw1">KEY</span> <span class="kw1">NOT</span> <span class="kw1">NULL</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; name varchar2<span class="br0">&#40;</span><span class="nu0">200</span><span class="br0">&#41;</span> <span class="kw1">NOT</span> <span class="kw1">NULL</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">CREATE</span> <span class="kw1">TABLE</span> hobby <span class="br0">&#40;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; id number <span class="kw1">PRIMARY</span> <span class="kw1">KEY</span> <span class="kw1">NOT</span> <span class="kw1">NULL</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; person_id number <span class="kw1">REFERENCES</span> person <span class="kw1">NOT</span> <span class="kw1">NULL</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; name varchar2<span class="br0">&#40;</span><span class="nu0">200</span><span class="br0">&#41;</span> <span class="kw1">NOT</span> <span class="kw1">NULL</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="br0">&#41;</span></div>
</li>
</ol>
</div>
<p>Just ignore that the hobby table probably needs some normalization. Now assume you want to flag the favorite hobby of a person and of course there can be only one favorite hobby per person. </p>
<p>You could create an additional table holding that information, linking person entries and hobby entries, with a unique constraint on the person_id. From a theoretical point of view this is the correct normalized way to do it. But it makes you add a complete table when you just need a flag. There is a somewhat denormalized way to do it, which is in cases like this one simpler to use. </p>
<div class="geshi no sql">
<ol>
<li class="li1">
<div class="de1"><span class="kw1">ALTER</span> <span class="kw1">TABLE</span> hobby </div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">ADD</span> &nbsp;is_favorite varchar2<span class="br0">&#40;</span><span class="nu0">1</span><span class="br0">&#41;</span> <span class="kw1">UNIQUE</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">ALTER</span> <span class="kw1">TABLE</span> hobby <span class="kw1">ADD</span> constraint check_is_favorite</div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">CHECK</span> <span class="br0">&#40;</span>is_favorite <span class="sy0">=</span> <span class="st0">&#39;Y&#39;</span><span class="br0">&#41;</span>;</div>
</li>
</ol>
</div>
<p>The idea is to add a <tt>is_favorite</tt> column and make it unique, but also only allow a single value different from <tt>null</tt> using a check constraint. Since <tt>null</tt> values don&#8217;t get indexed you can have as many <tt>null</tt> values in a unique column as you want. This does look probmising, but there is a problem. The <tt>is_favorite</tt> column should only be unique per person, so we have to include the <tt>person_id</tt>. But now all the <tt>null</tt> values get indexed, since a unique key only ignores <tt>null</tt> values when all indexed columns are <tt>null</tt>. So we have to replace the <tt>null</tt> values with something unique. We can do that by creating a function based column which is identical to <tt>is_favorite</tt> for not <tt>null</tt> values and replaces the <tt>null</tt> values with the primary key (which of course is unique by definition). </p>
<div class="geshi no sql">
<ol>
<li class="li1">
<div class="de1"><span class="kw1">ALTER</span> <span class="kw1">TABLE</span> hobby</div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">ADD</span> is_favorite_unique <span class="kw1">AS</span> <span class="br0">&#40;</span>nvl<span class="br0">&#40;</span>is_favorite, id<span class="br0">&#41;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">ALTER</span> <span class="kw1">TABLE</span> hobby <span class="kw1">ADD</span> CONSTRAINT unique_favorite_hobby</div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">UNIQUE</span><span class="br0">&#40;</span>person_id, is_favorite_unique<span class="br0">&#41;</span>;</div>
</li>
</ol>
</div>
<p>If you remove the unique constraint from the is_favorite column you finally have the desired behavior:</p>
<div class="geshi no sql">
<ol>
<li class="li1">
<div class="de1"><span class="kw1">CREATE</span> <span class="kw1">TABLE</span> person <span class="br0">&#40;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; id number <span class="kw1">PRIMARY</span> <span class="kw1">KEY</span> <span class="kw1">NOT</span> <span class="kw1">NULL</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; name varchar2<span class="br0">&#40;</span><span class="nu0">200</span><span class="br0">&#41;</span> <span class="kw1">NOT</span> <span class="kw1">NULL</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">CREATE</span> <span class="kw1">TABLE</span> hobby <span class="br0">&#40;</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; id number <span class="kw1">PRIMARY</span> <span class="kw1">KEY</span> <span class="kw1">NOT</span> <span class="kw1">NULL</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; person_id number <span class="kw1">REFERENCES</span> person <span class="kw1">NOT</span> <span class="kw1">NULL</span>,</div>
</li>
<li class="li1">
<div class="de1">&nbsp; name varchar2<span class="br0">&#40;</span><span class="nu0">200</span><span class="br0">&#41;</span> <span class="kw1">NOT</span> <span class="kw1">NULL</span></div>
</li>
<li class="li1">
<div class="de1">&nbsp; <span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">ALTER</span> <span class="kw1">TABLE</span> hobby </div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">ADD</span> &nbsp;is_favorite varchar2<span class="br0">&#40;</span><span class="nu0">1</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">ALTER</span> <span class="kw1">TABLE</span> hobby <span class="kw1">ADD</span> constraint check_is_favorite</div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">CHECK</span> <span class="br0">&#40;</span>is_favorite <span class="sy0">=</span> <span class="st0">&#39;Y&#39;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">ALTER</span> <span class="kw1">TABLE</span> hobby</div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">ADD</span> is_favorite_unique <span class="kw1">AS</span> <span class="br0">&#40;</span>nvl<span class="br0">&#40;</span>is_favorite, id<span class="br0">&#41;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">ALTER</span> <span class="kw1">TABLE</span> hobby <span class="kw1">ADD</span> CONSTRAINT unique_favorite_hobby</div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">UNIQUE</span><span class="br0">&#40;</span>person_id, is_favorite_unique<span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1">&nbsp;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">INSERT</span> <span class="kw1">INTO</span> person <span class="kw1">VALUES</span> <span class="br0">&#40;</span><span class="nu0">1</span>, <span class="st0">&#39;Jens&#39;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">INSERT</span> <span class="kw1">INTO</span> person <span class="kw1">VALUES</span> <span class="br0">&#40;</span><span class="nu0">2</span>, <span class="st0">&#39;Alfred&#39;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">INSERT</span> <span class="kw1">INTO</span> hobby <span class="br0">&#40;</span>id, person_id, name, is_favorite<span class="br0">&#41;</span> <span class="kw1">VALUES</span> <span class="br0">&#40;</span><span class="nu0">10</span>,<span class="nu0">1</span>, <span class="st0">&#39;coding&#39;</span>, <span class="st0">&#39;Y&#39;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">INSERT</span> <span class="kw1">INTO</span> hobby <span class="br0">&#40;</span>id, person_id, name, is_favorite<span class="br0">&#41;</span> <span class="kw1">VALUES</span> <span class="br0">&#40;</span><span class="nu0">20</span>,<span class="nu0">2</span>, <span class="st0">&#39;soccer&#39;</span>, <span class="kw1">NULL</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">INSERT</span> <span class="kw1">INTO</span> hobby <span class="br0">&#40;</span>id, person_id, name, is_favorite<span class="br0">&#41;</span> <span class="kw1">VALUES</span> <span class="br0">&#40;</span><span class="nu0">21</span>,<span class="nu0">2</span>, <span class="st0">&#39;reading&#39;</span>, <span class="kw1">NULL</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1"><span class="kw1">INSERT</span> <span class="kw1">INTO</span> hobby <span class="br0">&#40;</span>id, person_id, name, is_favorite<span class="br0">&#41;</span> <span class="kw1">VALUES</span> <span class="br0">&#40;</span><span class="nu0">22</span>,<span class="nu0">2</span>, <span class="st0">&#39;swimming&#39;</span>, <span class="st0">&#39;Y&#39;</span><span class="br0">&#41;</span>;</div>
</li>
<li class="li1">
<div class="de1"><span class="co1">&#8211; this fails with a unique exception</span></div>
</li>
<li class="li1">
<div class="de1"><span class="co1">&#8211; insert into hobby (id, person_id, name, is_favorite) values (23,2, &#39;watching highlander&#39;, &#39;Y&#39;);</span></div>
</li>
</ol>
</div>
]]></content:encoded>
			<wfw:commentRss>http://blog.schauderhaft.de/2012/03/25/advanced-database-constraints-there-can-be-only-one/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>SIP-18. Why?</title>
		<link>http://blog.schauderhaft.de/2012/03/18/sip-18-why/</link>
		<comments>http://blog.schauderhaft.de/2012/03/18/sip-18-why/#comments</comments>
		<pubDate>Sun, 18 Mar 2012 17:18:11 +0000</pubDate>
		<dc:creator>Jens Schauder</dc:creator>
				<category><![CDATA[Softwaredevelopment]]></category>
		<category><![CDATA[feature]]></category>
		<category><![CDATA[scala]]></category>
		<category><![CDATA[SIP-18]]></category>

		<guid isPermaLink="false">http://blog.schauderhaft.de/?p=1052</guid>
		<description><![CDATA[SIP-18 is a Scala Improvement Proposal. Its intent is &#8230; well &#8230; to be honest. I don&#8217;t get it. But the plan is to introduce a feature in Scala which would disable some of Scalas features. In order to turn these features back on you would have to import them with statement like these: import [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://docs.scala-lang.org/sips/pending/modularizing-language-features.html">SIP-18</a> is a Scala Improvement Proposal. Its intent is &#8230; well &#8230; to be honest. I don&#8217;t get it. But the plan is to introduce a feature in Scala which would disable some of Scalas features. In order to turn these features back on you would have to import them with statement like these:</p>
<div class="geshi no scala">
<div class="head">import language.macros</div>
<ol>
<li class="li1">
<div class="de1">import language.{structuralTypes, existentials}</div>
</li>
</ol>
</div>
<p>So this feature is rather simple and kind of obvious to understand. But what is its intent? The proposal itself says:</p>
<blockquote><p>The hope is that this will provide a good balance between the wish to provide the most powerful abstraction facilities possible and the wish to control of these features by making their usage more explicit.</p></blockquote>
<p>Smart people say when looking for the real reason for anything one shouldn&#8217;t stop at the first answer to the question &#8220;why?&#8221; but instead ask again: Why does anybody whish to make the usage of these features more explicit?</p>
<p><a href="https://groups.google.com/forum/#!msg/scala-sips/W5CGmauii8A/ddXorbmJpJkJ">Knowledgeable people seem to agree that you can use these features without actually wanting to with quite unfortunate side effects</a>:</p>
<blockquote><p>It&#8217;s quite easy for structural types to creep into a public API unintentionally [..] To give you an idea of the magnitude of the problem, the textual representation of the inferred type was 225kb. Yes, kilobytes.</p></blockquote>
<p>So there is actually good reason for a way disable some features for those that don&#8217;t want punch holes in their feet. We have a problem and we have a solution so everything should be fine, right? I don&#8217;t think so.</p>
<p>Lets look at possible alternative solutions first.</p>
<ol>
<li>code reviews and proper education of developers &#8230; mmh, ok that won&#8217;t work in most cases.</li>
<li>tools separate from the the language. I think Scala has a perfect setup for this. It allows compiler plugin and naive as I am I would think it should be perfectly feasible to write a tool or a compiler plugin that checks for usage of certain features. It would easily enforceable by a continuous integration setup which by now everybody should use who is working on some serious code.</li>
</ol>
<div>Lets look at the consequences of the proposed solution second.</div>
<div>
<ol>
<li>It is another language feature, so it makes the beast that is so difficult to tame for many even more difficult. And it is a bad kind of feature in itself. It uses an existing Feature (Imports) in order to do something completely different than the normal usage does (enabling of features vs. managing of namespaces)</li>
<li>It is zero protection for those not understanding the risk or willing to take it or both, even when they are only the minority of the team (note this is not possible with a compiler plugin or a separate tool used in the CI build)</li>
<li>It makes usage of the existing features even more difficult, because now all the little hints and tips found in the internet fail to mention that from version X on you have to make an import to use a certain feature. I&#8217;m already waiting for the stackoverflow questions &#8220;I want to do Y and do just as described HERE and it doesn&#8217;t work&#8221;</li>
</ol>
</div>
<p>There is a never ending discussion going on if Scala is complex or complicated or difficult. I think this SIP acknowledges this to be true. Which is a good thing (the acknowledgment). After all you don&#8217;t make guns saver be telling everybody these things are harmless.</p>
<p>Martin Odersky,  <a href="http://www.infoq.com/articles/odersky-scala-interview">Scala to stay a lean language</a>:</p>
<blockquote><p>In the future my ambition is to make Scala an smaller language, not a larger one.</p></blockquote>
<p>Why would he want to introduce such a weird feature of dubious value?</p>
<p>As said before: I don&#8217;t get it. Anybody wants to explain it to me in the comments? Serious, it would be welcome.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.schauderhaft.de/2012/03/18/sip-18-why/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>About Estimating</title>
		<link>http://blog.schauderhaft.de/2012/03/04/about-estimating/</link>
		<comments>http://blog.schauderhaft.de/2012/03/04/about-estimating/#comments</comments>
		<pubDate>Sun, 04 Mar 2012 08:46:42 +0000</pubDate>
		<dc:creator>Jens Schauder</dc:creator>
				<category><![CDATA[Management]]></category>
		<category><![CDATA[estimating]]></category>
		<category><![CDATA[feedback]]></category>

		<guid isPermaLink="false">http://blog.schauderhaft.de/?p=1045</guid>
		<description><![CDATA[One of the most difficult tasks in software development is estimating also known as guessing. Here are a couple of thoughts about the topic. Estimates aren&#8217;t Commitments. At least they shouldn&#8217;t. Lets assume you estimate you need 1 hour from your home to the airport, through all formalities and into the plane. Do you leave [...]]]></description>
			<content:encoded><![CDATA[<p>One of the most difficult tasks in software development is estimating also known as guessing. Here are a couple of thoughts about the topic.</p>
<ol>
<li><strong>Estimates aren&#8217;t Commitments</strong>. At least they shouldn&#8217;t. Lets assume you estimate you need 1 hour from your home to the airport, through all formalities and into the plane. Do you leave your house 1 hour before departure of the plane? Probably not. You&#8217;ll add all kinds of buffers and leave your house a lot earlier. Same should apply to any kind of project. If you think it takes 6 months it is a bad idea to promise a delivery date in 6 months. Promise 7, 9 or 12 months, depending how bad it is when you show up late.</li>
<li><strong>Estimates aren&#8217;t measurments</strong>. If you want to build a shelf, you can measure the space you have available, and if you measure properly you can cut the boards according to that measurement and they will fit. If they don&#8217;t it is probably your fault because you didn&#8217;t measure properly. With the tools in your house you might be able to measure size up to a couple meters with an error of about 1/1000 and if you want to measure more precise you just have to invest in better tools and measure more carefully.Not so with software. If you estimate a task to take a day you might be done after a day. Or maybe after 6 hours. Or you give up after 3 days. There is no way to be sure. You can&#8217;t just put more effort in estimating to make it more precise. Tools won&#8217;t help you much. The only thing reducing the margin of error is actually implementing it.</li>
<li><strong>Some basics in statistics</strong>. If you roll a dice once you will score approximately 3.5 points. With a margin of error of about 100%. If you roll the dice 1 million times the average value will be 3.5 with pretty good precision. This is no accident, but pretty strong math. The basic idea is that you can add up indipendent random events and that the relative uncertainty is smaller for the added up events than for each single event. This is good news since if you estimate a project you typically break it down into tasks and estimate each task. Then you add up everything and get your result. Which has a smaller range of error.</li>
<li><strong>The rule above applies does not apply</strong>. It holds only when the events (guesses/estimates) follow a normal distribution and are independent of each other. Neither is true for software estimates. Go figure.</li>
<li><strong>We learn through feedback</strong><br />
It&#8217;s almost impossible to learn anything without getting feedback on how you are doing. Imagine learning chess without anybody ever telling you when you make a bad or even illegal move. You just have a book with the rules and play games against yourself. How likely do you think it is to ever become a respectable chess player? Nil? I think so too. But with estimating we are often in such a situation. When you do waterfall projects you often do estimates for 100s of tasks in one go and only a year later you get the feedback: The sum of your estimates was 20% of. It&#8217;s really hard to learn this way. The situation improves a lot when you follow agile practices, where you typically estimate smaller batches, closer to the time when they are actually performed. This enables you to actually learn how long tasks take.</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://blog.schauderhaft.de/2012/03/04/about-estimating/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>The First Not Carbon Based Sentient Being</title>
		<link>http://blog.schauderhaft.de/2012/02/26/the-first-not-carbon-based-sentient-being/</link>
		<comments>http://blog.schauderhaft.de/2012/02/26/the-first-not-carbon-based-sentient-being/#comments</comments>
		<pubDate>Sun, 26 Feb 2012 08:34:00 +0000</pubDate>
		<dc:creator>Jens Schauder</dc:creator>
				<category><![CDATA[The Rest]]></category>
		<category><![CDATA[AI]]></category>
		<category><![CDATA[internet]]></category>
		<category><![CDATA[philosophy]]></category>

		<guid isPermaLink="false">http://blog.schauderhaft.de/?p=1042</guid>
		<description><![CDATA[With my last blog post I answered to a post of Ted Neward. In that post he also mentioned AI being an interesting topic back then: Artificial Intelligence was one such thing: the search to try and bring computers to a state of human-like sentience drove a lot of interesting ideas and concepts forward, but [...]]]></description>
			<content:encoded><![CDATA[<p>With<a href="/2012/02/19/just-because-its-not-new-doesnt-mean-its-old"> my last blog post</a> I answered to <a href="http://blogs.tedneward.com/2012/01/25/Is+Programming+Less+Exciting+Today.aspx">a post of Ted Neward</a>. In that post he also mentioned AI being an interesting topic back then:</p>
<blockquote><p>Artificial Intelligence was one such thing: the search to try and bring computers to a state of human-like sentience drove a lot of interesting ideas and concepts forward, but over the last decade or two, AI seems to have lost almost all of its luster and momentum</p></blockquote>
<p>I disagree! Maybe AI as a research topic is not as popular any more, but I think it pretty much became omnipresent and accessible for anybody with a little advanced computer skills. It just happened to happen partially in a very different way than anticipated. Lets start with the obvious:</p>
<p>Siri, Google and Wolfram|Alpha are pretty close to passing the turing test and a computer even won a game show for humans. So AI achieved a lot although we still don&#8217;t have humanoid robots in our homes and we probably never will.</p>
<p>But consider this: Imagine a blob of green jelly which sits embedded in the top of an anthill. It produces a smelly goo which the ants love and when an ant nibbles of the goo the green jelly absorbs some of the body fluids of the ant.</p>
<p>One day a neighbouring ant population approaches the ant hill threatening the ants. The ants in distress consume a lot of the smelly goo in order to sooth their stress. Suddenly the green jelly starts to spray a weak acid at the foreign ants until those retreat.</p>
<p>Question: Based on this observation, would you consider the green jelly a living being? If so tell me what is the difference between the green jelly, the friendly ants and the foreign ants on one hand and the Internet, the social media community and the politicians in favor of SOPA and PIPA?</p>
<p>Many scientists searching for extra terrestrial life seem to be quite sure that when they see foreign life forms they&#8217;ll recognize them as such. I think they missed one right under their nose. Just because it is so huge it spans a complete planet and because the role of bacteria inside the body of mammals is played by mammals inside the Internet.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.schauderhaft.de/2012/02/26/the-first-not-carbon-based-sentient-being/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Just because its Not New doesn&#8217;t mean its Old</title>
		<link>http://blog.schauderhaft.de/2012/02/19/just-because-its-not-new-doesnt-mean-its-old/</link>
		<comments>http://blog.schauderhaft.de/2012/02/19/just-because-its-not-new-doesnt-mean-its-old/#comments</comments>
		<pubDate>Sun, 19 Feb 2012 15:18:18 +0000</pubDate>
		<dc:creator>Jens Schauder</dc:creator>
				<category><![CDATA[The Rest]]></category>
		<category><![CDATA[change]]></category>
		<category><![CDATA[functional programming]]></category>
		<category><![CDATA[new]]></category>
		<category><![CDATA[old]]></category>
		<category><![CDATA[ubiquitious computing]]></category>

		<guid isPermaLink="false">http://blog.schauderhaft.de/?p=1039</guid>
		<description><![CDATA[Ted Neward wrote a piece in which he complains about not seeing anything new and exciting in the IT industry and ends with a question: If you’ve been programming for twenty years, what about the industry today gets your blood moving and your mind sharpened? So if you count my first experiments with a clunky [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://blogs.tedneward.com/2012/01/25/Is+Programming+Less+Exciting+Today.aspx">Ted Neward wrote a piece</a> in which he complains about not seeing anything new and exciting in the IT industry and ends with a question: If you’ve been programming for twenty years, what about the industry today gets your blood moving and your mind sharpened?</p>
<p>So if you count my first experiments with a clunky programmable calculator and my dabbling with an Apple II I do qualify. So here is my answer.</p>
<p>Lets start with a general note: the complaint that their is nothing new is old in it self. I remember the complains when Java started of: &#8220;Oh we already have C++/SmallTalk there is nothing new in it&#8221; or my boss back than when he finally got the basics of html and http straight: &#8220;Oh, its just a fancy terminal!&#8221;</p>
<p>But just because a topic is not new doesn&#8217;t mean its Old.</p>
<p>For me one such topic is functional programming. I learned abut functional programming about 15 years ago (and it was old back than). I found it to be cool, hardly grasped the very basics and than found out that while the way of programming was cool, the performance was abysmal (which might have been due to my lack of understanding). And I thought: &#8220;Now it would be cool if some time I could actually use this kind of stuff&#8221;. Today we have Scala (or F# if you prefer) which allows you to use these concepts in nice languages and integrate it with your more conservative main stream languages like Java or C#. Make no mistake: these languages won&#8217;t save the industry, but they allow me to explore concepts that might be older than the first computer, but are new and interesting to me.</p>
<p>I have a long list of books and paper a want to read and undstand. Its new stuff to learn and to put to good use. It would only get better if someone would be paying me for this.</p>
<p>The other thing is the ubiquity of computing power and internet connectivity. As it has been all the time the interesting challenge is not so much to write an application, but to come up with interesting ideas for applications. With an interesting idea you can easily reach hundreds or even thousands of potential users. This is awesome. Yeah it&#8217;s true there is nothing that is really new. But the scale of availability changed and continues to change.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.schauderhaft.de/2012/02/19/just-because-its-not-new-doesnt-mean-its-old/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

