<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://agile.codebetter.com/utility/FeedStylesheets/atom.xsl" media="screen"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><title type="html">Karl Seguin</title><subtitle type="html">.NET From Ottawa, Ontario</subtitle><id>http://agile.codebetter.com/blogs/karlseguin/atom.aspx</id><link rel="alternate" type="text/html" href="http://agile.codebetter.com/blogs/karlseguin/default.aspx" /><link rel="self" type="application/atom+xml" href="http://agile.codebetter.com/blogs/karlseguin/atom.aspx" /><generator uri="http://communityserver.org" version="3.0.20416.853">Community Server</generator><updated>2008-06-24T21:53:00Z</updated><entry><title>And we're off...</title><link rel="alternate" type="text/html" href="http://agile.codebetter.com/blogs/karlseguin/archive/2008/08/21/and-we-re-off.aspx" /><id>http://agile.codebetter.com/blogs/karlseguin/archive/2008/08/21/and-we-re-off.aspx</id><published>2008-08-21T17:25:00Z</published><updated>2008-08-21T17:25:00Z</updated><content type="html">&lt;p&gt;Yesterday was my last day at Fuel. It was a hard decision, but one I felt was necessary in order to grow. 
&lt;p&gt;I&amp;#39;m heading back into more enterprise-type of work. I&amp;#39;ll essentially be building management systems and services for emergency-room medical equipment. Our teams portion of the work isn&amp;#39;t as critical as the medical devices themselves, but there&amp;#39;s still an extremely high need for quality.&lt;/p&gt;
&lt;p&gt;From my observations, our field suffers badly from high turnover. Part of that is the economic flux in software development - I think most companies are still grappling to figure out how much a software developer is actually worth to them with respect to an open market. A major problem is how deceivingly simple it is to write software - but how difficult it is to write good software. A young company can start off hiring a group of junior developers at $40K (the going rate in Ottawa as far as I can tell), but as soon as jobs starts to get bigger and expectations greater, they seem unable to make that jump to $80K. We can get 2 programmers for that price - they reason. Of course, as has been &lt;a href="http://haacked.com/archive/2007/06/25/understanding-productivity-differences-between-developers.aspx"&gt;shown numerous times&lt;/a&gt; before (don&amp;#39;t managers read these things?!), top programmers are unbelievably cheap with respect to productivity. &lt;/p&gt;
&lt;p&gt;We generally learn from our failures and success, and by being exposed to a variety of programs and fellow programmers. Stay at one place for too long, and you get really good at doing one thing, but opportunities to learn become few and far apart. I think good developers start to thirst for failure - or at least the risk of failure. I&amp;#39;m not taking about the failure that comes from an unreasonable deadline either, but from true problem solving.&lt;/p&gt;
&lt;p&gt;Which of course leads to another big reason I see developers leaving their jobs - they want to do things differently. The most drastic example is the move to Agile methodologies. It&amp;#39;s easy to get caught up in the Agile-hype - in large part because a lot of it is common sense - but the reality is that most companies aren&amp;#39;t ready or capable of doing such huge transition. It&amp;#39;s far easier to change companies than to try to change a company.&lt;/p&gt;
&lt;p&gt;I think all of these problems can be summed up by companies not understanding software development or developers. Some companies &lt;a href="http://gizmodo.com/5025980/sony-knows-what-went-wrong-with-the-ps3http:/gizmodo.com/5025980/sony-knows-what-went-wrong-with-the-ps3"&gt;don&amp;#39;t even realize they are in the software business&lt;/a&gt;...yikes!&lt;/p&gt;
&lt;p&gt;People often say the grass is greener on the other side. But sometimes it really is greener on the other side. I guess we&amp;#39;ll soon find out.&lt;/p&gt;&lt;img src="http://agile.codebetter.com/aggbug.aspx?PostID=182163" width="1" height="1"&gt;</content><author><name>karl</name><uri>http://agile.codebetter.com/members/karl.aspx</uri></author></entry><entry><title>Custom ASP.NET Page Tracing</title><link rel="alternate" type="text/html" href="http://agile.codebetter.com/blogs/karlseguin/archive/2008/08/15/custom-asp-net-page-tracing.aspx" /><id>http://agile.codebetter.com/blogs/karlseguin/archive/2008/08/15/custom-asp-net-page-tracing.aspx</id><published>2008-08-15T15:13:00Z</published><updated>2008-08-15T15:13:00Z</updated><content type="html">&lt;p&gt;Starting a new large-scale project with an ASP.NET front-end, I wanted to add a mechanism to get constant feedback about what my app was doing. Something similar to the built-in tracing mechanism, but far more lightweight. &amp;lt;%@Page trace=&amp;quot;true&amp;quot;...%&amp;gt; is great for specific cases, but it probably isn&amp;#39;t something you want to leave on all the time while developer – and even if you do, there&amp;#39;s so much noise you might miss out on those vital pieces of information.&lt;/p&gt;
&lt;p&gt;So after googling around for a good solution and being surprised that I couldn&amp;#39;t find anything, I decided to write my own. I can&amp;#39;t help but think that there&amp;#39;s a well known solution that everyone (but me) uses, so if there is, please tell me! Otherwise here are the very simple steps to reproduce what I have so far.&lt;/p&gt;
&lt;p&gt;The approach is simple: store log messages in a List within then HttpContext, and dump it to the page. First, we start off with the class that&amp;#39;ll hold each trace message. Within this class we&amp;#39;ll hold the actual message, a type (log, debug, error), the elapsed time in milliseconds from the first logged message and the delta in milliseconds from the previous message:&lt;/p&gt;&lt;pre class="c-sharp" name="code"&gt;public class TracerItem
{
   public TracerItemType Type { get; set; }
   public DateTime Dated { get; set; }
   public string Message { get; set; }
   public int Delta { get; set; }
   public int Elapsed { get; set; }

   public TracerItem() {}

   public TracerItem(DateTime dated, TracerItemType type, string message, int elapsed, int delta)
   {
      Dated = dated;
      Type = type;
      Message = message;
      Elapsed = elapsed;
      Delta = delta;
   }
}

public enum TracerItemType
{
   Info = 1,
   Debug = 2,
   Error = 3,
}
&lt;/pre&gt;
&lt;p&gt;There&amp;#39;s really nothing to explain there. Next, we&amp;#39;ll create our static Tracer class, which defined the very important &lt;em&gt;Log&lt;/em&gt; method:&lt;/p&gt;&lt;pre class="c-sharp" name="code"&gt;public static class Tracer
{
   public static List&amp;lt;TracerItem&amp;gt; GetLogs()
   {
      var items = (List&amp;lt;TracerItem&amp;gt;) HttpContext.Current.Items[&amp;quot;__tracer&amp;quot;];
      if (items == null)
      {
         items = new List&amp;lt;TracerItem&amp;gt;();
         HttpContext.Current.Items[&amp;quot;__tracer&amp;quot;] = items;
      }
      return items;
   }
   public static void Log(string message, params object[] arguments)
   {
#if TRACER
      Log(message, TracerType.Info, arguments);
#endif
   }
   public static void Log(string message, TracerItemType type, params object[] arguments)
   {
#if TRACER
      var now = DateTime.Now;
      var items = GetLogs();
      var delta = items.Count == 0 ? 0 : (int)now.Subtract(items[items.Count - 1].Dated).TotalMilliseconds;
      var elasped = items.Count == 0 ? delta : items[items.Count - 1].Elapsed + delta;
      items.Add(new TracerItem(now, type, string.Format(message, arguments), elasped, delta));
#endif
   }
}
&lt;/pre&gt;
&lt;p&gt;The &lt;em&gt;GetLogs&lt;/em&gt; method initializes and gets our list of trace messages (this method isn&amp;#39;t thread-safe). Notice that I use a preprocessor directive within the &lt;em&gt;Log&lt;/em&gt; methods. According to &lt;a href="http://www.codeproject.com/KB/dotnet/JITOptimizations.aspx"&gt;this codeproject article&lt;/a&gt;, the JIT compiler will optimize out empty methods. This means that if we don&amp;#39;t define the TRACER symbol our log code won&amp;#39;t have any impact on performance (it also means that you need to define the TRACER symbol for it to work).&lt;/p&gt;
&lt;p&gt;Next, we can use our classes to actually log events. For example, we might want to trace a specific cache miss:&lt;/p&gt;&lt;pre class="c-sharp" name="code"&gt;var user = (User) Cache.Get(string.Format(&amp;quot;userbyid_{0}&amp;quot;, id));
if (user == null)
{
  Tracer.Log(&amp;quot;Cache miss =&amp;gt; user by id {0}&amp;quot;, id);
  //get the user
}
return user;
&lt;/pre&gt;
&lt;p&gt;The only thing left to do is display the actual content. You&amp;#39;ll probably want to change this to fit your site, but this is what I did within a UserControl for an ASP.NET MVC site (loaded via &lt;em&gt;RenderUserControl&lt;/em&gt; from my master):&lt;/p&gt;&lt;pre class="html" name="code"&gt;&amp;lt;% var items = Tracer.GetLogs(); %&amp;gt;
&amp;lt;div id=&amp;quot;tracer&amp;quot;&amp;gt;
   &amp;lt;div class=&amp;quot;item header&amp;quot;&amp;gt;
      &amp;lt;div class=&amp;quot;index&amp;quot;&amp;gt;#&amp;lt;/div&amp;gt;
      &amp;lt;div class=&amp;quot;elapsed&amp;quot;&amp;gt;elapsed&amp;lt;/div&amp;gt;
      &amp;lt;div class=&amp;quot;delta&amp;quot;&amp;gt;delta&amp;lt;/div&amp;gt;
      &amp;lt;div class=&amp;quot;message&amp;quot;&amp;gt;message&amp;lt;/div&amp;gt;
   &amp;lt;/div&amp;gt;
   &amp;lt;% for(int count = 0; count &amp;lt; items.Count; ++count) { %&amp;gt;
   &amp;lt;div class=&amp;quot;item &amp;lt;%=items[count].Type %&amp;gt;&amp;quot;&amp;gt;
      &amp;lt;div class=&amp;quot;index&amp;quot;&amp;gt;&amp;lt;%= count+1 %&amp;gt;&amp;lt;/div&amp;gt;
      &amp;lt;div class=&amp;quot;elapsed&amp;quot;&amp;gt;&amp;lt;%= items[count].Elapsed %&amp;gt;ms&amp;lt;/div&amp;gt;
      &amp;lt;div class=&amp;quot;delta&amp;quot;&amp;gt;&amp;lt;%= items[count].Delta %&amp;gt;ms&amp;lt;/div&amp;gt;
      &amp;lt;div class=&amp;quot;message&amp;quot;&amp;gt;&amp;lt;%= items[count].Message %&amp;gt;&amp;lt;/div&amp;gt;
   &amp;lt;/div&amp;gt;
   &amp;lt;% } %&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/pre&gt;
&lt;p&gt;Along with the accompanying CSS:&lt;/p&gt;&lt;pre class="css" name="code"&gt;#tracer{width:1000px;margin:0 auto;padding:10px;}
#tracer .item {clear:both;}
#tracer .header{font-weight:bold;}
#tracer .item div{float:left;text-align:center;}
#tracer .Info{color:#888;}
#tracer .Debug{color:#2B2;}
#tracer .Error{color:#B22;}
#tracer .item div.index{width:20px;}
#tracer .item div.delta{width:90px;}
#tracer .item div.elapsed{width:90px;}
&lt;/pre&gt;
&lt;p&gt;The whole thing is rendered on top of my header, so I always see what&amp;#39;s going on. I am interested in expanding all of this into a stand-alone library. I also want to figure out how to hook into NHibernate&amp;#39;s logging and add an &amp;quot;NHibernate&amp;quot; tab so you can see all of the SQL being executed.&lt;/p&gt;&lt;img src="http://agile.codebetter.com/aggbug.aspx?PostID=181995" width="1" height="1"&gt;</content><author><name>karl</name><uri>http://agile.codebetter.com/members/karl.aspx</uri></author></entry><entry><title>What's in a Title?</title><link rel="alternate" type="text/html" href="http://agile.codebetter.com/blogs/karlseguin/archive/2008/08/14/what-s-in-a-title.aspx" /><id>http://agile.codebetter.com/blogs/karlseguin/archive/2008/08/14/what-s-in-a-title.aspx</id><published>2008-08-14T15:39:00Z</published><updated>2008-08-14T15:39:00Z</updated><content type="html">&lt;p&gt;The&amp;nbsp;relative hype around the &lt;a class="" href="http://codebetter.com/blogs/karlseguin/archive/2008/06/24/foundations-of-programming-ebook.aspx"&gt;Foundation ebook&lt;/a&gt; has been pretty fun.&amp;nbsp;Today I noticed a very detailed (and positive) &lt;a class="" href="http://accidentaltechnologist.com/book-reviews/book-review-foundations-of-programming-by-karl-seguin/"&gt;review of the book&lt;/a&gt;. Which is, of course, flattering.&lt;/p&gt;
&lt;p&gt;If there&amp;#39;s one thing a few people don&amp;#39;t care for though, it&amp;#39;s the title. They don&amp;#39;t feel that it properly captures the spirit of the book, or that it isn&amp;#39;t as marketable as it could be. I think if this was a &amp;quot;real&amp;quot; book, the publisher would have insisted on something&amp;nbsp;different - likely with the words &amp;quot;ALT.NET&amp;quot; in big print.&lt;/p&gt;
&lt;p&gt;However, given that it wasn&amp;#39;t commercial, I had the luxury of being a little cleverer. The point, which I think most people get, is that this stuff *IS* fundamental. If enterprise developers think &amp;quot;fundamentals&amp;quot; mean if-statements, recursions and hash algorithm, than we&amp;#39;re in trouble. IoC might not be what they teach in school - but it should be. Or at least it should be the first thing you teach yourself.&amp;nbsp;It reminds me of the funny pro-Google quote: &lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;quot;Google uses Bayesian filtering the way Microsoft uses the if statement&amp;quot;&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;If I had to do it again though, I&amp;#39;d probably change the name. My ego can&amp;#39;t stand knowing I might have gotten more praise with a better title.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;img src="http://agile.codebetter.com/aggbug.aspx?PostID=181931" width="1" height="1"&gt;</content><author><name>karl</name><uri>http://agile.codebetter.com/members/karl.aspx</uri></author><category term="Foundations" scheme="http://agile.codebetter.com/blogs/karlseguin/archive/tags/Foundations/default.aspx" /></entry><entry><title>Got Shoes?</title><link rel="alternate" type="text/html" href="http://agile.codebetter.com/blogs/karlseguin/archive/2008/08/13/got-shoes.aspx" /><id>http://agile.codebetter.com/blogs/karlseguin/archive/2008/08/13/got-shoes.aspx</id><published>2008-08-13T12:36:00Z</published><updated>2008-08-13T12:36:00Z</updated><content type="html">&lt;p&gt;An article I wrote for DotNetSlackers on Ruby Shoes &lt;a class="" href="http://dotnetslackers.com/articles/ruby/Got-Shoes.aspx"&gt;just got published&lt;/a&gt;. Shoes is a little framework a colleague turned me onto - it&amp;#39;s for building cross platform desktop applications on Ruby. I&amp;#39;m not sure its quite ready for prime time, but I do think its a far better way to learn Ruby with respect to something like Rails. Rails is just too complicated and leaks too much to serve as a good learning tool.&lt;/p&gt;
&lt;p&gt;Shoes also has a &lt;a class="" href="http://hackety.org/press/"&gt;crazy manual&lt;/a&gt; that&amp;#39;s completely out there. It almost reads like a bed time story (the first 20 pages are pretty fluff though and can easily be skipped) yet still manages to act as a good introduction and reference manual. Its comparing apples to oranges, but the Shoes manual is now my &lt;span style="FONT-SIZE:10pt;LINE-HEIGHT:115%;FONT-FAMILY:&amp;#39;Arial&amp;#39;,&amp;#39;sans-serif&amp;#39;;mso-fareast-font-family:Calibri;mso-fareast-theme-font:minor-latin;mso-ansi-language:EN-US;mso-fareast-language:EN-US;mso-bidi-language:AR-SA;"&gt;favorite &lt;/span&gt;programming reference (overtaking &lt;a class="" href="http://en.wikipedia.org/wiki/The_C_Programming_Language_(book)"&gt;The C Programming Language&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;Oh, and since we&amp;#39;re talking about programming books, the &lt;a class="" href="http://www.amazon.com/Compilers-Principles-Techniques-Alfred-Aho/dp/0201100886"&gt;Dragon Book&lt;/a&gt; has always been very very low on my list...&lt;/p&gt;&lt;img src="http://agile.codebetter.com/aggbug.aspx?PostID=181870" width="1" height="1"&gt;</content><author><name>karl</name><uri>http://agile.codebetter.com/members/karl.aspx</uri></author></entry><entry><title>Back to Basics: LinkedLists</title><link rel="alternate" type="text/html" href="http://agile.codebetter.com/blogs/karlseguin/archive/2008/08/04/back-to-basics-linkedlists.aspx" /><id>http://agile.codebetter.com/blogs/karlseguin/archive/2008/08/04/back-to-basics-linkedlists.aspx</id><published>2008-08-04T18:55:00Z</published><updated>2008-08-04T18:55:00Z</updated><content type="html">&lt;p&gt;I tend to subscribe to the belief that programmers with some C background are typically better off than those without. This is largely because C is far less abstract from the underlying O/S and hardware than languages like C# or Java – specifically the memory model. This kind of knowledge is just handy to have – even for day to day programming.&lt;/p&gt;
&lt;p&gt;I&amp;#39;ve covered fundamental memory topics before, including &lt;a href="http://codebetter.com/blogs/karlseguin/archive/2008/04/27/foundations-of-programming-pt-7-back-to-basics-memory.aspx"&gt;chapter 7&lt;/a&gt; of the Foundation series (&lt;a href="http://codebetter.com/blogs/karlseguin/archive/2008/06/24/foundations-of-programming-ebook.aspx"&gt;free ebook&lt;/a&gt;) as well as with the &lt;a href="http://codebetter.com/blogs/karlseguin/archive/2008/05/06/what-arrays-and-pointers-have-in-common-or-why-arrays-start-at-zero.aspx"&gt;arrays are just fancy pointers&lt;/a&gt; post. It&amp;#39;s time to put some of that information to quasi-practical use. &lt;/p&gt;
&lt;p&gt;One of the first real programming classes I had dealt with data structures. Technically all the primitive type you deal with are simple data structures - a System.Int32 is a data structure capable of holding a 4 byte value representing an integer. What I want to talk about though are slightly more complex data structures – Arrays, Linked Lists, HashTables and Binary Trees (maybe). I think it&amp;#39;s great that .NET and Java come loaded with a bunch of data structures. While you can probably get away without ever knowing how they really work, there might be instances where it&amp;#39;d be useful to know how things work under the hood – besides, I think this is just really fun stuff to mess around with.&lt;/p&gt;
&lt;h3&gt;Arrays&lt;/h3&gt;
&lt;p&gt;We&amp;#39;ve already covered arrays &lt;a href="http://codebetter.com/blogs/karlseguin/archive/2008/05/06/what-arrays-and-pointers-have-in-common-or-why-arrays-start-at-zero.aspx"&gt;in depth&lt;/a&gt;. In case you forgot, the most important point to know is that arrays are cut up from a contiguous block of memory. It&amp;#39;s this fact that lets them be indexed speedily using simple pointer arithmetic. If you want to access the 4th array element (index 3), you simply need take your pointer, which is pointing at the start of the array, and increment its memory location by 3 times the size of the type in the array. This explains why an array&amp;#39;s dimension needs to be defined as soon as you declare it. It also explains why you can&amp;#39;t simply expand the size of an array – there&amp;#39;s a good chance that the memory directly next to the array is being taken by something else. The only way to grow an array is to reallocate a larger chunk of contiguous memory and copy the old array into the new one. This is exactly the strategy employed by many .NET classes –including the StringBuilder and ArrayList (if you&amp;#39;re interested, open up &lt;a href="http://www.aisto.com/roeder/dotnet/"&gt;Reflector&lt;/a&gt;, and look at the Capacity property on the ArrayList class).&lt;/p&gt;
&lt;h3&gt;Linked Lists&lt;/h3&gt;
&lt;p&gt;The fact that .NET&amp;#39;s ArrayLists take care of this automatically (and rather efficiently) is pretty impressive. In school though, for reasons I&amp;#39;ll guess at later, we didn&amp;#39;t build our own ArrayList, but rather built well-known LinkedLists. As of .NET 2.0 there&amp;#39;s actually a built-in generic LinkedList (Java has had one for a while as far as I know). In most situations you&amp;#39;ll want to use an ArrayList, but LinkedList do serve a unique purpose – and again, I just think it&amp;#39;s good stuff to know as it illustrates how memory works. So, let&amp;#39;s take a look at how to build a LinkedList in C#. We&amp;#39;ll keep it basic, and won&amp;#39;t worry about implementing typical collection interfaces (IEnumerable). There&amp;#39;s already a working LinkedList, we just want to explore the data structure to get an even greater understanding of programming.&lt;/p&gt;
&lt;h3&gt;What Are Linked List?&lt;/h3&gt;
&lt;p&gt;If an array can be defined as a data structure based on a contiguous chunk of memory (which is synonymous with fixed-size), then a LinkedList should be defined as a data structure based on dispersed chunks of memory. As such, LinkedLists can grow to unlimited sizes (only limited by available memory). The fundamental aspect of a LinkedList is that each element within the list points to the next element in the list. This is necessary since items aren&amp;#39;t placed one after the other and simple pointer arithmetic&amp;#39;s won&amp;#39;t work - you can&amp;#39;t just do pointer + sizeof(int) to figure out where the next element is - it could be anywhere!&lt;/p&gt;
&lt;h3&gt;How do we do it?&lt;/h3&gt;
&lt;p&gt;Building a linked list is pretty simple. We&amp;#39;ll need a generic LinkedList class which will expose our Add and Remove method (and Find and whatever else we want), as well as a LinkedListItem class, which will wrap the added item and include a reference to the next item.&lt;/p&gt;
&lt;p&gt;Here&amp;#39;s a memory representation of what it&amp;#39;ll look like:&lt;/p&gt;&lt;img height="124" alt="Linked List memory 1" src="http://www.thecodewiki.com/codebetter/linkedlist/linkedlist1.gif" width="564" /&gt; 
&lt;p&gt;Notice that our containing LinkedList class has a reference to our first item within the linked list. This is necessary otherwise we&amp;#39;d have no point of access to any of the items.&lt;/p&gt;
&lt;h3&gt;LinkedList v1&lt;/h3&gt;
&lt;p&gt;For the first version we&amp;#39;ll focus on getting the core components - it won&amp;#39;t be able to do anything, but it will set the groundwork for v2.&lt;/p&gt;&lt;pre class="c-sharp" name="code"&gt;public class LinkedList&amp;lt;T&amp;gt;
{
   private LinkedListItem _first;

   public LinkedList(){}
   public LinkedList(T firstItem)
   {
      _first = new LinkedListItem(firstItem);
   }

   private class LinkedListItem
   {
      public readonly T Item;
      public LinkedListItem Next;

      public LinkedListItem(T item)
      {
         Item = item;
      }
   }
}&lt;/pre&gt;
&lt;p&gt;All we can do with this code is instantiated a new version of the LinkedList class and pass in the first element - we can&amp;#39;t add more items, delete items or retrieve them. However, it does illustrate the purpose of the LinkedListItem class as a wrapper.&lt;/p&gt;
&lt;h3&gt;LinkedList v2&lt;/h3&gt;
&lt;p&gt;For this version of our list we&amp;#39;ll add the ability to add new items to the list by adding two methods. We need an Add method to actually add a new element to our list, but we also need a method to find the last element of our list.&lt;/p&gt;&lt;pre class="c-sharp" name="code"&gt;public void Add(T itemToAdd)
{
   if (_first == null)
   {
      _first = new LinkedListItem(itemToAdd);
      return;
   }
   LinkedListItem last = FindLastItem();         
   last.Next = new LinkedListItem(itemToAdd);
}

private LinkedListItem FindLastItem()
{
   if (_first == null)
   {
      return null;
   }
   LinkedListItem item = _first;
   while (item.Next != null)
   {
      item = item.Next;
   }
   return item;
}&lt;/pre&gt;
&lt;p&gt;There&amp;#39;s a very common pattern with LinkedList - walking through the elements. To find the last entry - the one where Next is null, we need to go through each item. We can&amp;#39;t just index a spot and jump to it.&lt;/p&gt;
&lt;h3&gt;LinkedList v3&lt;/h3&gt;
&lt;p&gt;You wouldn&amp;#39;t know it from the above code, but one of the things LinkedList excel at is speedily inserting records. In fact, high insert/retrieval ration is probably the only good reason to use them on a modern system. They way we&amp;#39;ve coded it now, inserts are actually a pretty slow linear operation - the longer the list gets, the longer it takes to find the last element. However, with the simple addition of a reference to the Last item we can make insertion a constant and very fast operation. Here&amp;#39;s a visual representation of the memory for our improved LinkedList:&lt;/p&gt;&lt;img height="131" alt="Linked List memory 2" src="http://www.thecodewiki.com/codebetter/linkedlist/linkedlist2.gif" width="565" /&gt; 
&lt;p&gt;Here&amp;#39;s the code (LinkedListItem hasn&amp;#39;t changed, so it&amp;#39;s been left out):&lt;/p&gt;&lt;pre class="c-sharp" name="code"&gt;public class LinkedList&amp;lt;T&amp;gt;
{
   private LinkedListItem _first;
   private LinkedListItem _last;

   public LinkedList(){}
   public LinkedList(T firstItem)
   {
    _first = new LinkedListItem(firstItem);
    _last = _first;
   }
   public void Add(T itemToAdd)
   {
      if (_first == null)
      {
         _first = new LinkedListItem(itemToAdd);
         _last = _first;
         return;
      }         
      _last.Next = new LinkedListItem(itemToAdd);
      _last = _last.Next;
   }
   private class LinkedListItem{...}
}
&lt;/pre&gt;
&lt;h3&gt;Why LinkedLists?&lt;/h3&gt;
&lt;p&gt;We&amp;#39;ll take a break from making improvements to our code to discuss what the appeal of LinkedLists are. Obviously, a main advantage is that they aren&amp;#39;t fixed in size, like arrays. Another advantage is that thanks to our last code change, insertion is a constant and speedy operation. Yet another advantage is that an item can be added to the middle of the linked list with minimal effort - we don&amp;#39;t need to shift our entire list, simply reroute our next pointer. Finally, since LinkedLists don&amp;#39;t require contiguous memory, they can be used with highly fragmented memory space. &lt;/p&gt;
&lt;p&gt;Insertion into an ArrayList is also fast, but not constant. Once the ArrayList fills, it must grow. Additionally, when it does grow, a contiguous group of memory must be found to meet the new size. Of course, LinkedList do have one major drawback: random access is brutally slow. We have to walk through the list to find the desired item.&lt;/p&gt;
&lt;h3&gt;LinkedList v4&lt;/h3&gt;
&lt;p&gt;Deleting from a LinkedList is a little tricky (at least the way we&amp;#39;ve set it up). We don&amp;#39;t just remove the item, we also have to reroute our list. The item that pointed to our removed item must now point to the removed item&amp;#39;s next. If 1 --&amp;gt; 2 --&amp;gt; 3 and we remove 2, then 1--&amp;gt;3. This is pretty tricky to cleanly implement as-is. One way we can improve the maintainability of our LinkedList is to change each item so that it not only tracks the Next item in the list, but also the Previous one (this is called a doubly-linked list). &lt;/p&gt;&lt;pre class="c-sharp" name="code"&gt;public class LinkedList&amp;lt;T&amp;gt;
{
   private LinkedListItem _first;
   private LinkedListItem _last;

   public LinkedList(){}
   public LinkedList(T firstItem)
   {
      _first = new LinkedListItem(firstItem);
      _last = _first;
   }
   public void Add(T itemToAdd)
   {
      if (_first == null)
      {
         _first = new LinkedListItem(itemToAdd);
         _last = _first;
         return;
      }         
      _last.Next = new LinkedListItem(itemToAdd);
      _last.Next.Previous = _last;
      _last = _last.Next;
   }

   public void Remove(T itemToRemove)
   {
      LinkedListItem found = Find(itemToRemove);
      if (found == null)
      {
         return;
      }
      //this is the _first element
      if (found.Previous == null)
      {
         _first = found.Next;
      }
      else
      {
         //reroute the list
         found.Previous.Next = found.Next;
      }
      //this is the last element
      if (found.Next == null)
      {
         _last = found.Previous;
      }                 
   }
   private LinkedListItem Find(T itemToFind)
   {
      if (_first == null)
      {
         return null;
      }
      for (LinkedListItem current = _first; current != null; current = current.Next)
      {
         if (current.Item.Equals(itemToFind))
         {
            return current;
         }
      }
      return null;
   }

   private class LinkedListItem
   {
      public readonly T Item;
      public LinkedListItem Next;
      public LinkedListItem Previous;

      public LinkedListItem(T item)
      {
         Item = item;
      }
   }
}&lt;/pre&gt;
&lt;h3&gt;Fin&lt;/h3&gt;
&lt;p&gt;Today, it&amp;#39;s safe to consider LinkedLists as highly specialized data structures. However, back when memory was a real constraint, they were a core part of any program. Even the choice of creating a doubly-linked list could be difficult as every item within the list consumed an extra reference (8bits on an 8bit platform, 16bits on a 16bit platform and so on). Even if LinkedList aren&amp;#39;t as useful today as they once were, they&amp;#39;re still great for illustrating how our code interacts with system memory. They also show us how arrays and ArrayLists really work, by providing an interesting contrast. Thanks Mr. Woollard for teaching me all about data structures!&lt;/p&gt;&lt;img src="http://agile.codebetter.com/aggbug.aspx?PostID=181602" width="1" height="1"&gt;</content><author><name>karl</name><uri>http://agile.codebetter.com/members/karl.aspx</uri></author></entry><entry><title>Beautiful Code</title><link rel="alternate" type="text/html" href="http://agile.codebetter.com/blogs/karlseguin/archive/2008/08/01/beautiful-code.aspx" /><id>http://agile.codebetter.com/blogs/karlseguin/archive/2008/08/01/beautiful-code.aspx</id><published>2008-08-02T00:52:00Z</published><updated>2008-08-02T00:52:00Z</updated><content type="html">&lt;p&gt;I&amp;#39;d like to think that I&amp;#39;m a pretty passionate programmer, but I don&amp;#39;t think I&amp;#39;d describe code as being beautiful. Maybe I&amp;#39;ve seen one or two nice editor themes that really stand out, but actual code is just a bunch of ASCII characters as far as I&amp;#39;m concerned. At best I&amp;#39;ll find myself impressed with a programs organizational structure. &lt;/p&gt;
&lt;p&gt;Every now and again though, I&amp;#39;ll see a visualization of code that&amp;#39;s either really cool or downright breathtaking.&lt;/p&gt;
&lt;h3&gt;Game of Life&lt;/h3&gt;
&lt;p&gt;Probably the best known one that I can think of is John Conway&amp;#39;s &lt;a href="http://en.wikipedia.org/wiki/Conway%27s_Game_of_Life"&gt;Game of Life&lt;/a&gt;. Back in 1970, Conway devised a &amp;quot;game&amp;quot; with 4 simple rules which dictate whether a given cell is on or off based on the on/off state of neighbouring cells. When properly initialized, interesting patterns emerge. You can check out a Java implementation &lt;a href="http://www.bitstorm.org/gameoflife/"&gt;here&lt;/a&gt;&amp;nbsp;and a number of videos about all types of implementations on &lt;a href="http://www.youtube.com/results?search_query=Conway+Game+of+Life&amp;amp;search_type="&gt;youtube&lt;/a&gt;. It&amp;#39;s pretty astounding how four simple rules (which are equally simple to implement) can produce something so rich.&lt;/p&gt;
&lt;h3&gt;Sorting&lt;/h3&gt;
&lt;p&gt;One of my personal favourites though is the visualization of sorting algorithms. I&amp;#39;m pretty far from an algorithm freak, but there&amp;#39;s something just fascinating about watching these go. It isn&amp;#39;t so much how they individually look, but rather the diversity of how they operate - which translates in a diverse visual representation. Take a look at &lt;a href="http://www.iti.fh-flensburg.de/lang/algorithmen/sortieren/sortcontest/sortcontest.htm"&gt;this Java applet&lt;/a&gt; and hit the &amp;quot;Start All&amp;quot; button in the upper left corner. I find both Bitonic and Heap sorts mesmerizing. And, if you&amp;#39;re interested in a more informative version, check &lt;a href="http://siebn.de/index.php?page=anisort/english"&gt;this not-so-pretty Java applet&lt;/a&gt;, which steps through the Java code for each sorting phase.&lt;/p&gt;
&lt;h3&gt;Math&lt;/h3&gt;
&lt;p&gt;It&amp;#39;d be silly not to mention more mathematical-based patterns. Fractals can get &lt;a href="http://browse.deviantart.com/digitalart/fractals/"&gt;pretty crazy&lt;/a&gt;, but even the simple &lt;a href="http://upload.wikimedia.org/wikipedia/commons/3/38/Sierpinski-zoom4-ani.gif"&gt;Sierpinski Triangle&lt;/a&gt; can be hypnotic (maybe it&amp;#39;s because I like moving things). There&amp;#39;s also Voronoi Diagram and Delaunay Triangulation, which I know nothing about, except that they are much more fun with the &lt;a href="http://www.cs.cornell.edu/Info/People/chew/Delaunay.html"&gt;&amp;quot;More Colorful&amp;quot; checkbox checked&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;Tierra&lt;/h3&gt;
&lt;p&gt;Although not visually represented, my all time favourite has to be Thomas Ray&amp;#39;s Tierra computer simulation. Thomas Ray essentially created evolution within his computer by creating a self replicating code which randomly mutated itself. Out of this seeming chaos emerged parasites, liars and even a more efficient algorithm than the one he himself programmed. The best description, which is absolutely worth the short read, are the first two pages of chapter 15 in Kevin Kelly&amp;#39;s most excellent Out Of Control book (and they happen to be freely available - &lt;a href="http://www.kk.org/outofcontrol/ch15-a.html"&gt;page 1&lt;/a&gt; and &lt;a href="http://www.kk.org/outofcontrol/ch15-b.html"&gt;page 2&lt;/a&gt;).&lt;/p&gt;
&lt;h3&gt;Terrarium&lt;/h3&gt;
&lt;p&gt;If you agree with me and find Tierra amazing, you&amp;#39;ll probably be interested in Microsoft&amp;#39;s Terrarium. This is considerably more complex than everything else we&amp;#39;ve looked at so far, but it&amp;#39;s also the best suited at helping you learn. Terrarium was a learning tool built by Microsoft meant to showcase .NET and help new developers learn the framework and languages. You essentially create an insect by inheriting a base object, and override behaviour - such as what to do when you run into another insect or need to find food. You&amp;#39;d then release your code on a multiplayer server and could see how your insect did compared to everyone else&amp;#39;s. I did play with it for a few months years ago, and while the idea was certainly really neat and forward thinking, the implementation was a little weak. Anyways, if you&amp;#39;re interested, it looks like the project might be &lt;a href="http://www.hanselman.com/blog/LearningOpportunityNETTerrariumIsBack.aspx"&gt;getting resurrected&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;Assembly&lt;/h3&gt;
&lt;p&gt;The last thing I&amp;#39;d like to share are the winners of the annual &lt;a href="http://www.assembly.org/summer08/"&gt;Assembly contest&lt;/a&gt;. Although there are a lot of different categories, the ones that always draw my attention are the file-size limited ones. For example, take last years winner in the 4K winner &lt;em&gt;Candystall by Pittsburgh Stallers vs Loonies&lt;/em&gt;. You can watch the &lt;a href="http://www.youtube.com/watch?v=krG1ZTJcbaY"&gt;video here&lt;/a&gt; and download the &lt;a href="http://www.scene.org/file.php?file=%2Fparties%2F2007%2Fassembly07%2Fin4k%2Fcandystall_by_pittsburgh_stallers_vs_loonies.zip&amp;amp;fileinfo"&gt;.exe here&lt;/a&gt;. Would you be able to do that in a file under 4k in size? I wouldn&amp;#39;t! If you&amp;#39;re willing to add a bit more file size, you can also have the world&amp;#39;s smallest 3D game engine: &lt;a href="http://91.202.41.234/kkrieger"&gt;kkrieger&lt;/a&gt;. At 96k it truly is hard to believe.&lt;/p&gt;
&lt;h3&gt;Fin&lt;/h3&gt;
&lt;p&gt;There are countless more, and if you know of anything really neat, please leave a comment. As a final entry, check out &lt;a href="http://code.google.com/creative/radiohead/"&gt;Radiohead&amp;#39;s House Of Cards video&lt;/a&gt; - filmed without a camera.&lt;/p&gt;&lt;img src="http://agile.codebetter.com/aggbug.aspx?PostID=181528" width="1" height="1"&gt;</content><author><name>karl</name><uri>http://agile.codebetter.com/members/karl.aspx</uri></author></entry><entry><title>Looking for .NET projects to contribute to</title><link rel="alternate" type="text/html" href="http://agile.codebetter.com/blogs/karlseguin/archive/2008/07/31/looking-for-net-projects-to-contribute-to.aspx" /><id>http://agile.codebetter.com/blogs/karlseguin/archive/2008/07/31/looking-for-net-projects-to-contribute-to.aspx</id><published>2008-07-31T22:07:00Z</published><updated>2008-07-31T22:07:00Z</updated><content type="html">&lt;p&gt;I&amp;#39;ve been getting a fair bit of mesages from developers, who are enthusiastic about DDD and the common ALT.NET toolset, looking for a good project to contribute to - as a means of doing some hands on learning and helping out the community at the same time. I know one place to start might be Jeff Atwood&amp;#39;s &lt;a class="" href="http://spreadsheets.google.com/pub?key=pKxDW35algYebfs8nssTjIQ"&gt;open source list&lt;/a&gt;, but I was hoping someone might have more specific ideas.&lt;/p&gt;
&lt;p&gt;I think one of the challenges is that many open source projects tend to be tools for developers, and as such they are either pretty complicated, or don&amp;#39;t relate well to typical enterprise development. The other problem is that many open source projects are well established and have a large codebase, which makes them significantly harder to get involved with.&lt;/p&gt;
&lt;p&gt;Anyways, if anyone&amp;nbsp;knows of a good open source project where&amp;nbsp;a junior developer would be able to understand and contribue, please let us know. (Self-promotions welcomed)&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;img src="http://agile.codebetter.com/aggbug.aspx?PostID=181458" width="1" height="1"&gt;</content><author><name>karl</name><uri>http://agile.codebetter.com/members/karl.aspx</uri></author></entry><entry><title>Password : You're doing it wrong</title><link rel="alternate" type="text/html" href="http://agile.codebetter.com/blogs/karlseguin/archive/2008/07/30/password-you-re-doing-it-wrong.aspx" /><id>http://agile.codebetter.com/blogs/karlseguin/archive/2008/07/30/password-you-re-doing-it-wrong.aspx</id><published>2008-07-30T16:07:00Z</published><updated>2008-07-30T16:07:00Z</updated><content type="html">&lt;p&gt;I&amp;#39;d like to think that I deal with passwords the way most developers do. When dealing with registration or something else that requires the user to provide a password, I follow some general guidelines: 
&lt;ol&gt;
&lt;li&gt;The password must be a minimum length, normally no less than 6 characters&lt;/li&gt;
&lt;li&gt;The password&amp;#39;s maximum length is very high (200 characters)&lt;/li&gt;
&lt;li&gt;I&amp;#39;ll typically check for at least a mix of letters and numbers. For applications with considerably more sensitive data, I&amp;#39;ll have more requirements – such as mixed casing or special characters.&lt;/li&gt;
&lt;li&gt;Hash the password with a salt (the salt can be a fixed string, or something more unique to the user - again based on sensitivity). Salting means that if someone gets access to a dump of your Users table, they&amp;#39;ll still have a hard time logging into the system with a dictionary attack.&lt;/li&gt;
&lt;li&gt;Since hashes can&amp;#39;t easily be reversed, send out a new password to users when they &lt;em&gt;forgot password&lt;/em&gt; and have them change the temporary password as soon as they log in.&lt;/li&gt;&lt;/ol&gt;
&lt;p&gt;All this is pretty vanilla and you can change an SHA1 hash implementation for some encryption or whatever else tickles your fancy. What I&amp;#39;ve noticed though isn&amp;#39;t that developers are hitting some type of technical hurdle when dealing with password, but rather, a usability one. The point behind bullets 1, 2 and 3 is that users ought to be able to enter &lt;strong&gt;anything&lt;/strong&gt; they want as a password, provided it meets a &lt;strong&gt;minimum&lt;/strong&gt; set of guidelines. As developers, we should try very hard never to impose restrictions which &lt;strong&gt;limit&lt;/strong&gt; the effectiveness of a password. Lately though, I&amp;#39;ve been astonished at some of the limits sites impose on passwords – forcing me to come up with a less secure password than what I would have liked. &lt;/p&gt;
&lt;p&gt;Here are some popular sites which have such restrictions: 
&lt;ul&gt;
&lt;li&gt;digg only accepts letters and numbers&lt;/li&gt;
&lt;li&gt;SourceForge only accepts letters and numbers (when you change your password, SourceForge even goes through the trouble of showing you a little dynamic update as you type (weak &amp;gt; normal &amp;gt; strong and then &amp;quot;invalid character&amp;quot; when you enter an exclamation mark)&lt;/li&gt;
&lt;li&gt;Passport limits password to 16 characters (isn&amp;#39;t Microsoft a champion of passphrases?)&lt;/li&gt;
&lt;li&gt;MySpace only accepts passwords up to 10 characters long, but at least require 1 number or punctuation character&lt;/li&gt;
&lt;li&gt;Wikipedia let me register with a password of ‘a&amp;#39;, but at least has very informative help on choosing a strong password. (Additionally, given what an anonymous user can do on Wikipedia, I&amp;#39;m not too disappointed in this policy)&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;And for sites with better policies: 
&lt;ul&gt;
&lt;li&gt;Ebay, PayPal and Google have useful help and accept special characters (PayPal and Google even require at least 8 characters),&lt;/li&gt;
&lt;li&gt;Twitter and Facebook don&amp;#39;t have any “choosing a strong password&amp;quot; help, but still seem to accept everything&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;The most shameful site I&amp;#39;ve ever come across though is completely unacceptable – not only because of the ridiculous limitations it puts on passwords, but also the type of data it&amp;#39;s responsible for. The Bank of Montreal&amp;#39;s Mosaik Credit Card (BMO is major Canadian bank), has a password limit of 8 characters and only accepts letters and numbers (there&amp;#39;s actually a maxlength=&amp;quot;8&amp;quot; attribute on the form).&lt;/p&gt;
&lt;p&gt;Here&amp;#39;s a simple rule to follow. If Windows Calculator displays the total number of possible combinations in non-exponential form, you password guidelines suck.&lt;/p&gt;&lt;img src="http://agile.codebetter.com/aggbug.aspx?PostID=181388" width="1" height="1"&gt;</content><author><name>karl</name><uri>http://agile.codebetter.com/members/karl.aspx</uri></author></entry><entry><title>My Thoughts on ASP.NET's MVC</title><link rel="alternate" type="text/html" href="http://agile.codebetter.com/blogs/karlseguin/archive/2008/07/22/my-thoughts-on-asp-net-s-mvc.aspx" /><id>http://agile.codebetter.com/blogs/karlseguin/archive/2008/07/22/my-thoughts-on-asp-net-s-mvc.aspx</id><published>2008-07-23T01:49:00Z</published><updated>2008-07-23T01:49:00Z</updated><content type="html">Like me, you might have been surprised that the foundation series didn&amp;#39;t have a chapter on the MVC pattern. I&amp;#39;m no fan of the existing page model (I actually think it&amp;#39;s horrible), and I&amp;#39;ve successfully used MonoRail on a few projects, so it would have made for a good topic. My reasons for not including something on MVC were simple: we were and continue to be flooded with MVC information (as though it&amp;#39;s a brand new invention), and I didn&amp;#39;t think I could explain MVC using MonoRail effectively (I find it has a steep learning curve). I considered using RoR, but figured that would confuse people even more. 
&lt;p&gt;Hopefully though, if you&amp;#39;re a fan of the foundation series, you&amp;#39;ve already &lt;a class="" href="http://codebetter.com/files/folders/codebetter_downloads/entry180972.aspx"&gt;downloaded the learning application&lt;/a&gt; which puts the theory to practice using ASP.NET&amp;#39;s MVC framework. So, what do I think about ASP.NET MVC? Overall I&amp;#39;ve been very impressed. I can&amp;#39;t think of a good reason for starting a new project using the WebForms model - or MonoRail for that matter (sorry). If you&amp;#39;re an ASP.NET developer, it&amp;#39;s really a no brainer.&lt;/p&gt;
&lt;p&gt;I do have two major issues with it though. First, if you come from almost any other MVC framework (MonoRail, Django, RoR, Akelos, etc...) you might be expecting an actually Model framework - instead you get an empty Model folder. In other words, the MVC framework doesn&amp;#39;t add anything to the .NET O/R Mapping / DAL story. From Microsoft&amp;#39;s point of view this makes sense, since they feel that they are already offering solid solutions - DataSets, SqlDataSources, LINQ to SQL, Entity Framework. Truth be told, this is fine with me, as it lets me use NHibernate. I just think, given what the other MVC frameworks offer, it&amp;#39;s a little dishonest - you&amp;#39;ll end up disappointed if you&amp;#39;re expecting to be able to do this out of the box:&lt;/p&gt;&lt;pre class="c-sharp" name="code"&gt;public class Car : ActiveRecord
{
}
....
Car.FindById(1);&lt;/pre&gt;
&lt;p&gt;My real problem though is simply that neither C# nor VB.NET lend themselves all that well to view logic. Jeff Atwood actually just &lt;a class="" href="http://www.codinghorror.com/blog/archives/001155.html"&gt;blogged the same criticism&lt;/a&gt;. Jeff uses RoR to highlight the problem. I don&amp;#39;t fully agree. I won&amp;#39;t say that RHTML is great, but I will say that it&amp;#39;s far better than C# or VB.NET. I think views need a specialize language - I&amp;#39;m sure that anyone who&amp;#39;s done some significant work in either RoR or Django would agree. There are solutions available now - NVelocity and Boo (I assume you could use it with the MVC framework?), but I&amp;#39;m just going to trudge along with C# until IronRuby is a viable solution.&lt;/p&gt;
&lt;p&gt;Aside from that, everything is pretty solid - routes work great, helper methods are adequate (they&amp;#39;re starting to add more and more), and testing is actually doable - I haven&amp;#39;t run into any problems, but from what I&amp;#39;ve read things aren&amp;#39;t 100% perfect yet (either way, it&amp;#39;s a huge step up from WebForms). &lt;/p&gt;
&lt;p&gt;So, to recap. MVC good. WebForms Bad. C# in views less than ideal. Empty Model folder = M. Oh, and&lt;a class="" href="http://codebetter.com/files/folders/codebetter_downloads/entry180972.aspx"&gt; download the learning application&lt;/a&gt;!.&lt;/p&gt;&lt;img src="http://agile.codebetter.com/aggbug.aspx?PostID=181136" width="1" height="1"&gt;</content><author><name>karl</name><uri>http://agile.codebetter.com/members/karl.aspx</uri></author><category term="Foundations" scheme="http://agile.codebetter.com/blogs/karlseguin/archive/tags/Foundations/default.aspx" /></entry><entry><title>Foundations of Programming - Learning Application</title><link rel="alternate" type="text/html" href="http://agile.codebetter.com/blogs/karlseguin/archive/2008/07/18/foundations-of-programming-learning-application.aspx" /><id>http://agile.codebetter.com/blogs/karlseguin/archive/2008/07/18/foundations-of-programming-learning-application.aspx</id><published>2008-07-18T13:34:00Z</published><updated>2008-07-18T13:34:00Z</updated><content type="html">&lt;p&gt;If you&amp;#39;re anything like me, you probably learn a lot better by going through code rather than reading books. I&amp;#39;m happy to release the Foundations of Programming Learning Application - it&amp;#39;s a complete solution meant to show what was covered in the Foundations series. It&amp;#39;s a Visual Studio 2008 solution.&lt;/p&gt;
&lt;p&gt;You can &lt;a class="" href="http://codebetter.com/files/folders/codebetter_downloads/entry180972.aspx"&gt;download it here&lt;/a&gt;. It should require no configuration (my fingers are crossed on that one) and ought to just run out of the box. There are comments sprinkled all over to help explain things or provide some insight. No doubt there&amp;#39;ll be typos, since I&amp;#39;m nothing without word.&lt;/p&gt;
&lt;p&gt;(you can grab the free ebook from: &lt;a href="http://codebetter.com/blogs/karlseguin/archive/2008/06/24/foundations-of-programming-ebook.aspx"&gt;http://codebetter.com/blogs/karlseguin/archive/2008/06/24/foundations-of-programming-ebook.aspx&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What is it?&lt;br /&gt;&lt;/strong&gt;It&amp;#39;s a sample awards website&amp;nbsp;- with categories and nominees. The root container is called a Round - a sample Round would be called &amp;#39;The 2008 CodeBetter Awards&amp;#39;. A Round has a state (planning, annoucements, voting, winners) and a number of Categories (Best Blogger, Best Blog Post, Best Open Source Project, ...) with each categories having a Nominee (Title, Summary, Link, Author...). The website is using the ASP.NET MVC Preview 4 - I don&amp;#39;t think you&amp;#39;ll need to install anything extra as all the DLLs are included with the project. I&amp;#39;m using an SQL Lite database with a relative path to the file, so all should work as-is. Dummy data is already loaded.&lt;/p&gt;
&lt;p&gt;The web application mostly shows a read-only view of the data. There&amp;#39;s also a sample console application that does more administrative stuff (it isn&amp;#39;t interactive, it just runs through 4 steps or so). You can run the administrative portion over and over again - the first step is to clean itself up. The admin part basically adds a new round, with categories and nominees.&lt;/p&gt;
&lt;p&gt;Of course, there&amp;#39;s a project full of unit tests as well.&lt;/p&gt;
&lt;p&gt;I tried to keep everything simple and straightforward (which is largely why I didn&amp;#39;t want to build a whole web-based admin module and user registration and all that). Like most, I&amp;#39;m pretty new to ASP.NET MVC. Some might think my views have too much code, I think they have the perfect amount &lt;img src="http://codebetter.com/emoticons/emotion-4.gif" alt="Stick out tongue" /&gt;. There&amp;#39;s extensive use of Lambdas, so if you have a hard time reading them, I hope my excessive examples will help illuminate them.&lt;/p&gt;&lt;img src="http://agile.codebetter.com/aggbug.aspx?PostID=180974" width="1" height="1"&gt;</content><author><name>karl</name><uri>http://agile.codebetter.com/members/karl.aspx</uri></author><category term="Foundations" scheme="http://agile.codebetter.com/blogs/karlseguin/archive/tags/Foundations/default.aspx" /></entry><entry><title>Announcing the .NET Extension Library</title><link rel="alternate" type="text/html" href="http://agile.codebetter.com/blogs/karlseguin/archive/2008/07/14/announcing-the-net-extension-library.aspx" /><id>http://agile.codebetter.com/blogs/karlseguin/archive/2008/07/14/announcing-the-net-extension-library.aspx</id><published>2008-07-15T00:01:00Z</published><updated>2008-07-15T00:01:00Z</updated><content type="html">&lt;p&gt;285 days ago I blogged about my dislike for extension methods. Extension methods aren&amp;#39;t very discoverable, and they can lead to poor communication (between members of a team, from project to project, and between a developer and the code he or she is trying to read).&lt;/p&gt;
&lt;p&gt;I still think extension methods have serious shortcoming, but I&amp;#39;ve soften my view&amp;nbsp;on them quite&amp;nbsp;a bit. I don&amp;#39;t know what changed, maybe it was my extended foray into Ruby or spending the last few weeks neck-deep in the ASP.NET MVC framework, but I decided to attempt to put out a standard extension library for .NET developers. One of my gripes with extension methods is that they can make projects rather inconsistent, a new developer might be surprised that string.Left suddenly doesn&amp;#39;t work on a new project. Ideally, having&amp;nbsp;a well-known extension library might help solve that problem.&lt;/p&gt;
&lt;p&gt;The .NET Extension Library isn&amp;#39;t just about extension methods though. It&amp;#39;s about providing core functionality to projects. For example, I&amp;#39;ve blogged a few times about how hard it is to unit test code that caches - largely because there isn&amp;#39;t an cache interface. This is a problem no more. The .NET Extension Library has an ICache interface, a CacheFactory (which really just returns HttpRuntime.Cache - for now), as well as enhancements to the cache API. Here&amp;#39;s one of my favourite examples of what you can do:&lt;/p&gt;&lt;pre class="c-sharp" name="code"&gt;User user = CacheFactory.GetInstance.Fetch(
     &amp;quot;user.{0}&amp;quot;.Sub(userId), 
     () =&amp;gt; _dataStore.GetUser(userId),   
     3.DaysFromNow());
&lt;/pre&gt;
&lt;p&gt;Fetch is a mix between Get and Insert.&amp;nbsp;My second favourite addition are the extensions to IEnumerable, which bring all collections/arrays inline with the List when it comes to methods like Each, TrueForAll, Find, FindAll and more. You no longer need to use the static Array methods.&lt;/p&gt;
&lt;p&gt;Input is always welcomed, as are suggestions and/or additions. As much as I&amp;#39;m up for adding useful extension methods, I rather focus on &lt;a class="" href="http://codebetter.com/blogs/jeremy.miller/archive/2008/07/09/classes-that-show-up-in-every-project.aspx"&gt;classes that show up in every project&lt;/a&gt; kinda thing, such as an abstraction for logging and such.&lt;/p&gt;
&lt;p&gt;Anyways, check it out at codeplex: &lt;a href="http://www.codeplex.com/nxl"&gt;http://www.codeplex.com/nxl&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;&lt;img src="http://agile.codebetter.com/aggbug.aspx?PostID=180825" width="1" height="1"&gt;</content><author><name>karl</name><uri>http://agile.codebetter.com/members/karl.aspx</uri></author></entry><entry><title>Scale Cheaply - Memcached</title><link rel="alternate" type="text/html" href="http://agile.codebetter.com/blogs/karlseguin/archive/2008/07/07/scale-cheaply-memcached.aspx" /><id>http://agile.codebetter.com/blogs/karlseguin/archive/2008/07/07/scale-cheaply-memcached.aspx</id><published>2008-07-07T23:40:00Z</published><updated>2008-07-07T23:40:00Z</updated><content type="html">&lt;p&gt;I generally subscribe to the attitude that premature optimizations are evil, but I strongly believe that a robust caching strategy should evolve alongside the rest of the system. Waiting too long makes it hard to cleanly and thoughtfully add caching. Besides, in my experience, a considered caching strategy generally means I worry less about performance in other areas - especially data access and data modelling. In other words, I can build those complex parts for maintainability, as opposed to having to worry about the cost of each individual query.&lt;/p&gt;
&lt;p&gt;.NET developers are pretty cache-savvy - thanks largely in part to the powerful &lt;code&gt;System.Web.Caching&lt;/code&gt; namespace and ASP.NET&amp;#39;s simple to use OutputCaching capabilities. For that reason, and the fact that it tends to be very application specific, I don&amp;#39;t want to go over how to decide what to cache, how to deal with synch issues, updates and so on. Instead, I specifically want to talk about Memcached.&lt;/p&gt;
&lt;p&gt;You&amp;#39;re probably already familiar with Memcached - it&amp;#39;s a highly efficient distributed caching system. It&amp;#39;s used generously by all the big web 2.0 players (In may 2007 it was revealed that Facebook relies on 200 16GB quad-core dedicated Memcached servers). Interest in Memcached from the .NET community has been relatively low (although over the last year more and more people are talking about it). Frankly, if you&amp;#39;re doing anything that requires horizontal scaling you&amp;#39;re seriously shooting yourself in the foot by overlooking it. It runs on windows - although we run it on Linux and there&amp;#39;s really no reason for you not to learn that too!&lt;/p&gt;
&lt;p&gt;Fundamentally, there are two problems with the built-in cache. First, it&amp;#39;s limited to the memory of a single system which happens to be shared with the rest of your application domain. Secondly, if you have two servers, each with their own in-memory cache, users are likely to see very weird synching issues. Memcached isn&amp;#39;t as fast as in-memory caching, but will scale to virtually unlimited amount of memory. There isn&amp;#39;t any redundancy of failover, simply memory spread across multiple servers.&lt;/p&gt;
&lt;p&gt;The best part is that it literally takes seconds to get it up and running. First, download a windows build onto your development machine &lt;a href="http://code.jellycan.com/memcached/"&gt;here&lt;/a&gt;. (look for the win32 binary of memcached). Unzip the package somewhere, I put mine in &lt;code&gt;c:\program files\memcached\&lt;/code&gt;. Next, from the command line, run &lt;code&gt;memcached -d install&lt;/code&gt;. This will install memcached as a service. You can run &lt;code&gt;memcached -h&lt;/code&gt; for more command lines options. You&amp;#39;ll need to start the service (I also changed my startup type to manual, but that&amp;#39;s completely up to you).&lt;/p&gt;
&lt;p&gt;The next step is to install the client library. I use suggest &lt;a href="http://www.codeplex.com/EnyimMemcached/"&gt;Enyim Memcached from CodePlex&lt;/a&gt;. The project comes with a sample configuration file, which you should be able to easily incorporate into your web.config or app.config. While developing, only put one server 127.0.0.1 on port 11211 (which is the default). You also need to add a reference to the two dlls.&lt;/p&gt;
&lt;p&gt;Aside from that, you basically program against a simple API. You create an instance of &lt;code&gt;MemcachedClient&lt;/code&gt; (it&amp;#39;s thread-safe so you can use a singleton, or re-create it since it&amp;#39;s inexpensive to create), and call &lt;code&gt;Store&lt;/code&gt;, &lt;code&gt;Get&lt;/code&gt; or &lt;code&gt;Remove&lt;/code&gt; (or a few other useful methods) like you would the normal cache object. As I&amp;#39;ve blogged about before (&lt;a href="http://codebetter.com/blogs/karlseguin/archive/2007/06/03/tweaking-net-s-cache-api.aspx"&gt;here&lt;/a&gt; and &lt;a href="http://codebetter.com/blogs/karlseguin/archive/2008/07/03/get-your-func-on.aspx"&gt;here&lt;/a&gt;), I&amp;#39;m a fan of hiding all of this behind an interface to ease mocking and swapping.&lt;/p&gt;
&lt;p&gt;Here&amp;#39;s an example:&lt;/p&gt;&lt;pre class="c-sharp" name="code"&gt;MemcachedClient client = new MemcachedClient();
client.Store(StoreMode.Set, &amp;quot;Startup&amp;quot;, DateTime.Now, DateTime.Now.AddMinutes(20));
DateTime startup = client.Get&amp;lt;DateTime&amp;gt;(&amp;quot;Startup&amp;quot;);
client.Remove(&amp;quot;Startup&amp;quot;);&lt;/pre&gt;&lt;img src="http://agile.codebetter.com/aggbug.aspx?PostID=180458" width="1" height="1"&gt;</content><author><name>karl</name><uri>http://agile.codebetter.com/members/karl.aspx</uri></author></entry><entry><title>Get Your Func On</title><link rel="alternate" type="text/html" href="http://agile.codebetter.com/blogs/karlseguin/archive/2008/07/03/get-your-func-on.aspx" /><id>http://agile.codebetter.com/blogs/karlseguin/archive/2008/07/03/get-your-func-on.aspx</id><published>2008-07-04T00:15:00Z</published><updated>2008-07-04T00:15:00Z</updated><content type="html">&lt;p&gt;I&amp;#39;ve noticed that I have a 2 step pattern for learning new framework or language features. I&amp;#39;m guessing this is pretty typical for most people. First, I&amp;#39;ll use the feature within framework classes or 3rd party ddls. Then I&amp;#39;ll leverage it more directly within my own code. What&amp;#39;s surprising to me is the length of time which occurs between step 1 and step 2. &lt;/p&gt;
&lt;p&gt;Take generics for example. Back in the 1.x days, I wrote a ton of repetitive classes that inherited from &lt;code&gt;CollectionBase&lt;/code&gt;. So when 2.0 came out, I immediately and aggressively started to use generic collections. However, it was quite some time later (a year?) until I wrote my own class that leveraged them directly. Today, I don&amp;#39;t write a new generic class every day, but I do consider them an important part of my toolbox and kinda wonder what took me so long to take them up.&lt;/p&gt;
&lt;p&gt;I have a feeling that many developers are in the same boat - it&amp;#39;s easy to consume code that implements new features, but not so easy to grasp how to implement those same features ourselves. &lt;/p&gt;
&lt;p&gt;As it turns out, the other day, I had another such ah-hah moment with the &lt;code&gt;System.Func&lt;/code&gt; generic delegate. Like me, you&amp;#39;ve probably consumed it often, or at least one of its cousins: &lt;code&gt;System.Action&lt;/code&gt; and &lt;code&gt;System.Predicate&lt;/code&gt;. I thought I&amp;#39;d show how I used it, in hopes that it might open up some possibilities for you.&lt;/p&gt;
&lt;h3&gt;Ovewview&lt;/h3&gt;
&lt;p&gt;First though, a brief overview. The three delegates above are essentially shortcuts that save you from having to write your own common delegate. The most common one is probably &lt;code&gt;Predicate&amp;lt;T&amp;gt;&lt;/code&gt;, which returns a boolean.&lt;code&gt; Predicte&amp;lt;T&amp;gt;&lt;/code&gt; is used extensively by the &lt;code&gt;List&amp;lt;T&amp;gt;&lt;/code&gt; and &lt;code&gt;Array&lt;/code&gt; classes. The most obvious is the &lt;code&gt;Exist&lt;/code&gt; method:&lt;/p&gt;&lt;pre class="c-sharp" name="code"&gt;List&amp;lt;string&amp;gt; roles = user.Roles;
if (roles.Exists(delegate(string r) { return r == &amp;quot;admin&amp;quot;;}))
{
   //do something
}
&lt;/pre&gt;
&lt;p&gt;or the lambda version (which I much prefer)&lt;/p&gt;&lt;pre class="c-sharp" name="code"&gt;if (role.Exists(r =&amp;gt; r == &amp;quot;admin))
{
}&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;Func&amp;lt;T&amp;gt;&lt;/code&gt; is a lot like &lt;code&gt;Predicate&lt;/code&gt;, but instead of returning a boolean it returns T. Also, &lt;code&gt;Func&amp;lt;T&amp;gt;&lt;/code&gt; has multiple overloads that let you pass 0 to 4 input parameters into the delegate. &lt;code&gt;Action&amp;lt;T&amp;gt;&lt;/code&gt; is like &lt;code&gt;Func&amp;lt;T&amp;gt;&lt;/code&gt; except it doesn&amp;#39;t return anything - it does an action. &lt;/p&gt;
&lt;h3&gt;Code Decoupling&lt;/h3&gt;
&lt;p&gt;So, how can you make use of these within your own code? Well, here&amp;#39;s what I did. First, I&amp;#39;m a big proponent of caching, as well as a big fan of unit testing. However, the two don&amp;#39;t easily go hand-in-hand because Microsoft doesn&amp;#39;t provide an interface to their built-in cache, which leads to tight coupling (which of course makes it difficult to change caching implementation down the road, and impossible to unit test). The first thing to do is create your own interface, a simple start might look like:&lt;/p&gt;&lt;pre class="c-sharp" name="code"&gt;public interface ICacheManager
{
   T Get&amp;lt;T&amp;gt;(string key);
   void Insert(string key, object value);
}&lt;/pre&gt;
&lt;p&gt;Next comes our first implementation:&lt;/p&gt;&lt;pre class="c-sharp" name="code"&gt;public class InMemoryCacheManager : ICacheManager
{
    public T Get&amp;lt;T&amp;gt;(string key)
    {
        return (T) HttpRuntime.Cache.Get(key);
    }
    public void Insert(string key, object value)
    {
         HttpRuntime.Cache.Insert(key, value);
    }
}&lt;/pre&gt;
&lt;h3&gt;Func Fights Repitition&lt;/h3&gt;
&lt;p&gt;So, what does all this have to do with &lt;code&gt;System.Func&lt;/code&gt;? Well, the above code is used in a very repetitive manner: get the value from the cache, if it&amp;#39;s null, load it from somewhere and put it back in the cache. For example:&lt;/p&gt;&lt;pre class="c-sharp" name="code"&gt;public User GetUserFromId(int userId)
{
    ICacheManager cache = CacheFactory.GetInstance;
    string cacheKey = string.Format(&amp;quot;User.by_id.{0}&amp;quot;, userId);
    User user = cache.Get(cacheKey);
    if (user == null)
    {
       user = _dataStore.GetUserFromId(userId);
       cache.Insert(cacheKey, user);
    }
   return user;
}&lt;/pre&gt;
&lt;p&gt;After a year or so of writing code like this, I figured there must be a better way, which of course is where &lt;code&gt;Func&lt;/code&gt; comes in. Ideally, we&amp;#39;d like to get the value, and provide our callback code all at once. So, let&amp;#39;s change our interface:&lt;/p&gt;&lt;pre class="c-sharp" name="code"&gt;public interface ICacheManager
{
   T Get&amp;lt;T&amp;gt;(string key, Func&amp;lt;T&amp;gt; callback);
   void Insert(string key, object value);
}&lt;/pre&gt;
&lt;p&gt;The second parameter is the delegate we&amp;#39;ll want to execute if &lt;code&gt;Get&lt;/code&gt; returns &lt;code&gt;null&lt;/code&gt;. Of course our delegate will return the same type (T) as &lt;code&gt;Get&lt;/code&gt; would - just like in the above case where we expect a &lt;code&gt;User&lt;/code&gt; from both &lt;code&gt;Get&lt;/code&gt; and our data store. Here&amp;#39;s the actual implementation:&lt;/p&gt;&lt;pre class="c-sharp" name="code"&gt;public T Get&amp;lt;T&amp;gt; (string key, Func&amp;lt;T&amp;gt; callback)
{
   T item = (T) HttpRuntime.Cache.Get(key);
   if (item == null)
   {
       item = callback();
       Insert(key, item);
   }
   return item;
}&lt;/pre&gt;
&lt;p&gt;How do we use the above code?&lt;/p&gt;&lt;pre class="c-sharp" name="code"&gt;public User GetUserFromId(int userId)
{
   return CacheFactory.GetInstance.Get(string.Format(&amp;quot;User.by_id.{0}&amp;quot;, userId), 
                                                                () =&amp;gt; _dataStore.GetUserFromId(userId));
}&lt;/pre&gt;
&lt;p&gt;I know the &lt;code&gt;() =&amp;gt;&lt;/code&gt; syntax might be intimidating (especially if you aren&amp;#39;t familiar with lambdas), but all it is is a parameterless delegate.&lt;/p&gt;
&lt;p&gt;Of course, this system can easily be expanded to add additional caching instructions (absolute/sliding expiries, dependencies and so on) via overloaded &lt;code&gt;Get&amp;lt;T&amp;gt; &lt;/code&gt;and &lt;code&gt;Insert&lt;/code&gt; members. &lt;/p&gt;
&lt;p&gt;(I just noticed this example also highlights how to use generics within your own code too!)&lt;/p&gt;&lt;img src="http://agile.codebetter.com/aggbug.aspx?PostID=180316" width="1" height="1"&gt;</content><author><name>karl</name><uri>http://agile.codebetter.com/members/karl.aspx</uri></author></entry><entry><title>Scale Cheaply - Sharding</title><link rel="alternate" type="text/html" href="http://agile.codebetter.com/blogs/karlseguin/archive/2008/06/30/scale-cheaply-sharding.aspx" /><id>http://agile.codebetter.com/blogs/karlseguin/archive/2008/06/30/scale-cheaply-sharding.aspx</id><published>2008-06-30T15:11:00Z</published><updated>2008-06-30T15:11:00Z</updated><content type="html">&lt;p&gt;There are a lot of expensive ways to scale your database – all of which are highly touted by the big three database vendors because, well, they want to sell you all types of really expensive stuff. Despite what an “engagement consultant” might tell you though, most of the high-traffic websites on the web (google, digg, facebook) rely on far cheaper and better strategies: the core of which is called sharding. &lt;/p&gt;
&lt;p&gt;What’s really astounding is that sharding is database agnostic – yet only the MySQL crowd seem to really be leveraging it. The sales staff at Microsoft, IBM and Oracle are doing a good job selling us expensive solutions.&lt;/p&gt;
&lt;p&gt;Sharding is the separation of your data across multiple servers. How you separate your data is up to you, but generally it’s done on some fundamental identifier. For example, if we were building a hosted bug tracking site, our data model would likely look something like: &lt;/p&gt;
&lt;p&gt;&lt;img style="WIDTH:575px;HEIGHT:243px;" height="243" src="http://www.openmymind.net/shardnig_db1.gif" width="575" border="0" alt="" /&gt;&lt;/p&gt;
&lt;p&gt;Every Client is pretty much isolated from all other Clients. So if we put all of Client 1’s data on Server 1 and Client 2’s data on Server 2, our system will run just fine. This scales out horizontally infinitely well (there’s little to no overhead). Our first 500 clients can all go on our first server, at which point we can introduce a second database server and place our next 500 clients. Servers need only be added when actually needed, and there’s no need for management servers, load balancers or anything else – just straight database connections.&lt;/p&gt;
&lt;p&gt;One of the disadvantages of sharding is that it does impact your code. You need to figure out which database to connect to. For our simple scenario above, this isn’t too difficult:&lt;/p&gt;&lt;pre class="c-sharp" name="code"&gt; 
using (SqlConnection connection = GetConnection(clientId))
{
 ...
}
private static SqlConnection GetConnection(int clientId)
{
   string connectionString;
   if (clientId &amp;lt;= 500)
   {
      connectionString = _connectionStrings[0];
   }
   else
   {
      connectionString = _connectionStrings[1];
   }
   return new SqlConnection(connectionString);
}
&lt;/pre&gt;This is a simplified example, but should be pretty easy to expand on. Another approach is to use a modulus to figure out which connection string to use, something like: &lt;pre class="c-sharp" name="code"&gt; 
return new SqlConnection(connectingString[clientId % _connectingString.Length]);
&lt;/pre&gt;
&lt;p&gt;This brings up another problem with sharding (a big one) – repartitioning your data. If we pick the above modulus algorithm with 2 servers and 2 clients then:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Client 2 will be associated to ConnectionString[0] (2 % 2 == 0)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Client 1 will be associated to ConnectionString[1] (1 % 2 == 1)&lt;/p&gt;
&lt;p&gt;If we now add a bunch of clients along with a 3rd server, then our code expects to find Client 2 on a different server (2 % 3 == 2). Essentially what this means is that you’ll need a repartitioning strategy – whether that’s an advanced connection manager configuration approach, or bulk copy scripts. The good news is that all of this should be deep inside your data layer and completely hidden from your calling code. There are many ways to handle this, pick whatever seems simplest.&lt;/p&gt;
&lt;p&gt;The last hurdle to overcome is actually sharding your data. Our bug hosted example was pretty straightforward, but even it has limitations. When a client creates a new account they are asked to submit their subdomain of choice. We need to check whether that subdomain is available or not – which isn’t trivial since our data is spread all around. Similarly, when a user logs in, we don’t yet know which client they belong to, therefore we can’t figure out which database server to hit for authentication. In such cases, rather than sharding data on a key, you shard on purpose. Essentially, this means you have a database dedicated to your Users table, as well as a ClientHost table which does nothing more than provide a single place to look up whether a host is available or not. Again, this is something that your data access layer must be aware of.&lt;/p&gt;
&lt;p&gt;Despite these issues, sharding is my preferred database scaling choice by far. All the issues can be fixed with a bit of code deep within your data layer. The performance advantage AND cost advantage make it a no-brainer. The only reason to consider clustering is for high availability scenarios, or in cases where your bottleneck is data that cannot be easily split. Also, keep in mind that sharding typically plays nice with replication or clustering, so these aren&amp;#39;t necessarily exclusive strategies.&lt;/p&gt;&lt;img src="http://agile.codebetter.com/aggbug.aspx?PostID=180067" width="1" height="1"&gt;</content><author><name>karl</name><uri>http://agile.codebetter.com/members/karl.aspx</uri></author></entry><entry><title>Foundations of Programming Ebook</title><link rel="alternate" type="text/html" href="http://agile.codebetter.com/blogs/karlseguin/archive/2008/06/24/foundations-of-programming-ebook.aspx" /><id>http://agile.codebetter.com/blogs/karlseguin/archive/2008/06/24/foundations-of-programming-ebook.aspx</id><published>2008-06-25T01:53:00Z</published><updated>2008-06-25T01:53:00Z</updated><content type="html">&lt;p&gt;I&amp;#39;m excited to finally release the official, and completely free, Foundations of Programming EBook. This essentially contains all 9 Foundation parts including a conclusion and some typical book fluff (table of content, acknowledgement and so on). A number of spelling errors were corrected, along with some small technical changes and clarifications - largely based on feedback, so thanks for everyone who provided it! Otherwise it&amp;#39;s exactly the same as what&amp;#39;s been posted here over the past several months.&lt;/p&gt;
&lt;p&gt;Download it from &lt;a href="http://codebetter.com/files/folders/codebetter_downloads/entry179694.aspx"&gt;http://codebetter.com/files/folders/codebetter_downloads/entry179694.aspx&lt;/a&gt; &lt;br /&gt;&lt;br /&gt;Download the Learning Application from: &lt;a href="http://codebetter.com/blogs/karlseguin/archive/2008/07/18/foundations-of-programming-learning-application.aspx"&gt;http://codebetter.com/blogs/karlseguin/archive/2008/07/18/foundations-of-programming-learning-application.aspx&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;a href="http://codebetter.com/files/folders/codebetter_downloads/entry179694.aspx"&gt;&lt;img title="Foundations Of Programming" height="250" alt="Foundations Of Programming" src="http://www.openmymind.net/cover.jpg" width="193" border="0" /&gt;&lt;/a&gt;&amp;nbsp; &lt;/p&gt;
&lt;p&gt;If the above link fails, you can also get it from &lt;a href="http://www.openmymind.net/FoundationsOfProgramming.pdf"&gt;http://www.openmymind.net/FoundationsOfProgramming.pdf&lt;/a&gt; &lt;br /&gt;&lt;/p&gt;&lt;img src="http://agile.codebetter.com/aggbug.aspx?PostID=179695" width="1" height="1"&gt;</content><author><name>karl</name><uri>http://agile.codebetter.com/members/karl.aspx</uri></author><category term="Foundations" scheme="http://agile.codebetter.com/blogs/karlseguin/archive/tags/Foundations/default.aspx" /></entry></feed>