<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-3714840552149734001</id><updated>2011-07-30T09:17:17.155-07:00</updated><title type='text'>Apprenticeship</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://8thlightapprenticeship.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://8thlightapprenticeship.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Justin</name><uri>http://www.blogger.com/profile/04054497811526894325</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://3.bp.blogspot.com/_snSMUhgzWLE/S0KeHj1cwNI/AAAAAAAAAAQ/f9gAgDyjN2A/S220/me.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>53</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-3714840552149734001.post-3207921563960860183</id><published>2010-04-08T20:50:00.000-07:00</published><updated>2010-04-08T21:45:13.965-07:00</updated><title type='text'>Day 62</title><content type='html'>At last I understand.  For quite some time now, I have been doing a lot of work on websites and web apps.  Working on a variety of different frameworks, on several different projects.  But I have always been working on the back end.  Creating models, creating functionality, making interactive pages, and migrating data; Yet I never did any real work on the front end.  I suppose my fantastical UI design for my TicTacToe app counts, and maybe the infinite beauty of my Crown Imports Mockup with Balsamiq, but no real front end web pages.&lt;br /&gt;&lt;br /&gt;Today I at last learned how it is usually done.  I also learned how bad I suck with photoshop, but thats another story.  &lt;br /&gt;&lt;br /&gt;Basically, you will hire some designer (perhaps even you can do it!) who knows a lot about making pretty things and making things that make sense for people who like things that make sense.  This dude will whip up some totally awesome image of your webpage using photoshop or its equivalent.  Then, after he has perfected every corner and nick nack, he will ship it over to you.  &lt;br /&gt;&lt;br /&gt;Hopefully, it is nicely layered and can be easily sliced, but even if its not you can still get the job done.  &lt;br /&gt;&lt;br /&gt;First, you need to decide which elements are going to be important and static.  For example, most web pages have a fixed header and footer.  You need to identify such items and extract them into their own images.  Make sure you only grab parts that you know are going to be the same on pretty much every page.  &lt;br /&gt;&lt;br /&gt;Next, you find all the semi dynamic elements, like buttons and check boxes and such.  There are some default buttons for most browsers, but you might want special buttons that look super cool and sparkle when you press them.  Find these buttons and make sure you get both the default image, and the pressed image.  You probably always want a mouse over image, so don't let your designer get away easy!&lt;br /&gt;&lt;br /&gt;Once you have these elements, extract them out into their own images, keeping in mind they will be popping up all over the place.&lt;br /&gt;&lt;br /&gt;Then, you spot out all the really dynamic items that are likely to change a lot.  Animations, rotating picture frames, and text boxes/ text labels.  All of these items will of course require different attention, but a few key things to keep in mind are make sure the text sizes the designer used will work in the browser and in your elements,  make sure can include png images (Drew Diller has some useful tools for this), and make sure you rasterize any image you want to be transparent.&lt;br /&gt;&lt;br /&gt;All these super dynamic items are going to require special attention, and there really isn't just one way good way (at least that I have come across) to handle them.&lt;br /&gt;&lt;br /&gt;Finally, all these images and elements need to be shoved into some html so that they can be displayed on your web page.  From what I have seen, some people like to use html tables to organize all the items, where as other people prefer using offsets to line everything up they way they like.  You can do this in either html or css, or both, but css is a nice way to organize all the display information while also giving a lot of extra benefits.&lt;br /&gt;&lt;br /&gt;Thats the general process of setting up the front end of a web page.  After that you can add in some nice JavaScript to give you all the dynamic behavior you need, but make sure you are writing tests for that JS!&lt;br /&gt;&lt;br /&gt;If you have any improvements or suggestions, or even good articles you know of that give further detail on the process, please let me know!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3714840552149734001-3207921563960860183?l=8thlightapprenticeship.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://8thlightapprenticeship.blogspot.com/feeds/3207921563960860183/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/04/day-62.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/3207921563960860183'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/3207921563960860183'/><link rel='alternate' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/04/day-62.html' title='Day 62'/><author><name>Justin</name><uri>http://www.blogger.com/profile/04054497811526894325</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://3.bp.blogspot.com/_snSMUhgzWLE/S0KeHj1cwNI/AAAAAAAAAAQ/f9gAgDyjN2A/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3714840552149734001.post-6030694441601244987</id><published>2010-04-07T21:55:00.000-07:00</published><updated>2010-04-07T22:34:18.583-07:00</updated><title type='text'>Day 61</title><content type='html'>So, I was going to do a blog on how I set up my testing framework for JsUnit, and made a little interface to use it and all... but today I discovered ScrewUnit!  After reading Corey Haines' blog on his stickies project &lt;a href="http://thestickiesproject.wordpress.com/"&gt;&lt;/a&gt;, which was very much about testing JavaScript and all these neat ways to do TDD with it, I am now a complete convert.  It is sooooooo much better than JsUnit.  The error messages actually give line numbers!  How weird is that?&lt;br /&gt;&lt;br /&gt;BlueRidge and ScrewUnit are largely for Rails, but of course ScrewUnit can be used for just JS.  It is an excellent framework, built up almost like RSpec, but of course the syntax is different.  It is run in the browser, and you can just click on a test, or a describe block and it will run it.  Very fantastical. &lt;br /&gt;&lt;br /&gt;Since everything in JS is a object, and you can pass functions back and forth, most of the time mocking out objects is trivial.  In fact, when you design your app using TDD, you can make it soooo versatile that you can just pass in functions or blocks that act as natural parameters, but can also do your test for you.  Hopefully once I start my next project I will have some nice examples to show this in action.&lt;br /&gt;&lt;br /&gt;I also learned a lot of JQuery today.  How weird is it that you can get JQuery in one 6,000 line file?    There are actually lots of JQuery libraries, but I just yoinked the recommended file for now.   Pretty neat tool though.  It will be nice not having to do a document.getElementById("")  all the time, as well as making it easy to add classes to elements for easy styling.  Something that will be exceedingly useful in the project I am about to start.&lt;br /&gt;&lt;br /&gt;Speaking of which.  I just estimated a new project, which is supposed to be a web app?  The final nature of the program is still a bit of a mystery to me, which certainly causes issue with estimating, but it is supposed to be done nearly entirely with JavaScript.  It is also a fairly large application.  Not super complicated, it just has a lot of pages. This is why I wanted to learn a lot about ScrewUnit and JQuery, so that when I started working on this project I wouldn't do it page by page, but I would have the ability to create templates.  It could take ages to finish if I had to design each page anew (there are actually a huge variety of them), but if I can get some really useful objects, then I am pretty sure I can start cruising!&lt;br /&gt;&lt;br /&gt;Also, my classes are starting to become a pain now.  Which is unfortunate.  I have somewhat neglected them recently due to my apprenticeship challenges, and now it is coming back to haunt me!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3714840552149734001-6030694441601244987?l=8thlightapprenticeship.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://8thlightapprenticeship.blogspot.com/feeds/6030694441601244987/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/04/day-61.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/6030694441601244987'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/6030694441601244987'/><link rel='alternate' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/04/day-61.html' title='Day 61'/><author><name>Justin</name><uri>http://www.blogger.com/profile/04054497811526894325</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://3.bp.blogspot.com/_snSMUhgzWLE/S0KeHj1cwNI/AAAAAAAAAAQ/f9gAgDyjN2A/S220/me.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3714840552149734001.post-2953009236717676852</id><published>2010-04-06T09:39:00.000-07:00</published><updated>2010-07-06T15:57:02.597-07:00</updated><title type='text'>8th Light Blog Post: JavaScriptness.prototype = new Class();   From Classical to Prototypal</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://level7blog.typepad.com/.a/6a010534d4f760970c0120a8b2abb1970b-320wi"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 290px; height: 414px;" src="http://level7blog.typepad.com/.a/6a010534d4f760970c0120a8b2abb1970b-320wi" border="0" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;JavaScript is a very misunderstood language.  &lt;br /&gt;&lt;br /&gt;It has gotten a bad rap because most people that use it don't look for its brighter side. Instead they will often look online for some code to copy paste, or they will hack something together using tiny snippets and in-lines to get a drop down menu.&lt;br /&gt;&lt;br /&gt;It is also a very conflicted language.  By nature, JavaScript is a Prototypal language where nearly everything is an Object and there are no classes.   It is also somewhat Functional since all the functions are First Class Functions.  They are just more objects that can be passed into and returned from other functions.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;The issue is that many people try to use JavaScript like they would use Java or C++.  They want a Classical language, where they strictly define all their types and then create instances of those types.  Even though JavaScript can be jammed, beaten, or even mutilated into Classical structures (in fact the book &lt;u&gt;JavaScript: The Definitive Guide&lt;/u&gt; spent a chapter on exactly that), this is betraying its nature and ignoring all the benefits that come with Prototypes.&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt; The Classical Form &lt;/h2&gt;&lt;br /&gt;Lets take a look at a basic Classical implementation of a Square using JavaScript:&lt;br /&gt;&lt;pre style='color:#000000;background:#dddddd;border:1px solid black'&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;function&lt;/span&gt; Square &lt;span style='color:#808030; '&gt;(&lt;/span&gt;side&lt;span style='color:#808030; '&gt;)&lt;/span&gt; &lt;span style='color:#800080; '&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span style='color:#800000; font-weight:bold; '&gt;this&lt;/span&gt;&lt;span style='color:#808030; '&gt;.&lt;/span&gt;side &lt;span style='color:#808030; '&gt;=&lt;/span&gt; side&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#800080; '&gt;}&lt;/span&gt;&lt;br /&gt;Square&lt;span style='color:#808030; '&gt;.&lt;/span&gt;prototype&lt;span style='color:#808030; '&gt;.&lt;/span&gt;area &lt;span style='color:#808030; '&gt;=&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;function&lt;/span&gt; &lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt; &lt;span style='color:#800080; '&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span style='color:#800000; font-weight:bold; '&gt;return&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;this&lt;/span&gt;&lt;span style='color:#808030; '&gt;.&lt;/span&gt;side &lt;span style='color:#808030; '&gt;*&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;this&lt;/span&gt;&lt;span style='color:#808030; '&gt;.&lt;/span&gt;side&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#800080; '&gt;}&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;Square&lt;span style='color:#808030; '&gt;.&lt;/span&gt;prototype&lt;span style='color:#808030; '&gt;.&lt;/span&gt;perimeter &lt;span style='color:#808030; '&gt;=&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;function&lt;/span&gt; &lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt; &lt;span style='color:#800080; '&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span style='color:#800000; font-weight:bold; '&gt;return&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;this&lt;/span&gt;&lt;span style='color:#808030; '&gt;.&lt;/span&gt;side &lt;span style='color:#808030; '&gt;*&lt;/span&gt; &lt;span style='color:#008c00; '&gt;4&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#800080; '&gt;}&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;var&lt;/span&gt; mySquare &lt;span style='color:#808030; '&gt;=&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;new&lt;/span&gt; Square &lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#008c00; '&gt;5&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;You will notice that JavaScript even has a &lt;span style='color:#800000'&gt; new &lt;/span&gt; key word in an attempt to match a Classical implementation.  The function Square () defines a class with a side attribute.  It also has two instance methods, area and perimeter.  We can then create mySquare in almost the same way we might do it in Java.  This is JavaScript though, and the  &lt;span style='color:#800000'&gt; new &lt;/span&gt; works differently in JS.  It creates a new, empty object and then calls the Square() function (or the constructor)  passing the empty object into &lt;span style='color:#800000'&gt; this &lt;/span&gt;.  The constructor then populates that object with the specified behavior before returning it.  This is particularly scary, because if you forget to put &lt;span style='color:#800000'&gt; new &lt;/span&gt; in front of the constructor,  &lt;span style='color:#800000'&gt; this &lt;/span&gt; will refer to the Global Object, as will mySquare (meaning any further changes made to mySquare would also be on the Square 'class').  This is why, if you want to use JS in the Classical way, you should always capitalize the first letter of a constructor.&lt;br /&gt;&lt;br /&gt;Ok, so we have our Square, but say we want to create a square that holds a X or an O.  Well, we would want to inherit the properties of our current Square 'Class' and then add to them.  We might do something like this:&lt;br /&gt;&lt;br /&gt;&lt;pre style='color:#000000;background:#dddddd;border:1px solid black'&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;function&lt;/span&gt; ContainerSquare &lt;span style='color:#808030; '&gt;(&lt;/span&gt;side&lt;span style='color:#808030; '&gt;,&lt;/span&gt; contents&lt;span style='color:#808030; '&gt;)&lt;/span&gt; &lt;span style='color:#800080; '&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span style='color:#800000; font-weight:bold; '&gt;this&lt;/span&gt;&lt;span style='color:#808030; '&gt;.&lt;/span&gt;superclass&lt;span style='color:#808030; '&gt;(&lt;/span&gt;side&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span style='color:#800000; font-weight:bold; '&gt;this&lt;/span&gt;&lt;span style='color:#808030; '&gt;.&lt;/span&gt;contents &lt;span style='color:#808030; '&gt;=&lt;/span&gt; contents&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#800080; '&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;ContainerSquare&lt;span style='color:#808030; '&gt;.&lt;/span&gt;prototype &lt;span style='color:#808030; '&gt;=&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;new&lt;/span&gt; Square&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;ContainerSquare&lt;span style='color:#808030; '&gt;.&lt;/span&gt;prototype&lt;span style='color:#808030; '&gt;.&lt;/span&gt;superclass &lt;span style='color:#808030; '&gt;=&lt;/span&gt; Square&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;ContainerSquare&lt;span style='color:#808030; '&gt;.&lt;/span&gt;prototype&lt;span style='color:#808030; '&gt;.&lt;/span&gt;constructor &lt;span style='color:#808030; '&gt;=&lt;/span&gt; ContainerSquare&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;ContainerSquare&lt;span style='color:#808030; '&gt;.&lt;/span&gt;prototype&lt;span style='color:#808030; '&gt;.&lt;/span&gt;getContents &lt;span style='color:#808030; '&gt;=&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;function&lt;/span&gt; &lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt; &lt;span style='color:#800080; '&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span style='color:#800000; font-weight:bold; '&gt;return&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;this&lt;/span&gt;&lt;span style='color:#808030; '&gt;.&lt;/span&gt;contents&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#800080; '&gt;}&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;var&lt;/span&gt; myContainer &lt;span style='color:#808030; '&gt;=&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;new&lt;/span&gt; ContainerSquare&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#008c00; '&gt;6&lt;/span&gt;&lt;span style='color:#808030; '&gt;,&lt;/span&gt; &lt;span style='color:#0000e6; '&gt;"X"&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;We create a new 'Class' for the ContainerSquare which uses the Square's constructor to define the &lt;span style='color:#000000; '&gt; side &lt;/span&gt; attribute, along with the two instance methods.  We then define our new &lt;span style='color:#000000; '&gt; contents &lt;/span&gt; attribute, along with an accessor method to go with it. &lt;br /&gt;&lt;br /&gt;The &lt;span style='color:#000000; '&gt; ContainerSquare &lt;span style='color:#808030; '&gt;.&lt;/span&gt;prototype &lt;span style='color:#808030; '&gt;=&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;new&lt;/span&gt; Square&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;line sets up a Prototypal inheritance structure so that a ContainerSquare object will be linked to the proper prototype chain.&lt;br /&gt;&lt;br /&gt;The prototype chain is the hierarchy of objects that a method or attribute call will traverse until it finds what it is looking for.  In other words, when I call myContainer.size(), JavaScript will first check to see if the myContainer object has that function.  If not, it will proceed to check the object's prototype, which is the ContainerSquare.  Since ContainerSquare doesn't have the function, next in line is ContainerSquare's prototype, which is just Square.  Square does in fact have a size() function, and since javascript will use the first function it finds, it will use Square's size() function.&lt;br /&gt;&lt;br /&gt;Thus, by setting ContainerSquare's prototype to Square, we inherit any of the attributes or methods of Square.&lt;br /&gt;&lt;br /&gt;Although this all works, and we have successfully mashed a Prototypal language into a Classical scheme, we should try this in the way JavaScript wants to be used.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt; The Prototypal Form &lt;/h2&gt;&lt;br /&gt;We can start with the Square.  There are few pretty simple ways to achieve the same functionality using regular objects and their prototypes, and we will look at two of them.  The first will create a square object that we can use. Then if we need more squares, we can make a copy of that object using its prototype.  The second will create a squareMaker function, which can then be used to pop out new squares.&lt;br /&gt;&lt;br /&gt;&lt;pre style='color:#000000;background:#dddddd;border:1px solid black'&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;var&lt;/span&gt; firstSquare &lt;span style='color:#808030; '&gt;=&lt;/span&gt; &lt;span style='color:#800080; '&gt;{&lt;/span&gt;&lt;br /&gt;  side&lt;span style='color:#800080; '&gt;:&lt;/span&gt; &lt;span style='color:#008c00; '&gt;5&lt;/span&gt;&lt;span style='color:#808030; '&gt;,&lt;/span&gt;&lt;br /&gt;  area&lt;span style='color:#800080; '&gt;:&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;function&lt;/span&gt; &lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt; &lt;span style='color:#800080; '&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span style='color:#800000; font-weight:bold; '&gt;return&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;this&lt;/span&gt;&lt;span style='color:#808030; '&gt;.&lt;/span&gt;side &lt;span style='color:#808030; '&gt;*&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;this&lt;/span&gt;&lt;span style='color:#808030; '&gt;.&lt;/span&gt;side&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span style='color:#800080; '&gt;}&lt;/span&gt;&lt;span style='color:#808030; '&gt;,&lt;/span&gt;&lt;br /&gt;  perimeter&lt;span style='color:#800080; '&gt;:&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;function&lt;/span&gt; &lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt; &lt;span style='color:#800080; '&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span style='color:#800000; font-weight:bold; '&gt;return&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;this&lt;/span&gt;&lt;span style='color:#808030; '&gt;.&lt;/span&gt;side &lt;span style='color:#808030; '&gt;*&lt;/span&gt; &lt;span style='color:#008c00; '&gt;4&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span style='color:#800080; '&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#800080; '&gt;}&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Here, we already have a new and usable square at our disposal.  We don't need to call a constructor and define any types.  We can just take an object and mold it into the form we want.&lt;br /&gt;&lt;br /&gt;Say we want another square though.  We can't just write something like &lt;span style='color:#000000; '&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;var&lt;/span&gt; secondSquare &lt;span style='color:#808030; '&gt;=&lt;/span&gt; firstSquare&lt;span style='color:#800080; '&gt;;&lt;/span&gt; &lt;/span&gt;  because JS passes objects by reference, and thus the second square would just point to the first square.  What we can do, and this is a technique developed by Douglas Crockford, is make a copy of our object by calling a new constructor with a prototype that points to our object. This new contructor creates a new empty object and assigns the values of our old object to the new empty object.  You can do this yourself, or you can use Crockford's technique as follows:&lt;br /&gt;&lt;br /&gt;&lt;pre style='color:#000000;background:#dddddd;border:1px solid black'&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;if&lt;/span&gt; &lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;typeof&lt;/span&gt; Object&lt;span style='color:#808030; '&gt;.&lt;/span&gt;beget &lt;span style='color:#808030; '&gt;!==&lt;/span&gt; &lt;span style='color:#0000e6; '&gt;'function'&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt; &lt;span style='color:#800080; '&gt;{&lt;/span&gt;&lt;br /&gt;  Object&lt;span style='color:#808030; '&gt;.&lt;/span&gt;beget &lt;span style='color:#808030; '&gt;=&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;function&lt;/span&gt; &lt;span style='color:#808030; '&gt;(&lt;/span&gt;o&lt;span style='color:#808030; '&gt;)&lt;/span&gt; &lt;span style='color:#800080; '&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span style='color:#800000; font-weight:bold; '&gt;var&lt;/span&gt; F &lt;span style='color:#808030; '&gt;=&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;function&lt;/span&gt; &lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt; &lt;span style='color:#800080; '&gt;{&lt;/span&gt;&lt;span style='color:#800080; '&gt;}&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;    F&lt;span style='color:#808030; '&gt;.&lt;/span&gt;prototype &lt;span style='color:#808030; '&gt;=&lt;/span&gt; o&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span style='color:#800000; font-weight:bold; '&gt;return&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;new&lt;/span&gt; F&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span style='color:#800080; '&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#800080; '&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;var&lt;/span&gt; secondSquare &lt;span style='color:#808030; '&gt;=&lt;/span&gt; Object&lt;span style='color:#808030; '&gt;.&lt;/span&gt;beget&lt;span style='color:#808030; '&gt;(&lt;/span&gt;firstSquare&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;secondSquare&lt;span style='color:#808030; '&gt;.&lt;/span&gt;side &lt;span style='color:#808030; '&gt;=&lt;/span&gt; &lt;span style='color:#008c00; '&gt;6&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;You can see that we are actually defining an on the fly constructor F, using our object 'o' to define F's prototype (where 'o' is firstSquare). Then we create a new object using that constructor.  This will give us a new copy of our object, with all its attributes and functions.  If we now called &lt;span style='color:#000000; '&gt;secondSquare&lt;span style='color:#808030; '&gt;.&lt;/span&gt;area&lt;span style='color:#808030; '&gt;()&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;/span&gt; we would get 36.&lt;br /&gt;&lt;br /&gt;If you wanted to then make a ContainerSquare, you could simply add a contents attribute to the second square, and then make copies of the secondSquare if you need more Containers.  Keep in mind that since firstSquare is the prototype of secondSquare, if you were to add a contents attribute to firstSquare, you would then have that attribute on secondSquare; however, adding attributes to the secondSquare does not place them on the firstSquare.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt; Spawn More Protolords &lt;/h2&gt;&lt;br /&gt;The other way to get squares would be to make a squareMaker function.  This function will return a new object with whatever attributes you define.  I am also going to show you some closure so that the attributes are private, and only accessible through accessor methods.&lt;br /&gt;&lt;br /&gt;&lt;pre style='color:#000000;background:#dddddd;border:1px solid black'&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;var&lt;/span&gt; squareMaker &lt;span style='color:#808030; '&gt;=&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;function&lt;/span&gt;&lt;span style='color:#808030; '&gt;(&lt;/span&gt;side&lt;span style='color:#808030; '&gt;)&lt;/span&gt; &lt;span style='color:#800080; '&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span style='color:#800000; font-weight:bold; '&gt;return&lt;/span&gt; &lt;span style='color:#800080; '&gt;{&lt;/span&gt;&lt;br /&gt;    getSide&lt;span style='color:#800080; '&gt;:&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;function&lt;/span&gt;&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt; &lt;span style='color:#800080; '&gt;{&lt;/span&gt;&lt;br /&gt;      &lt;span style='color:#800000; font-weight:bold; '&gt;return&lt;/span&gt; side&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span style='color:#800080; '&gt;}&lt;/span&gt;&lt;span style='color:#808030; '&gt;,&lt;/span&gt;&lt;br /&gt;    area&lt;span style='color:#800080; '&gt;:&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;function&lt;/span&gt; &lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt; &lt;span style='color:#800080; '&gt;{&lt;/span&gt;&lt;br /&gt;      &lt;span style='color:#800000; font-weight:bold; '&gt;return&lt;/span&gt; side &lt;span style='color:#808030; '&gt;*&lt;/span&gt; side&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span style='color:#800080; '&gt;}&lt;/span&gt;&lt;span style='color:#808030; '&gt;,&lt;/span&gt;&lt;br /&gt;    perimeter&lt;span style='color:#800080; '&gt;:&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;function&lt;/span&gt; &lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt; &lt;span style='color:#800080; '&gt;{&lt;/span&gt;&lt;br /&gt;      &lt;span style='color:#800000; font-weight:bold; '&gt;return&lt;/span&gt; side &lt;span style='color:#808030; '&gt;*&lt;/span&gt; &lt;span style='color:#008c00; '&gt;4&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span style='color:#800080; '&gt;}&lt;/span&gt;&lt;br /&gt;  &lt;span style='color:#800080; '&gt;}&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#800080; '&gt;}&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;var&lt;/span&gt; anotherSquare &lt;span style='color:#808030; '&gt;=&lt;/span&gt; squareMaker&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#008c00; '&gt;5&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;You will notice that the return value of the squareMaker is almost exactly like how we defined our firstSquare object.  We are just returning the definition of a square, and thats quite awesome.  Another thing you will notice is the bit of closure.  We pass a value into the squareMaker, but it isn't stored anywhere.  It is held in the scope of the squareMaker function, allowing those internal methods to use it, but hiding it from the outside (unlike the side attribute defined in the firstSquare).  This sort of closure is another wicked awesome tool you can use in JS.  In a way, this use of closure is like defining private variables to a class.&lt;br /&gt;&lt;br /&gt;To get the Container functionality we create a containerMaker using the squareMaker, and some more closure, to make a new square object. We then dynamically add a getContents method to provide access to our private contents attribute.&lt;br /&gt;&lt;br /&gt;&lt;pre style='color:#000000;background:#dddddd;border:1px solid black'&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;var&lt;/span&gt; containerMaker &lt;span style='color:#808030; '&gt;=&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;function&lt;/span&gt;&lt;span style='color:#808030; '&gt;(&lt;/span&gt;side&lt;span style='color:#808030; '&gt;,&lt;/span&gt; contents&lt;span style='color:#808030; '&gt;)&lt;/span&gt; &lt;span style='color:#800080; '&gt;{&lt;/span&gt;&lt;br /&gt;  &lt;span style='color:#800000; font-weight:bold; '&gt;var&lt;/span&gt; container &lt;span style='color:#808030; '&gt;=&lt;/span&gt; squareMaker&lt;span style='color:#808030; '&gt;(&lt;/span&gt;side&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;  container&lt;span style='color:#808030; '&gt;.&lt;/span&gt;getContents &lt;span style='color:#808030; '&gt;=&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;function&lt;/span&gt; &lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt; &lt;span style='color:#800080; '&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span style='color:#800000; font-weight:bold; '&gt;return&lt;/span&gt; contents&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span style='color:#800080; '&gt;}&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span style='color:#800000; font-weight:bold; '&gt;return&lt;/span&gt; container&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#800080; '&gt;}&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;var&lt;/span&gt; anotherContainer &lt;span style='color:#808030; '&gt;=&lt;/span&gt; containerMaker&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#008c00; '&gt;6&lt;/span&gt;&lt;span style='color:#808030; '&gt;,&lt;/span&gt; &lt;span style='color:#0000e6; '&gt;"O"&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt; Conclusion &lt;/h2&gt;&lt;br /&gt;So we have now seen two ways to use some of the better parts of JavaScript to get the same functionality that we could get using the Classical scheme.  We can also see some advantages in using JS in its natural form like: getting some closure (which can be exceedingly powerful), very dynamic objects ready to change in anyway you can think of, quickly defined objects which can be used and multiplied, and no need to predefine types.  Pretty sweet right?&lt;br /&gt;&lt;br /&gt;I will admit one slight inefficiency with the two solutions I showed you (although there are ways around this).  Using the squareMaker, or making copies of the objects will make full copies, including the function objects defined inside.  If you use the Classical scheme I showed, you are defining functions on the prototype rather than the object itself, thus there will only be one copy of the function.  &lt;br /&gt;You can, of course, do something similar in the JS scheme, but the optimization doesn't count for all that much in most cases (unless you are doing mobile development where you want to save everything you can!).&lt;br /&gt;&lt;br /&gt;JavaScript isn't a Classical language, but instead a Prototypal language that is powerful enough to mimic a Classical language without breaking a sweat. There is much to be gained by recognizing this fact and changing your mindset to work with it.  Trying to fit a square into a circular hole will just get you stuck.  All languages are unique with a variety of their own advantages, and as good developers we should recognize these differences and reap all the benefits they have to offer.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3714840552149734001-2953009236717676852?l=8thlightapprenticeship.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://8thlightapprenticeship.blogspot.com/feeds/2953009236717676852/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/04/8th-light-blog-post-javascriptnessproto.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/2953009236717676852'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/2953009236717676852'/><link rel='alternate' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/04/8th-light-blog-post-javascriptnessproto.html' title='8th Light Blog Post: JavaScriptness.prototype = new Class();   From Classical to Prototypal'/><author><name>Justin</name><uri>http://www.blogger.com/profile/04054497811526894325</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://3.bp.blogspot.com/_snSMUhgzWLE/S0KeHj1cwNI/AAAAAAAAAAQ/f9gAgDyjN2A/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3714840552149734001.post-7787790376155851326</id><published>2010-04-05T18:22:00.000-07:00</published><updated>2010-04-05T19:16:21.650-07:00</updated><title type='text'>Day 59</title><content type='html'>Java Script!!  So I finished my unbeatable TicTacToe last night... or this morning really.  For only having 4 days (2 of which I was still quite sick) to learn a new language (2 really, since I didn't know HTML very well at all either), to learn and customize a new testing framework, and to create a new TicTacToe program, ai, and interface, it turned out really awesome.  The interface was a little spartan, but it was fully functional with bonus features.&lt;br /&gt;&lt;br /&gt;Though this was probably just because of the tools I was using, I found that I had to be exceedingly careful with Java Script.  There are a lot of little things you can do or forget to do that will really mess you up.  Since the code is all compiled in the browser, and most things in the language are done at run time, the errors can be pretty tough to chase.  Even when using a testing framework like JsUnit, you just don't get very much valuable feedback from error messages.&lt;br /&gt;&lt;br /&gt;As a result, I worked extremely carefully, doing everything slowly and very incrementally.  I never made a huge changes without running my tests again and again, and making sure everything still worked along the way.  This way, most of the errors I had were found within just a few moment by scanning through the recently changed code.  I was also fortunate enough to have all the basic rules of what to do and what not to do fresh in my mind from the&lt;u&gt; Java Script: The Good Parts&lt;/u&gt; book.&lt;br /&gt;&lt;br /&gt;Another thing that I did, that I know saved me in a huge number of cases, is I would very, very frequently stop moving forward and move back two steps.  Rather than adding another test and getting a new feature done, I would look back at what I had and see if I could find any better implementations.  At first I did this just to try to make use of some of the cool benefits of the Prototypal and Functional nature of JavaScript, but after awhile it just didn't make sense not to go back and refactor.  I found time and time again that if I hadn't turned back to refactor when I did, if I had just delayed it for one or two more features, I would have been stuck with a mess.  At that point, I probably would have just kept what I had and continued to develop a messier and messier program.&lt;br /&gt;&lt;br /&gt;It was also really easy.  It just seemed like Java Script is the type of language that &lt;i&gt; wants &lt;/i&gt; to be refactored.  Perhaps its because I wasn't used to it.  But it is also possible, because the language is so straight forward, so direct, and so expressive, that there is almost always a obvious and significant improvement that you can make.&lt;br /&gt;&lt;br /&gt;Testing  JS was a bit of a pain at first.  Actually, it was a bit of a pain most of the time.  Once again, this may be from my lack of experience, but JS and HTML seemed so intertwined that decoupling the logic from the GUI was often a challenge.&lt;br /&gt;&lt;br /&gt;For example, to include a JavaScript file from another JavaScript file you have to actually generate some HTML to include it!  I didn't want to explicitly write out &lt;pre  style="background:#ffffff;color:#000000;"&gt;&lt;span style=" ;color:#808030;"&gt;&amp;lt;&lt;/span&gt;script type&lt;span style=" ;color:#808030;"&gt;=&lt;/span&gt;&lt;span style=" ;color:#800000;"&gt;"&lt;/span&gt;&lt;span style=" ;color:#0000e6;"&gt;text/javascript&lt;/span&gt;&lt;span style=" ;color:#800000;"&gt;"&lt;/span&gt; src&lt;span style=" ;color:#808030;"&gt;=&lt;/span&gt;&lt;span style=" ;color:#800000;"&gt;"&lt;/span&gt;&lt;span style=" ;color:#0000e6;"&gt;another.js&lt;/span&gt;&lt;span style=" ;color:#800000;"&gt;"&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;&gt;&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;&amp;lt;&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;/&lt;/span&gt;script&lt;span style=" ;color:#808030;"&gt;&gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt; right in my first JS file, so instead I added another function to the document object which creates a script element, and plugs in the file you want.  This way, anytime I wanted to include another .js file, I could call that function in my current .js file, and avoid having to write out the script line (which btw is fickle way to do it because certain browsers (like IE7) will read your &lt;&gt; ... &lt; / script &gt;  as the tag for the previous include, and thus will mess everything up.  So you actually would have to do &lt;&gt; ... &lt; / scr + ipt &gt;  so that the tags couldn't be read until they were concatenated by the parser, and thus safe).&lt;br /&gt;&lt;br /&gt;Here is how I did it:&lt;br /&gt;&lt;pre  style="background:#ffffff;color:#000000;"&gt;document&lt;span style=" ;color:#808030;"&gt;.&lt;/span&gt;addAnotherJavaScriptFile &lt;span style=" ;color:#808030;"&gt;=&lt;/span&gt; &lt;span style=" font-weight:bold; color:#800000;"&gt;function&lt;/span&gt; &lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;filePath&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt; &lt;span style=" ;color:#800080;"&gt;{&lt;/span&gt;&lt;br /&gt; &lt;span style=" font-weight:bold; color:#800000;"&gt;var&lt;/span&gt; head &lt;span style=" ;color:#808030;"&gt;=&lt;/span&gt; document&lt;span style=" ;color:#808030;"&gt;.&lt;/span&gt;getElementsByTagName&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;&lt;span style=" ;color:#0000e6;"&gt;"head"&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;[&lt;/span&gt;&lt;span style=" ;color:#008c00;"&gt;0&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;]&lt;/span&gt;&lt;span style=" ;color:#800080;"&gt;;&lt;/span&gt;&lt;br /&gt; &lt;span style=" font-weight:bold; color:#800000;"&gt;var&lt;/span&gt; newScript &lt;span style=" ;color:#808030;"&gt;=&lt;/span&gt; document&lt;span style=" ;color:#808030;"&gt;.&lt;/span&gt;createElement&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;&lt;span style=" ;color:#0000e6;"&gt;'script'&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;span style=" ;color:#800080;"&gt;;&lt;/span&gt;&lt;br /&gt; newScript&lt;span style=" ;color:#808030;"&gt;.&lt;/span&gt;setAttribute&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;&lt;span style=" ;color:#0000e6;"&gt;'type'&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;,&lt;/span&gt; &lt;span style=" ;color:#0000e6;"&gt;'text/javascript'&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;span style=" ;color:#800080;"&gt;;&lt;/span&gt;&lt;br /&gt; newScript&lt;span style=" ;color:#808030;"&gt;.&lt;/span&gt;setAttribute&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;&lt;span style=" ;color:#0000e6;"&gt;'src'&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;,&lt;/span&gt; filePath&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;span style=" ;color:#800080;"&gt;;&lt;/span&gt;&lt;br /&gt; head&lt;span style=" ;color:#808030;"&gt;.&lt;/span&gt;appendChild&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;newScript&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;span style=" ;color:#800080;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style=" ;color:#800080;"&gt;}&lt;/span&gt;&lt;span style=" ;color:#800080;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;document&lt;span style=" ;color:#808030;"&gt;.&lt;/span&gt;addAnotherJavaScriptFile&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;&lt;span style=" ;color:#0000e6;"&gt;"game/computer.js"&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;span style=" ;color:#800080;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This made it easy to include more files, if need be, and was a guaranteed way to work across browsers.&lt;br /&gt;&lt;br /&gt;I am completely exhausted now and am gonna go pass out.  Something I discovered last night/morning - when you are at the point where your brain shuts off (maybe around 2:30 - 3 AM) but you still have to get things done... it might honestly help more to just start trying random things and use guess and check rather than thinking it through.  After I spent about 45 -60 minutes trying to work through a problem step by step, with no success, I decided to just start switching the important variables in a nearly random manner with the key values, and within about 3 minutes I stumbled upon the solution.  Of course in the morning I spotted in almost immediately, but desperate times often require desperate measures.  And hot damn, it got the job done.&lt;br /&gt;&lt;br /&gt;Tomorrow I will go over some of the ways I used JsUnit to test my code.  I will also be handing in my 8thLight Blog submission tomorrow, so that should be interesting.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3714840552149734001-7787790376155851326?l=8thlightapprenticeship.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://8thlightapprenticeship.blogspot.com/feeds/7787790376155851326/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/04/day-59.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/7787790376155851326'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/7787790376155851326'/><link rel='alternate' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/04/day-59.html' title='Day 59'/><author><name>Justin</name><uri>http://www.blogger.com/profile/04054497811526894325</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://3.bp.blogspot.com/_snSMUhgzWLE/S0KeHj1cwNI/AAAAAAAAAAQ/f9gAgDyjN2A/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3714840552149734001.post-7923583781897482611</id><published>2010-04-01T19:02:00.000-07:00</published><updated>2010-04-01T20:25:38.537-07:00</updated><title type='text'>Day 57</title><content type='html'>So apparently driving for 24 hours straight can get you sick.  I got back from my vacation to Florida, where I visited Panama City Beach (Amazing!), and Miami for the Ultra Music Festival, and the drive back was a grand total of about 1,400 miles and 24 hours of driving.  Since we wanted to get back on Monday at a decent time, we drove straight through the night with scattered chunks of restless sleep as me and Tomato switched off.  5 monster energy drinks and a bunch of Oreos later I was home.  &lt;br /&gt;&lt;br /&gt;Unfortunately I must have caught something in Florida, and the lack of sleep mixed with a lack of nutrition and the overall unsanitary environment which is my car, my immune system was crashed.  &lt;br /&gt;&lt;br /&gt;Tuesday I felt under the weather, but was still able to get a lot of reading done.  Colin, I finished the Java Script book, which was excellent by the way, and I can get it to you tomorrow.  If you don't mind, I might want to keep it for reference though because I am going to do my 8th Light blog post on turning a Classical Object Oriented/Class driven batch of code into the true Prototypal nature which is Java Script.&lt;br /&gt;&lt;br /&gt;Wednesday I was in bed for nearly the whole day, my body completely stripped of energy and trying to over come whatever it was I had/have.  A soar throat, relentless coughing, wavering headaches, and a complete lack of energy left me almost completely worthless.  I did still manage to mess around with getting some basic JavaScript and HTML interaction going.  I was pleased to find out that it is actually exceedingly easy, but that was after I angrily grouched about trying to find out why certain things weren't working only to find out that there was a typo in the book!  A simple little mistake, very illusive and sneaky.  The book was defining a literal with one attribute and one function like so:&lt;br /&gt;&lt;br /&gt;&lt;pre style='color:#000000;background:#ffffff;'&gt;var myObject &lt;span style='color:#808030; '&gt;=&lt;/span&gt; &lt;span style='color:#800080; '&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#e34adc; '&gt;&amp;#xa0;&amp;#xa0;&amp;#xa0;&amp;#xa0;&amp;#xa0;&amp;#xa0;&amp;#xa0;&amp;#xa0;value:&lt;/span&gt; &lt;span style='color:#008c00; '&gt;0&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#e34adc; '&gt;&amp;#xa0;&amp;#xa0;&amp;#xa0;&amp;#xa0;&amp;#xa0;&amp;#xa0;&amp;#xa0;&amp;#xa0;increment:&lt;/span&gt; function &lt;span style='color:#808030; '&gt;(&lt;/span&gt;inc&lt;span style='color:#808030; '&gt;)&lt;/span&gt; &lt;span style='color:#800080; '&gt;{&lt;/span&gt;&lt;br /&gt;                &lt;span style='color:#800000; font-weight:bold; '&gt;this&lt;/span&gt;&lt;span style='color:#808030; '&gt;.&lt;/span&gt;value &lt;span style='color:#808030; '&gt;+&lt;/span&gt;&lt;span style='color:#808030; '&gt;=&lt;/span&gt; typeof inc &lt;span style='color:#808030; '&gt;=&lt;/span&gt;&lt;span style='color:#808030; '&gt;=&lt;/span&gt;&lt;span style='color:#808030; '&gt;=&lt;/span&gt; &lt;span style='color:#ffffff; background:#dd0000; font-weight:bold; font-style:italic; '&gt;'number'&lt;/span&gt; &lt;span style='color:#800080; '&gt;?&lt;/span&gt; inc &lt;span style='color:#800080; '&gt;:&lt;/span&gt; &lt;span style='color:#008c00; '&gt;1&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;        &lt;span style='color:#800080; '&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#800080; '&gt;}&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;myObject&lt;span style='color:#808030; '&gt;.&lt;/span&gt;increment&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;document&lt;span style='color:#808030; '&gt;.&lt;/span&gt;writeln&lt;span style='color:#808030; '&gt;(&lt;/span&gt;myObject&lt;span style='color:#808030; '&gt;.&lt;/span&gt;value&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt; &lt;span style='color:#696969; '&gt;// 1&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Can you spot it?  The actual code chunk was a little bit larger, but this is where the error lies. &lt;br /&gt;&lt;br /&gt;Having no real JScript experience, I was completely baffled why my very first test program (after some other simpler stuff like 'Hello World' and such) wasn't working.&lt;br /&gt;&lt;br /&gt;See it yet?&lt;br /&gt;&lt;br /&gt;Its the semicolon after  the &lt;span style='color:#e34adc; '&gt;&amp;#xa0;&amp;#xa0;&amp;#xa0;&amp;#xa0;&amp;#xa0;&amp;#xa0;&amp;#xa0;&amp;#xa0;value:&lt;/span&gt; &lt;span style='color:#008c00; '&gt;0&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;It is supposed to be a comma...  Blast you editors not catching publish mistakes!!&lt;br /&gt;&lt;br /&gt;When defining attributes of a literal you use the format  &lt;br /&gt;{ name: value,&lt;br /&gt;  name2: value2,&lt;br /&gt; name2: value3&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;Oh well...&lt;br /&gt;&lt;br /&gt;Today, although I still felt kinda crappy, I was able to get a lot done.  After playing around a bit longer, getting a better feel for the relationship between JavaScript and HTML, I spiked out a complete TicTacToe interface which was totally playable and such, but no AI.  Now I am working on the real interface using TDD and JSUnit.  JSUnit is a lot like JUnit, but I am making my own test page thingy, which is pretty sweet.&lt;br /&gt;&lt;br /&gt;I have a LOT to do yet, so tomorrow and this weekend are going to be packed tight!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3714840552149734001-7923583781897482611?l=8thlightapprenticeship.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://8thlightapprenticeship.blogspot.com/feeds/7923583781897482611/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/04/day-57.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/7923583781897482611'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/7923583781897482611'/><link rel='alternate' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/04/day-57.html' title='Day 57'/><author><name>Justin</name><uri>http://www.blogger.com/profile/04054497811526894325</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://3.bp.blogspot.com/_snSMUhgzWLE/S0KeHj1cwNI/AAAAAAAAAAQ/f9gAgDyjN2A/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3714840552149734001.post-7835298232559244525</id><published>2010-03-22T19:52:00.000-07:00</published><updated>2010-03-22T20:32:58.803-07:00</updated><title type='text'>Day 54</title><content type='html'>I received my next two apprenticeship challenges today, and I am quite psyched to get them done!  The first is to write a more formal and informational blog post for the 8th Light website.  The second is to write an unbeatable Tic Tac Toe in a language I have never used before.  &lt;br /&gt;&lt;br /&gt;For the blog post I was thinking I would write a tutorial on how to get started on a new Limelight app, but it turns out Paul Pagel already wrote one of those.  It might still be a good idea since Limelight has evolved quite a bit since that blog, but I am not sure yet.&lt;br /&gt;&lt;br /&gt;As for the Tic Tac Toe in a new language, I was thinking I would do it in java script.  Not my first choice in languages, but I will have to learn JS soon anyway to do a project Paul has been asking me to work on, which will be pretty much entirely done in JS, as well as a little html and css.  I kind of want to do it in a functional language like clojure since I have almost no experience working in that frame of mind, but JS would be a twofer.&lt;br /&gt;&lt;br /&gt;Here is the catch though.  I have the next two weeks, plus a weekend, to finish these two tasks, and I will be gone in Florida for the rest of this week!  That means I have only 7 days to get these two tasks done...  I see some rough nights in my near future, and I am damn excited to make the most o them!&lt;br /&gt;&lt;br /&gt; Today I did some more work on Limelight, getting some more tests to pass and fixing up the margins on the text area.&lt;br /&gt;&lt;br /&gt;I also got royally pranked by two esteemed members of the 8th Light team.  I will let them remain unnamed for their treachery, as no good prank is left unanswered.&lt;br /&gt;Basically, I had gone to the DMV today to renew my license, but of course it turns out they are closed on Mondays.  Either way, I  mentioned this at lunch in the office.  Later on, I left my iphone in the bathroom where it was recovered by one of the Craftsman to remain unnamed.  Rather than return it to this unsuspecting, trusting, and apparently oblivious apprentice, this Craftsman, along with another Craftsman, decided to see what fun they can have.&lt;br /&gt;&lt;br /&gt;At about 3 pm I get an email from a Jacob Carson, who says I left my ipone near the Libertyville DMV and they wish to claim the reward (I keep my info and a $50 reward offer as my phones default background).  This completely blows my mind as I specifically remember walking into the office listening to a podcast when I returned from the DMV.  Suddenly I start frantically retracing my steps in my mind trying to find out how this could be possible.  Did I hallucinate having my phone when I came back?  Could I have been listening to my nano?  Was I thinking of a different day?&lt;br /&gt;&lt;br /&gt;I eliminated all these possibilities, and it seemed to me that there remained only one possibility.  Neither Micah nor I use an iPhone case, and thus they appear remarkably similar face down.  I conceived that it was possible I had left mine in the bathroom, which Micah must have later gone into and mistakenly taken my phone for his, at which point he went out for lunch (with a client) at the subway right next to the DMV.  There my phone must have somehow slipped out of his pocket, thus returning it to the place I had been earlier today.  An outrageously unlikely possibility, but Eric Smith wasn't in the office that day, so it must be the case. &lt;br /&gt;&lt;br /&gt;I went down and asked Micah if he had eaten at subway today, and of course he said no.  &lt;br /&gt;&lt;br /&gt;Perplexed... I proceeded on to the bathroom, to the origin of the problem.  Once I step out, there lies my phone on the ground before me. &lt;br /&gt;&lt;br /&gt;It was so obvious, but so very devious.  Touche good sirs, touche.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3714840552149734001-7835298232559244525?l=8thlightapprenticeship.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://8thlightapprenticeship.blogspot.com/feeds/7835298232559244525/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/03/day-54.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/7835298232559244525'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/7835298232559244525'/><link rel='alternate' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/03/day-54.html' title='Day 54'/><author><name>Justin</name><uri>http://www.blogger.com/profile/04054497811526894325</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://3.bp.blogspot.com/_snSMUhgzWLE/S0KeHj1cwNI/AAAAAAAAAAQ/f9gAgDyjN2A/S220/me.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3714840552149734001.post-5106570244401719108</id><published>2010-03-21T23:54:00.000-07:00</published><updated>2010-03-22T07:54:53.798-07:00</updated><title type='text'>Day 53</title><content type='html'>The presentation went quite well, and I got a lot of excellent feedback.   I was also able to talk to my dad and get some more ideas.&lt;br /&gt;Here is what I am going to do:&lt;br /&gt;&lt;br /&gt;First I will lay out a hypothesis on what good code looks like.  I will then choose a batch of code snippets that represent my hypothesis, and I will also select some snippets that are nothing like my hypothesis, as well as some random snippets.&lt;br /&gt;&lt;br /&gt;Next I will collect audience feedback on the snippets and use it to refine my hypothesis.  I will take their suggestions to refine the snippets and further polarize them.  &lt;br /&gt;&lt;br /&gt;After I implement the last group's suggestions, I will show the snippets to a new group and see if there has been any improvement.  From this I can begin to derive some knowledge about what people 'think' good code looks like, and what people will actually rate as good code.&lt;br /&gt;&lt;br /&gt;This discrepancy alone will be valuable because it will demonstrate whether or not we know how to write code that we will like.  As most developer's know, their own code is always excellent and clever... for a few months, but when you come back to it a year later it might not be so good.  This could be because we have gotten much better at writing code, but it could also be because we never really thought it was good in the first place. We merely implemented what we thought were good practices, and not what we actually valued in code.&lt;br /&gt;&lt;br /&gt;Once I have gathered enough data, and refined my methods such that I can accurately predict if people will perceive a code segment as good or bad, I can then work to create a flurry of good code segments.&lt;br /&gt;&lt;br /&gt;With these I can begin offering more talks, still collecting data, but also performing a little Clockwork Orange.  I will be able to show slides with code that I know almost everyone agrees to be good, and use them to 'condition' the audience.&lt;br /&gt;I can perform little experiments where everyone writes a small function at the start of the talk, and then every 5 slides people will pass their functions around and have others rate them.  We will see if the average ratings change, and for what reasons.  We would then write another function half way through, perform the same task, but see if the ratings have improved.&lt;br /&gt;&lt;br /&gt;Lots of value to be gained here, and I don't even know the half of it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3714840552149734001-5106570244401719108?l=8thlightapprenticeship.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://8thlightapprenticeship.blogspot.com/feeds/5106570244401719108/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/03/day-53.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/5106570244401719108'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/5106570244401719108'/><link rel='alternate' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/03/day-53.html' title='Day 53'/><author><name>Justin</name><uri>http://www.blogger.com/profile/04054497811526894325</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://3.bp.blogspot.com/_snSMUhgzWLE/S0KeHj1cwNI/AAAAAAAAAAQ/f9gAgDyjN2A/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3714840552149734001.post-8548722606429726710</id><published>2010-03-18T20:57:00.000-07:00</published><updated>2010-03-18T21:15:10.463-07:00</updated><title type='text'>Day 52</title><content type='html'>Tomorrow I am giving my Lunch and Learn talk!  I am actually pretty excited for it, and to begin my research process.  There is a lot of knowledge and experience out there, and I want to go grab it all!  I got that nice keynote remote app for my iphone, it really helps keep things going smoothly.  There is also the option to have speaker notes on your phone, so if you get caught up at any point you can peak down at your remote and get back on track.&lt;br /&gt;&lt;br /&gt;Since this is the first, of hopefully many future talks on the Code Sense, it will be a little more on the experimental side.  I have created a formula which I think will allow me to gather a lot of important information, and even stir up some debate, but it is still a very fluid concept.  I am hoping to get a lot of feedback tomorrow, hear what the guys think, and drastically refine my process to be prepared for the conferences to come.&lt;br /&gt;&lt;br /&gt;I apologize for not being more on top of my blogs recently, work at the client site has been rather straight forward recently.  Although the feature Micah and I are working on right now is posing some challenges.  I actually spent most of the day turning a very complicated cucumber step into a valuable test.  The acceptance test was very stand alone, and there were none of its kind before so everything has to been done nearly from scratch.   It is also fairly monstrous because, although its purpose is to test only our new feature, its set up is ridiculously complicated.  &lt;br /&gt;&lt;br /&gt;At first, and this is an issue that really became apparent today, I was going to make all the step definitions to walk through the tasks needed to set up the exact circumstances we were testing.  However, this was just catering to our solution.  I was going to set up the circumstances in the database to exactly match what we check for.  But all this really checks is that our solution does what we know our solution does.  This is of course what most unit tests do, but it doesn't work quite the same way with acceptance tests.  Thats why there are nice helpers like Webrat that will set up the database by going through the actual steps a user would go through.  Thus, I began reworking all the steps to set up our scenario the way it would really be set up in production.&lt;br /&gt;&lt;br /&gt;This was much, much more complicated.  Creating the scenario to test what we wrote, going the full route, meant that our test had to touch an enormous portion of the code, and exercise a huge conglomeration of classes.  I honestly think this is going to be one of the longest, if not the longest, of all the client's acceptance tests.  Maybe it should be broken down, or maybe I am missing something, but this is what is required to recreate the circumstances we need to really test the production code.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3714840552149734001-8548722606429726710?l=8thlightapprenticeship.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://8thlightapprenticeship.blogspot.com/feeds/8548722606429726710/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/03/day-52.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/8548722606429726710'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/8548722606429726710'/><link rel='alternate' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/03/day-52.html' title='Day 52'/><author><name>Justin</name><uri>http://www.blogger.com/profile/04054497811526894325</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://3.bp.blogspot.com/_snSMUhgzWLE/S0KeHj1cwNI/AAAAAAAAAAQ/f9gAgDyjN2A/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3714840552149734001.post-4474340157295814765</id><published>2010-03-16T22:26:00.000-07:00</published><updated>2010-03-16T22:48:16.459-07:00</updated><title type='text'>Day 50</title><content type='html'>Micah and I applied to speak at Rails Conf in order to begin my research.  I hope we get accepted as Rails Conf is a huge conference and would be an excellent place to get my name and idea out there.   There is also another conference coming up in Chicago where I will submit my proposal.  This is a smaller conference, but it will have a lot of the Chicagoland software companies like Obtiva and 8th Light.  Whether or not my proposals get accepted, I am excited to begin diving into this research.  I thought out most of my talk for Friday, and I will begin creating the slides tomorrow morning.&lt;br /&gt;&lt;br /&gt;At work today I began chugging through our new feature.  It was quite a pain in the arse because I basically spent all my time trying to decode massive conditional statements.  The code is trying to use a single query on the database to filter out a massive number of objects with very specific requirements.  As a result, there are these overwhelmingly complicated conditional statements that are nested in nests of nests inside a nest cave hidden in a gap in another nest.  Not only are the many levels deep, they also mix together ruby methods, railsy methodness, sql queries, and ruby methods that perform several sql queries and.  Some of them are also inefficient, and could be logically reduced and simplified.  I would do this, but I don't know that the algorithms have a comprehensive test set.  I would make one, but I have to make my own batch of tests to finish the feature, and if I stopped what I was doing to write tests for every chunk of untested code I found, I would never get a feature done.&lt;br /&gt;&lt;br /&gt;Once again, if you have any suggestions for my talk, I would appreciate the input.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3714840552149734001-4474340157295814765?l=8thlightapprenticeship.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://8thlightapprenticeship.blogspot.com/feeds/4474340157295814765/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/03/day-50.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/4474340157295814765'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/4474340157295814765'/><link rel='alternate' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/03/day-50.html' title='Day 50'/><author><name>Justin</name><uri>http://www.blogger.com/profile/04054497811526894325</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://3.bp.blogspot.com/_snSMUhgzWLE/S0KeHj1cwNI/AAAAAAAAAAQ/f9gAgDyjN2A/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3714840552149734001.post-3779144679278393816</id><published>2010-03-15T20:34:00.000-07:00</published><updated>2010-03-15T21:08:59.790-07:00</updated><title type='text'>Day 49</title><content type='html'>Today I was charged with my first of three final challenges for my apprenticeship.  The first one, which needs to be ready by this Friday, will be to deliver a lunch and learn to the 8th Light group.  Though I already gave a lunch and learn on my testing design patterns, this lunch and learn will have to be pristine. I already know what I will be doing, and I will explain this further in a moment.&lt;br /&gt;&lt;br /&gt;At the client site today Micah and I got to see the fruits of our labor.  Our feature is not only out on the live site, but is now in full use.  The feature was the ability to have, make, and use promotions in order to acquire more members.  Today they sent out a massive batch of emails with a promotion code, and in just one day, the promotion dragged in over 2500 new users.  They were quite pleased to say the least. &lt;br /&gt;&lt;br /&gt;We also finished up another feature which sends out reminder emails to people who have subscribed using the promotion.  We then picked up another story which we will work on tomorrow.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;My plan for my first Apprenticeship Challenge:&lt;br /&gt;This is actually something I had started talking about with Micah on Thursday last week, and we discussed it even more today.  I had the idea when Micah was explaining to me how his talk went at the conference he recently spoke at.  One of the activities he did was to show his audience a bunch of code snippets (this was originally done by Michael Feathers, and he actually gave the snippets to Micah) and have them rate each snippet on the quality of the code.  After everyone voted on a snippet they compared everyone answers only to find that everyone had different opinions on which snippets were good and which were bad.&lt;br /&gt;&lt;br /&gt;This got me thinking.  Good code is a very subjective concept.  There are certain things that people will agree help the code, or hurt the code, but for the most part... there is no one formula to write good code.  In fact, great code to one person can be merely decent code to another.  Likewise terrible code to one developer could look very readable and understandable to another.  Such is the debacle.  What is good code?&lt;br /&gt;&lt;br /&gt;My dad recently wrote his &lt;u&gt; Clean Code &lt;/u&gt; book which explained certain characteristics that help to define a process that could lead to good code, but at the same time it was clear that it takes years and years of practice to learn how to develop consistently good, clean code.&lt;br /&gt;&lt;br /&gt;But does it have to?  Maybe there are certain aspects of code that all people find pleasing and understandable.  Maybe there exists certain naming conventions, or certain malleable themes that really help to explain intention.  I don't know, but I am going to find out.&lt;br /&gt;&lt;br /&gt;My plan is to go to conference after conference holding the same talk/workshop where I hold activities showing people code snippets and getting their feed back.&lt;br /&gt;&lt;br /&gt;Here is how I, and this process is open to all suggestions, plan on doing this.&lt;br /&gt;&lt;br /&gt;First, I need a way to get people to come to my talks.  I need an incentive.  Well, how about I offer expert advice on what 'Good Code' looks like!  Damn... I am not qualified.  Thank goodness I know a lot of people that are!   I will collect a wide sample of code snippets and then ask several industry experts which snippets they think are good, and which they think are bad.  Then I will offer to show this information at the end of my talk, after we see what my audience thought about the code.&lt;br /&gt;&lt;br /&gt;Once I get people at my talks, we will proceed to look at a lot of code!  In some fun manner I am yet to create, I will show the audience a code snippet and then ask the following questions:&lt;br /&gt;How is this code?            (possible answers = Awful[0] - Bad[1] - Ok[2] - Good[3] - Excellent[4])&lt;br /&gt;(They have to answer this, and keep their answer no matter how they answer the rest of the questions.  The point is to capture their 'Blink' estimation, or their first impression of the code)&lt;br /&gt;&lt;br /&gt;How is the naming?&lt;br /&gt;How is the use of the language?&lt;br /&gt;How clear are the levels of abstraction?&lt;br /&gt;How complicated?&lt;br /&gt;How consistent and useful is the theme?&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;After we have rated a batch of maybe 5 snippets, we will go back an examine them.  I am not to sure about this part because I want to keep the review until the end of the talk so I get mostly unbiased data, but I don't want people to get bored.  &lt;br /&gt;&lt;br /&gt;Finally when we are all done we will compare what we thought about the code to what Industry Experts thought of the code.&lt;br /&gt;&lt;br /&gt;Throughout the talk I will be asking people for their thoughts on the code, on their reaction to everyone else's opinions, and especially for reactions of the expert's opinions of the code.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;8th Light will be my first group and first experiment.  This will be the trial run to work out the kinks in my future talks and presentations.&lt;br /&gt;&lt;br /&gt;Let me know what you think and please offer suggestions!!!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3714840552149734001-3779144679278393816?l=8thlightapprenticeship.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://8thlightapprenticeship.blogspot.com/feeds/3779144679278393816/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/03/day-49.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/3779144679278393816'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/3779144679278393816'/><link rel='alternate' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/03/day-49.html' title='Day 49'/><author><name>Justin</name><uri>http://www.blogger.com/profile/04054497811526894325</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://3.bp.blogspot.com/_snSMUhgzWLE/S0KeHj1cwNI/AAAAAAAAAAQ/f9gAgDyjN2A/S220/me.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3714840552149734001.post-3111830602771644124</id><published>2010-03-11T21:48:00.000-08:00</published><updated>2010-03-11T22:29:06.294-08:00</updated><title type='text'>Day 47</title><content type='html'>Another successful day as we were able to finish all of our features for this iteration and commit everything in time for deployment.  I have really just been learning a lot about how to become a part of a team.  This has really been my first time doing stand-ups everyday, sharing and hearing about all the progress made and what is yet to be done.  I am now very confident in the stand-ups, and I actually listen to what everyone else has been doing rather than spending all that time preparing what I am going to say! I can interact with the customer, handling their requests and really digging deeper into the requirements of a feature. Not only the technical requirements, but also what the real business requirements are, and the purpose behind every aspect of a feature.  These are most definitely crucial skills in becoming a Craftsman.&lt;br /&gt;&lt;br /&gt;Cruising along in the Rails book, although haven't been able to make too much progress the last few days as I was busy with the new features for work, and then school work yesterday and today.  Unfortunately I have a test tomorrow, though I might take it on  Saturday, so I have to spend some time catching up on that :/  &lt;br /&gt;&lt;br /&gt;Micah and I were having some very interesting conversations today, ranging from massive databases spontaneously becoming self-aware to the foundation of all forms of reason.  &lt;br /&gt;&lt;br /&gt;Can a sufficiently sized database suddenly become aware of its existence?  It would be difficult to back any conclusions on the subject with concrete facts, given that we have no real examples of this happening.  Or do we?  I am tempted to say we do.  Animals over time developed larger and larger brains.  Now a huge brain on a huge animal has to use most of its real-estate on muscular control, but when you have a smaller animal with a large brain, suddenly you have a lot of extra space.  With all this extra space, the brain will just begin to collect data.  Each experience will create new connections between neurons, and thus a new route to the same destination.  These connections are just new associations with different contexts. Once you gather up enough associations or connections between common objects and experiences, you become aware of them.  This is likely how humans became the sentient self aware creatures that we are.  Our minds became sufficiently advanced and could collect a sufficient quantity of knowledge such that we became aware of certain objects that we could manipulate.  Over time this advanced into practical knowledge, and with the creation of forms of language people could share such knowledge.  Then of course writing drastically accelerated this, since the conclusions of new generations no longer had to be gathered independently or passed down through legends and tails.  But all the advancements of our minds came through more associations with new and old ideas.&lt;br /&gt;&lt;br /&gt;Admittedly, I am no neural scientist, but I believe the basic principle behind the function of a human brain and the function of an AI is quite similar.  When I child is trying to figure out the world, how do you teach them what an apple is?  You can't just start saying "Apple" and expect them to understand, unless you give them a context.  You show them an apple, point to it, and say "Apple".  Suddenly an association is formed in their brain between the image of an apple and this strange sound.  Do this a few times and they will recognize it because their brain will have made enough associations between the separate concepts.  Such is similar with an AI.  Take the word "apple" and connect it with 1,000,000 pictures of different apples, give it the ability to discern certain features, and suddenly it can recognize apples (sorta).&lt;br /&gt;&lt;br /&gt;Escalate this.  Take it further and further.  There is already hordes of recognition software out there, as well as images in association with apples.  Naturally there is a huge leap from being able to recognize an apple and becoming self aware, but I would purport that it would be possible, given enough processing power, for a massive database to become self aware.  Certainly not always, but it doesn't seem too far out of the question.  Especially with tons of science fiction novels explaining the entire process like manuals. &lt;br /&gt;&lt;br /&gt;Just some thoughts of a wandering mind.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3714840552149734001-3111830602771644124?l=8thlightapprenticeship.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://8thlightapprenticeship.blogspot.com/feeds/3111830602771644124/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/03/day-47.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/3111830602771644124'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/3111830602771644124'/><link rel='alternate' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/03/day-47.html' title='Day 47'/><author><name>Justin</name><uri>http://www.blogger.com/profile/04054497811526894325</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://3.bp.blogspot.com/_snSMUhgzWLE/S0KeHj1cwNI/AAAAAAAAAAQ/f9gAgDyjN2A/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3714840552149734001.post-1740853622836377826</id><published>2010-03-09T20:36:00.000-08:00</published><updated>2010-03-09T21:08:36.211-08:00</updated><title type='text'>Day 45</title><content type='html'>Today I was left to fend for myself.  Once again, Micah was gone, and I was in Chicago representing 8th Light.  Unlike yesterday, however, where I was mostly left to do my work, today I was really sucked into business.  This is a fast moving company, constantly adding new features and new code, and thus any issue that arrises needs to be taken care of very quickly.  Since Micah was gone, it naturally fell that all questions, in relation to what Micah and I had done recently, came to me.  It started with a quick question, from the CTO, about our design on one of the features. But that rapidly turned into several more questions on if it worked how it should, what the requirements were, and so forth.  Eventually this resulted in a new feature that needed to be added on top of our old one.&lt;br /&gt;&lt;br /&gt;This started it all.  See once the precedence had been set, and people saw that I was standing in for Micah, suddenly I was Micah!  Within just a few minutes, I had become the new 8th Light guy, and all the questions and information that had been going through Micah started coming through me.  Honestly about half the time, when they were telling me all the changes they were making and asking me to get something done, I didn't know what I was supposed to do.  But I took down notes of what they were saying, like I had seen Micah do, and then when I had the time I went and learned what it was they were talking about and what I had to do.  I called Micah several times to try and keep him in the loop, and fortunately not a whole lot had to get done immediately, but there was a lot more going on compared to Monday.  &lt;br /&gt;&lt;br /&gt;By around noon, I had gotten a hang of it.  I felt comfortable answering questions on what we had done, discussing the things that had to be done, and taking responsibility for the work 8th Light was doing.  It was actually pretty awesome.  From yesterday to today my role changed from someone who was just working in the office to someone who was working with the office.  &lt;br /&gt;&lt;br /&gt;Unfortunately I was still having some trouble working out the details of how to test my feature.  So around two, I decided to take a break from that feature (to wait to work on it with Micah), and start the new one that was created today.  This feature came along quite smoothly and I have nearly finished it, hopefully tomorrow on the train I can claim it as complete.  &lt;br /&gt;&lt;br /&gt;It was fun because even though I didn't know exactly how to do it, I knew how to find out, so I ended up learning a lot along with getting to experiment a bit with one of the other guys there on how to do it.  Mostly we just played with the placement of error messages, how they should be formed and where they belong.  Stuff like, whether is should be a full message, or use Rails built in concatenation stuff.  Whether we should stick the messages in the controller or the model, and if inside the model, should it be attached to the model or pushed up higher.  For the most part, it was a lot of quibble matters, but still helpful for me to get a better feel for their program.&lt;br /&gt;&lt;br /&gt;Micah will be back tomorrow, but now I am ready to get a lot more involved on the business end of things.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3714840552149734001-1740853622836377826?l=8thlightapprenticeship.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://8thlightapprenticeship.blogspot.com/feeds/1740853622836377826/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/03/day-45.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/1740853622836377826'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/1740853622836377826'/><link rel='alternate' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/03/day-45.html' title='Day 45'/><author><name>Justin</name><uri>http://www.blogger.com/profile/04054497811526894325</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://3.bp.blogspot.com/_snSMUhgzWLE/S0KeHj1cwNI/AAAAAAAAAAQ/f9gAgDyjN2A/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3714840552149734001.post-2729677990871427513</id><published>2010-03-08T21:53:00.000-08:00</published><updated>2010-03-08T22:02:15.792-08:00</updated><title type='text'>Day 44</title><content type='html'>I need to make this quick since I have to get up quite early.  Commuting really makes you feel how short a day can really be.  When you get up early, and suddenly its time to sleep, you really notice those 3-4 hours lost everyday in transit.  &lt;br /&gt;I've made a fair amount more progress in the Rails book.  I really enjoy how this book teaches you how to make a full project, start to finish, as well as giving you extra side tasks to get on your own.  It seems like this is the most effective way of learning, and is beginning to make me critical of all those classroom lectures, and tedious homework assignments which took your step by step through the learning process without having you actually do anything memorable.  I think that a class structured around a single big project, coupled with many side tasks and activities to help accomplish the main task would be far more effective than flurries of small side projects that you forget the moment you hand them in.&lt;br /&gt;&lt;br /&gt;Tomorrow I should be finishing up my task at the client site.  Micah is gone on a conference so I am in Chicago working alone with the client.  My biggest problem is encountering mental blocks, where some little missing detail prevents me from putting the full puzzle together.  At the moment, this mental block is stopping me from both testing, and seeing how the next step will work.  Hopefully tomorrow morning I will have time enough to collect that detail and fit it into place.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3714840552149734001-2729677990871427513?l=8thlightapprenticeship.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://8thlightapprenticeship.blogspot.com/feeds/2729677990871427513/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/03/day-44.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/2729677990871427513'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/2729677990871427513'/><link rel='alternate' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/03/day-44.html' title='Day 44'/><author><name>Justin</name><uri>http://www.blogger.com/profile/04054497811526894325</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://3.bp.blogspot.com/_snSMUhgzWLE/S0KeHj1cwNI/AAAAAAAAAAQ/f9gAgDyjN2A/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3714840552149734001.post-666289844111835753</id><published>2010-03-07T12:04:00.000-08:00</published><updated>2010-03-08T07:05:51.910-08:00</updated><title type='text'>Day 43</title><content type='html'>At 8th Light, every once in awhile they will have some internal reviews.  It is a way for everyone to learn all they ways they can improve, and to make educated goals to work towards.  I sat in on these reviews, taking notes, and looking for common trends and things that were frequently suggested, or traits that were frequently praised. &lt;br /&gt;&lt;br /&gt;I came up with a batch of traits and qualities that seem to highlight many of the virtues you would find in a Craftsman, as described by 8th Light.  I thought it would be valuable to have such a list so that I don't have to wait for a review to begin setting my own goals!&lt;br /&gt;&lt;br /&gt;*Strong Enthusiasm - Always brightening everyone's mood with your love of what you do.&lt;br /&gt;&lt;br /&gt;*Don't be afraid to ask for help - Especially if you feel rushed, or have bitten off more than you can chew. &lt;br /&gt;&lt;br /&gt;*Ask a lot of questions - Even if you are already a Craftsman, if you are surrounded by other Craftsman, there will always be new things to learn.&lt;br /&gt;&lt;br /&gt;* Discipline Discipline Discipline - The mark of a Craftsman is to have an unfailing discipline to do the right thing.  Whether that is constantly learning new things, or never forgetting what you know, especially when it is hardest to practice. Here are three disciplines:&lt;br /&gt;   * Go Slow - Often it is better to take your time, making sure you do every step correctly, rather than rushing for a temporary spike in productivity.&lt;br /&gt;   * Do it Right - Never stop practicing the things you know that work.  Don't stop testing first. Don't stop refactoring.&lt;br /&gt;   * Being Methodical - Be thorough.  Be certain you are producing the best work that you are capable of through a steady and unflinching practice of virtues.&lt;br /&gt;&lt;br /&gt;* Lists - A Craftsman knows his own productivity, and can gage how much he can get done in a certain time span.  Making lists, getting metrics, and measuring your productivity will help to accomplish this.&lt;br /&gt;&lt;br /&gt;* Understanding the Real Business Intent - It is important to remember you aren't just writing code to fulfill some requirement on a note card, but you are actually creating a product that a business intends to use.  Try to understand what that note card means to them as you transform the requirement into a feature.&lt;br /&gt;&lt;br /&gt;* Recognize your failures of the past so that you can move forward on a new level.  &lt;br /&gt;&lt;br /&gt;* Don't be shy with your ideas - Throw your ideas out there, and then be the biggest critic of them.  You only stand to gain when others see your ideas (unless youzz crazy).&lt;br /&gt;&lt;br /&gt;* Lessons always come at a cost - Stay positive, because if you are getting punished by your mistakes, remember that you also learning from your mistakes.&lt;br /&gt;&lt;br /&gt;These are the big qualities I took from the reviews, and although I am sure there are others, this is a solid list to begin modeling my character against.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3714840552149734001-666289844111835753?l=8thlightapprenticeship.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://8thlightapprenticeship.blogspot.com/feeds/666289844111835753/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/03/day-43.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/666289844111835753'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/666289844111835753'/><link rel='alternate' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/03/day-43.html' title='Day 43'/><author><name>Justin</name><uri>http://www.blogger.com/profile/04054497811526894325</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://3.bp.blogspot.com/_snSMUhgzWLE/S0KeHj1cwNI/AAAAAAAAAAQ/f9gAgDyjN2A/S220/me.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3714840552149734001.post-4889393823514597627</id><published>2010-03-04T18:16:00.000-08:00</published><updated>2010-03-04T21:00:32.102-08:00</updated><title type='text'>Day 42</title><content type='html'>Alas, I missed my opportunity to blog last night.  At least, however, I get to blog on this day of all days.  Somehow, this day is the answer to life, the universe, and everything!  Ok, enough on that.  &lt;br /&gt;&lt;br /&gt;Yesterday and today I learned a lot more about how the client's system really works.  There is a huge amount of depth to it, and I have now dived fair deeper into its inner workings.  Right now I am charged with the task of figuring out how the system sends out mass emails, or individual emails triggered from particular actions, like signing up.  &lt;br /&gt;&lt;br /&gt;There are 3 main components to this functionality and they are:&lt;br /&gt;Redis - A non-relational database that stores data using simple key-value pairs.  The data can only be searched for using the keys.&lt;br /&gt;&lt;br /&gt;Resque - A delayed job system.  It has a queue which you populate with some tasks, and when it has the chance it runs through the queue performing actions of the items.&lt;br /&gt;&lt;br /&gt;ExactTarget - An email client which can be used to send out large quantities of emails, store templates, and keep metrics on the emails it has sent.&lt;br /&gt;&lt;br /&gt;In conjunction, these systems create a convenient way to send out emails to user's for a variety of reasons.&lt;br /&gt;&lt;br /&gt;Basically, the way it works is the Resque system populates a queue in the Redis database with tasks for ExactTarget.&lt;br /&gt;&lt;br /&gt;So when a user, say, signs up for a membership, they need to be sent an email confirmation.  You don't need this to happen immediately, but you do want it to happen within a few seconds.  You don't want the sending of the email to get in the way of maybe the user refreshing the page or something.  So you call Resque.enque( and then some task) so that the task will be put into a simple Redis database that can be accessed later.  Once there is some extra time, the Resque system will start up a worker which will loop through all the items in the queue can calling a perform() method on the particular class or module which represents the task.  The method, in the case of the email, will then gather up the needed information, package it, and then ship it off to the ExactTarget handler.  ExactTarget will then begin the process of sending out this email.  &lt;br /&gt;&lt;br /&gt;There are lots of little steps that happen in between, like transforming the data to a fro xml and json objects, but this is the general gist of it.&lt;br /&gt;&lt;br /&gt;Over all a relative interesting process to conveniently ship out emails attached to specific actions. It seems that almost all of the complexity is in the email client, and Micah has been cooking away at that.  Hopefully be will be able to implement and expand upon the existing system in just a few days.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3714840552149734001-4889393823514597627?l=8thlightapprenticeship.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://8thlightapprenticeship.blogspot.com/feeds/4889393823514597627/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/03/day-42.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/4889393823514597627'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/4889393823514597627'/><link rel='alternate' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/03/day-42.html' title='Day 42'/><author><name>Justin</name><uri>http://www.blogger.com/profile/04054497811526894325</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://3.bp.blogspot.com/_snSMUhgzWLE/S0KeHj1cwNI/AAAAAAAAAAQ/f9gAgDyjN2A/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3714840552149734001.post-4608601801797064634</id><published>2010-03-02T20:34:00.000-08:00</published><updated>2010-03-02T21:38:08.776-08:00</updated><title type='text'>Day 40</title><content type='html'>Wow, its Day 40 of my apprenticeship.  Pretty awesome.  I must say that looking back on all the things I have learned and in what ways I have grown, this apprenticeship has been one of the most, I want to say, 'constructive' experiences of my life.  I am still trying to adapt to my new circumstances, after drastically changing everything in my life in a matter of weeks, but there has been huge growth stemming from my new challenges.  Micah has been an excellent mentor, even though he is always busy, he still finds time to work with me on occasions to make sure I am still progressing.  I have also been exposed to a myriad of different customers, businesses, business related issues, CEOs, CTOs, projects, challenges, and coding environments. Honestly, myriad isn't really the right word, but I hear it used so often these days that I must add to the disaster. &lt;br /&gt;&lt;br /&gt;I would say if I had to name 1 thing I have learned the most about so far, it would be how much I don't know about.  How much is out there, how far behind I really am, and most importantly, the things I need to start doing and learning to catch up and get ahead.&lt;br /&gt;&lt;br /&gt;Today at work I spent a lot of time messing around with cucumber features trying to get them all to work.  Honestly, I feel like I wasn't as effective as I should have, and what I learned seemed uncritical. I did, however, get to speak with the CTO for quite some time, learning all about the path their company went through, what obstacles they faced, and some important things that made them stand out.  One example would be, keep it simple.  There has been a huge amount of research to suggest that people really don't know what they want.  In fact, the more choices people are given, the less happy they tend to end up being with their choice.  Barry Schwartz and his book &lt;u&gt;The Paradox of Choice: More is Less&lt;/u&gt; explain this quite clearly.  Also Dan Gilbert explains how when you have the option between many things, the thing you choice becomes less valuable than if you were just given something with no choice.  To get the context of all this I suggest you watch these TED talks: http://www.ted.com/talks/barry_schwartz_on_the_paradox_of_choice.html&lt;br /&gt;http://www.ted.com/talks/dan_gilbert_asks_why_are_we_happy.html&lt;br /&gt;&lt;br /&gt;Also, this CTO got to meet Malcolm Gladwell, thus me and Malcy are now buds one connection removed.&lt;br /&gt;&lt;br /&gt;I was able to finish more of the rails book today, now familiarized with the concepts behind layouts, models, controllers, and views to some extent.  Migrations are far more clear, and at last I understand the full and awesome power of validations.  In fact, after reading a bit more in the rails book, I was able to make more project on my story for the client.  I got write some sweet tests using some lambdas as well as grasp the purpose and intent of a far greater portion of the code.  It seems like every 10 pages I read I gain 10% more understanding!  If my math is bad enough, by the time I am done, I will have  100% understanding of rails!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3714840552149734001-4608601801797064634?l=8thlightapprenticeship.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://8thlightapprenticeship.blogspot.com/feeds/4608601801797064634/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/03/day-40.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/4608601801797064634'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/4608601801797064634'/><link rel='alternate' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/03/day-40.html' title='Day 40'/><author><name>Justin</name><uri>http://www.blogger.com/profile/04054497811526894325</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://3.bp.blogspot.com/_snSMUhgzWLE/S0KeHj1cwNI/AAAAAAAAAAQ/f9gAgDyjN2A/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3714840552149734001.post-6025397338267003350</id><published>2010-03-01T21:05:00.000-08:00</published><updated>2010-03-01T21:26:19.995-08:00</updated><title type='text'>Day 39</title><content type='html'>A frustrating day, much of which was spent overcoming small obstacles which took far longer than they should have, like trying to merge 2 different basecamp accounts, or getting intellij to work with cucumber.  After working through all of it, I was able to spend a lot of time exploring the clients code.  Still trying to get a feel of their project along with rails.  I find it frequently difficult to tell what is a part of rails, and what is a part of their code.  This is why it is fortunate I finished another 30 pages in the Rails book today.&lt;br /&gt;&lt;br /&gt;To be honest, I had never really read a language specific programming book through and though before, I had only read books on general programming theory and philosophy.  I had also used them for reference and such, but I was really missing out.  Its pretty easy to see how much can be learned by not just reading the book, but working through the examples along side the reading.  It is also very engaging!  Typically I had been sleeping on the train to Chicago, but this morning I was just captured by the book and couldn't stop soaking up what it had to offer.  I hope tomorrow I am able to get at least another 30 pages done, fitting in time around all the stuff I have to read for school =/   &lt;br /&gt;&lt;br /&gt;Much of the reading today was about the Models and working with databases.  I found myself experimenting with every route I could find rather than just following the book's guided path.  Though, this slowed me down, it also gave me a greater feel for the databases.  Trying out both MySQL and SQLite, as well as looking back on a project where I used CouchDb. &lt;br /&gt;&lt;br /&gt;CouchDb is pretty awesome btw, but I most certainly have to do more research of my own on it.  I know its powers, but I don't fully understand its foundation in detail.  &lt;br /&gt;Anyhooo, it is time for sleep so I can work on the train again tomorrow!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3714840552149734001-6025397338267003350?l=8thlightapprenticeship.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://8thlightapprenticeship.blogspot.com/feeds/6025397338267003350/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/03/day-39.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/6025397338267003350'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/6025397338267003350'/><link rel='alternate' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/03/day-39.html' title='Day 39'/><author><name>Justin</name><uri>http://www.blogger.com/profile/04054497811526894325</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://3.bp.blogspot.com/_snSMUhgzWLE/S0KeHj1cwNI/AAAAAAAAAAQ/f9gAgDyjN2A/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3714840552149734001.post-3072467649172258226</id><published>2010-02-28T18:48:00.000-08:00</published><updated>2010-02-28T19:39:55.518-08:00</updated><title type='text'>Day 38</title><content type='html'>U.S. Hockey team lost to the Canadians... I know it's their major sport and all, but I still wanted to beat them again, especially when it counted.&lt;br /&gt;&lt;br /&gt;On another note, this weekend I got some time to first, code with Micah and do some re-factoring.  He, like my dad, does this very methodically and linearly.  Its interesting because it always seems like they know exactly how any re-factoring is going to end up, no matter the complexity.  This is not the case however.  I am quite certain that, although sometimes they might have a feel for what it might end up looking like, or at least catch a whiff of the code smells, most of the time they just start cranking away and out pops a far cleaner chunk of code.  The reason it always seems like they know what it will look like in the end is that they always know the right steps to take in order to get there. &lt;br /&gt;&lt;br /&gt;On saturday Micah and I were looking at this beastly method I had written.  I had briefly tried to re-factor it before, but when I attempted to extract out some smaller methods, they required about 6 parameters each!  After reading &lt;u&gt;Clean Code&lt;/u&gt; I know that methods are better off with fewer parameters, and if you are squeezing in more than 3, something is wrong.  I decided that maybe I should be making a class or method object out of this function, but i hadn't yet gotten around to it.  &lt;br /&gt;&lt;br /&gt;When Micah looked at it, he  didn't think it merited a new class, and instead tried to find good chunks to extract out.  After a few moments, he decided to extract out the same chunks that I had tried.  The difference was that he wasn't at all phased by all the parameters these methods would need.  He motored on.  He began finding simple ways to pull in the parameterized data, step by step reducing the number of inputs to the method.  Once again I was a bit concerned because as we pulled more code into this method, to reduce the param count, I began noticing we were creating some duplication.  But Micah motored on.&lt;br /&gt;&lt;br /&gt;Finally, once we had reduced the input params down to 3, we looked back at the original method and extracted out another chunk of code.  The same thing occurred and there were just too many inputs, except that this time I could see that not only would we be moving a lot of the parameterized data into this new method, we would also be pulling it out of the old one.  Slowly but surely there was less and less duplication, and the data was being moved to where it actually belonged.  Rather than calculating a huge batch of variables at the start of the method and then passing them into the algorithms, we would be calculating only the needed variables at the needed time in their most suitable location.&lt;br /&gt;&lt;br /&gt;In the end the method was drastically simplified, something that always happens when pairing with someone like Micah, and we could finally see what was really going on.&lt;br /&gt;&lt;br /&gt;What was important about this process was learning to persevere.  I think one of the differences between and experienced coder and a novice coder is that even though neither can always see the end result, the experienced coder doesn't get worried when something gets uglier before it gets cleaner.  They keep the goal in mind, and they take the familiar steps that usually lead to a successful result.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;This weekend I also had some time to progress further with the Rails book.  One basic step I thought was important is what to do when starting a project.  It seems to me that you have 3 options when starting a new project.  You can either jump right into it and code without any planning, you can try to plan it from start to finish with a detailed process, or you can just sketch out some rough ideas about how you think it might all work.  Experts in the field seem to suggest that you should just make a rough sketch of what you are doing since one, it is useful to have a picture for both you and the customer, and two, because projects are always going to change from what you originally imagined. &lt;br /&gt;&lt;br /&gt;The Rails book suggests that you make quick sketches with paper and a pencil to layout the feel of the project in a very broad sense.  This will help you see eye to eye with your customer, and it is easy to throw away. &lt;br /&gt;Time to get back to coding another rails example project!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3714840552149734001-3072467649172258226?l=8thlightapprenticeship.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://8thlightapprenticeship.blogspot.com/feeds/3072467649172258226/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/02/day-38.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/3072467649172258226'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/3072467649172258226'/><link rel='alternate' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/02/day-38.html' title='Day 38'/><author><name>Justin</name><uri>http://www.blogger.com/profile/04054497811526894325</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://3.bp.blogspot.com/_snSMUhgzWLE/S0KeHj1cwNI/AAAAAAAAAAQ/f9gAgDyjN2A/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3714840552149734001.post-8154419367596344353</id><published>2010-02-26T07:15:00.000-08:00</published><updated>2010-02-26T07:47:04.374-08:00</updated><title type='text'>Day 37</title><content type='html'>I apologize for being late, last night I got caught up in my Sociology hw and I completely forgot to blog.  Yesterday we committed out work for the completed feature, and it got deployed in the real site.  Pretty cool how fast we were able to add a new feature, and then see it already in place on their website.  We actually got the feature done so fast that they just weren't ready for it, which I believe is what Micah was aiming for.  Suddenly this thing that they thought would take a couple of weeks to finish was done in three days, and they were completely surprised.&lt;br /&gt;&lt;br /&gt;This of course was the good sort of surprise, and they quite quickly brought in one of the people who would be using the feature often so that they could see how it would work.  Unfortunately I had to go to class right as Micah was demoing it, but it went well and apparently they were so impressed that they included it in their deployment right away! &lt;br /&gt;&lt;br /&gt;The client does continuous deployment, and each week they push up to the main server, so every time anyone commits code they have to make sure everything still works.  It seems kind of scary, since you could potentially deploy a secretly bugged build up to the live site, but of course you can always roll back if that turns out to be the case.  It does, however, let them very rapidly develop their site and there is always something new for people use and take advantage of.&lt;br /&gt;&lt;br /&gt;Some interesting things I had never though of occurred when we were setting up the error messages that the user might see. First off, since typically the business logic belongs in the models, we wanted to be passing the error message from the model through the controller. The client had, however, been using generic error messages located in the controller.  If some request failed, they would check to see if the model had populated an object with any error messages, and if there was one, they would print out a generic.  We wanted to print out a more informative and meaningful error, but here is the rub - if you are making an international app, you want to have as few error messages and such as you can so that translating all of them is a straight forward process.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3714840552149734001-8154419367596344353?l=8thlightapprenticeship.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://8thlightapprenticeship.blogspot.com/feeds/8154419367596344353/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/02/day-37.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/8154419367596344353'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/8154419367596344353'/><link rel='alternate' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/02/day-37.html' title='Day 37'/><author><name>Justin</name><uri>http://www.blogger.com/profile/04054497811526894325</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://3.bp.blogspot.com/_snSMUhgzWLE/S0KeHj1cwNI/AAAAAAAAAAQ/f9gAgDyjN2A/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3714840552149734001.post-2745371041784507958</id><published>2010-02-24T21:40:00.000-08:00</published><updated>2010-02-24T22:02:44.452-08:00</updated><title type='text'>Day 36</title><content type='html'>Diving deeper into Rails.  There is a framework used by our client which is both fairly impressive, and quite complicated.  It is powerful in that it handles mostly all of the needed CRUD for controllers, with a very polymorphic and expansive system, but it is also enormously complicated an difficult to understand.  Diving into the code certainly helps, but it sacrifices clarity for density.  None the less, seeing the bare bones for a new framework which, once understood, can drastically increase your productivity, is pretty cool.  I wish I had been there to see its development from birth.&lt;br /&gt;&lt;br /&gt;Working more with Micah today, we got a lot done on our current feature. I revamped my Cucumber knowledge, getting to write a few step definitions and acceptance tests recently.  Cucumber reads quite naturally and is pretty easy to work with.&lt;br /&gt;&lt;br /&gt;I also learned more about the REST convention, and following it conventions for URLs and routing.  This, along with defining a separation between all the dynamic structure of a page (like the Java Script) and the actual html for the page.  The client, in the spirit of being Restful (btw, Rails 3.0 is going to incorporate this by default),  likes to keep a web page as pure html and thus have all the JS in header operations before the page's html is constructed.  In this way, if a browser doesn't accept JS, it can still read the page, its just that requests that require JS wont do anything.  &lt;br /&gt;&lt;br /&gt;Got another 30 pages done with the Rails book as well.  At this point, mostly everything learned is learned through example and practice, thus I am writing a lot of code while reading.  Naturally, I am making the pet project that the book instructs you to make, but along side that I am going to work on my personal website so that I can really put what I learn into practice.  It is very important that I design a Rails App from start to finish on my own so that I can develop a better understanding of the separation between the client's code and built in Rails features.&lt;br /&gt;&lt;br /&gt;I find that it is far more important to understand what is going on, than to merely know what is going on.  The first is far more challenging, but also much more powerful.  It is just like highschool and college physics.  You can memorize all the formulas and equations you want, but come test time if you don't understand the material, you can still get caught up by a tough word problem.  Understanding gives you even more than this, since if you understand the fundamentals of a formula or a problem, then  you can recreate the needed equations on the spot without having them memorized.  The same is true with coding, algorithms, and syntax.  You can memorize and know all you want, but until you understand what you are working with, you wont be able to design creative solutions.&lt;br /&gt;&lt;br /&gt;Sorry for being brief, I have some Sociology hw to do, and I NEED sleep!  Early morning trips to Chicago are taking their toll&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3714840552149734001-2745371041784507958?l=8thlightapprenticeship.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://8thlightapprenticeship.blogspot.com/feeds/2745371041784507958/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/02/day-36.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/2745371041784507958'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/2745371041784507958'/><link rel='alternate' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/02/day-36.html' title='Day 36'/><author><name>Justin</name><uri>http://www.blogger.com/profile/04054497811526894325</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://3.bp.blogspot.com/_snSMUhgzWLE/S0KeHj1cwNI/AAAAAAAAAAQ/f9gAgDyjN2A/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3714840552149734001.post-8775014072762151241</id><published>2010-02-23T21:40:00.001-08:00</published><updated>2010-02-24T00:14:04.614-08:00</updated><title type='text'>Day 35</title><content type='html'>Another excellent day in Chicago.  Today I got to meet the CEO and founder of the current client.  Our introduction was rather brief and, as one would expect, we got straight to business talking about the details of the first feature we are making for them.  &lt;br /&gt;&lt;br /&gt;One of the more interesting issues tackled today was a race condition where several users are trying to access the same expiring option at the same time.  Say we have this sweepstakes going on, and only 10 people get to sign up for.  This sweepstakes is released on twitter, and immediately 50 people apply to sign up, all at virtually the same time.  You have a database which holds only ten redeemable account numbers, but this database is being accessed by several servers at the same time!  On the very last redeemable account, 5 people request the server at such a close interval that each of their servers request the database for the same account at the same time.  You can say that the last account should go to the first request for it, but what these requests are being done in parallel, so the first request in might be the last request out.  Who gets it?  How do you check too see if there is still an account remaining while other servers are grabbing the last account?&lt;br /&gt;&lt;br /&gt;Turns out that Ruby with MySQL has a very nice lock! method that can be called in a model to guarantee only one write can be made to a certain row in the database at any given time. It does something else, but let me query you first.   Is that enough?  &lt;br /&gt;&lt;br /&gt;Even if only one of these 5 servers was able to write to this database row, thus editing it to grabbing the last account, the 4 other servers could still read the row and therefore determine (if reading just before the row was being edited, but after it was locked) there is still an account left.  The remaining servers might then try to edit the row the moment the lock was released, which could cause some issues.&lt;br /&gt;&lt;br /&gt;Its not enough to simply lock the writing of this row, but you also must lock it so that nothing else can be reading it while it is being written to.  In this way, the first of the 5 servers would lock the row, at which point the other 4 servers would have to wait until the 5th server officially had the last account before they could read the row.&lt;br /&gt;&lt;br /&gt;Fortunately this is what the lock! method does, when using the LOCK IN SHARE MODE.  This along with using a Ruby transaction (which is an all or nothing access for an object), quite nicely resolved this race condition.&lt;br /&gt;&lt;br /&gt;Micah wrote up a script to test this (because unfortunately rspec performs its tests using transactions rather than actually accessing the database, thus making testing this race condition virtually impossible in the typical form) which would create 5 Ruby forks (not threads since Ruby threads all run through the same interpreter, and thus are really actually just one thread [ Not in JRuby though!!]) which would all request the last redeemable account at the same time.  We confirmed that it worked by seeing a couple of forks grabbing the last account while only using Ruby transactions, and then confirmed the lock! worked by running this script again and again.  Micah actually did a cute little command to run the script 30 times, and it never failed even through that.  Though it seems nearly impossible to be certain that it worked, it seems quite likely that it works.&lt;br /&gt;&lt;br /&gt;Start reading the Agile Web Development With Rails - Third Edition, and got about 30 pages in tonight.  I am really glad I started reading this after creating my Socket Server because not only does it solidify my server knowledge, it also gives me a new realm of connections to make so that I better understand how Rails really works.&lt;br /&gt;&lt;br /&gt;A quick overview of what I have gone through so far.  &lt;br /&gt;Chapter 1 was mostly all intros and talk about how Rails have developed and how this book will be structured, so never mind that.  Chapter 2 is where the details begin.&lt;br /&gt;&lt;br /&gt;Chapter 2 revolves around explaining MVC.&lt;br /&gt;&lt;br /&gt;MVC is of course the Model View Controller framework that Rails, along with many many other applications, uses.&lt;br /&gt;&lt;br /&gt;2.1&lt;br /&gt;&lt;br /&gt;MVC - Model View Controller&lt;br /&gt;&lt;br /&gt;Model - handles all data, data interaction, and business rules.  Gate keeper and data store.&lt;br /&gt;&lt;br /&gt;View - UI, normally based on model.  Never handles incoming data. Different views for same model.&lt;br /&gt;&lt;br /&gt;Controllers - The corner stone of application.  Receive requests, handles them using the models, display results using views.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Handling requests:&lt;br /&gt;&lt;br /&gt;http://my.url/store/add_to_cart/123&lt;br /&gt;&lt;br /&gt;store - name of controller&lt;br /&gt;add_to_cart - name of action&lt;br /&gt;123 - extracted into id&lt;br /&gt;&lt;br /&gt;The controller find's the user shopping cart and product (model)&lt;br /&gt;Tells the cart to add the product&lt;br /&gt;Shows updated info to user&lt;br /&gt;&lt;br /&gt;2.2&lt;br /&gt;&lt;br /&gt;Models--&lt;br /&gt;Organizing data (ObjectOriented vs relation databases):&lt;br /&gt;&lt;br /&gt;Database-centric - Bringing data and database modifications directly into production code.  Ewwwwww&lt;br /&gt;&lt;br /&gt;Object-Relational Mapping - Uses OO to control data.  Maps Classes to tables,  objects to rows, and columns to attributes.&lt;br /&gt;&lt;br /&gt;Active Record - Follows the ORM model.&lt;br /&gt;&lt;br /&gt;2.3&lt;br /&gt;&lt;br /&gt;Views --&lt;br /&gt;Often just batches of HTML, but typically wish to have some actions.  Actions provided by action methods in the controllers.  &lt;br /&gt; Dynamic content done in 3 ways using templates:&lt;br /&gt;  ERb (embedded ruby) &lt;br /&gt;  XML Builder&lt;br /&gt;  RJS (JavaScript) - Ajax&lt;br /&gt;&lt;br /&gt;Controllers --&lt;br /&gt;Responsibilities - Routing external requests (friendly URLs), Managing Caching, Managing helper modules (for views), Managing sessions&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Certainly a quick summary of the chapter, but if you want to know more details, the book itself it a pretty smooth read while retaining high content.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3714840552149734001-8775014072762151241?l=8thlightapprenticeship.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://8thlightapprenticeship.blogspot.com/feeds/8775014072762151241/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/02/day-35.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/8775014072762151241'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/8775014072762151241'/><link rel='alternate' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/02/day-35.html' title='Day 35'/><author><name>Justin</name><uri>http://www.blogger.com/profile/04054497811526894325</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://3.bp.blogspot.com/_snSMUhgzWLE/S0KeHj1cwNI/AAAAAAAAAAQ/f9gAgDyjN2A/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3714840552149734001.post-1738239435741090661</id><published>2010-02-22T20:52:00.000-08:00</published><updated>2010-02-23T07:06:06.670-08:00</updated><title type='text'>Day 34</title><content type='html'>Today we were at their office in Chicago meeting all of the guys of the new Client, getting the source code up to speed on our computers, and learning what we will be doing for them.  I must say, a pretty amazing company.  Their relaxed, but hard working on target mindset is extremely refreshing and conducive to an effective working environment.  Their website has been wildly successful and is saving tons of people tons of money, while bringing companies tons of customers and tons of money.  Where's the fault?  It actually comes in when certain companies start saying "You need to set a limit! Too many customers!"  Ayyy, there's the rub.&lt;br /&gt;&lt;br /&gt;Getting started on a new existing Rail's project is always a pain.  Even more so than Java or plain Ruby projects.  On every Rail's project there is a new set of 10-20 gems and plugins that have to be settled.  Each gem with their own specific version, frequently not the most up to date version either.  On top of this, there is a wide selection of databases that can be used, and always require some love and finagling to make them happy.  &lt;br /&gt;&lt;br /&gt;I spent around 4-5 hours today getting my situation up to date and on track with their environment.  Micah was able to get going in about 2 1/2 or so hours, so he got a good look at the code and a fair feel for what we will have to do to complete the feature.   On a happier note though, the guys here said we got up and ready faster than anyone else before us, who often took up to a week!&lt;br /&gt;&lt;br /&gt;Most of my time was spent getting MySQL working.  I jump from error to error, then fixed stuff, but went back to the same error as before.  It mostly all stemmed back to not being on Snow Leopard, but the default download for mysql was using the x86_64 archive.  Later on I figured this out, went back and got the right version - i386 archive,  but still had issues with missing refs.  &lt;br /&gt;&lt;br /&gt;One really useful tool I learned about is the RVM.  Ruby Version Manager.   It can switch back and forth between different Ruby environments, with different versions of Ruby (like the core Ruby or Ruby Enterprise Edition  (which is mega faster)), different gems and gem versions.  With just a simple command like:  rvm ree  I could switch to Ruby Enterprise Edition with all the gems I needed for this client, and then with: rvm system  I could swap back to my normal Ruby environment.   Uber powerful.&lt;br /&gt;&lt;br /&gt;Tomorrow we will start planning out our iterations and our story cards.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3714840552149734001-1738239435741090661?l=8thlightapprenticeship.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://8thlightapprenticeship.blogspot.com/feeds/1738239435741090661/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/02/day-34.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/1738239435741090661'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/1738239435741090661'/><link rel='alternate' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/02/day-34.html' title='Day 34'/><author><name>Justin</name><uri>http://www.blogger.com/profile/04054497811526894325</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://3.bp.blogspot.com/_snSMUhgzWLE/S0KeHj1cwNI/AAAAAAAAAAQ/f9gAgDyjN2A/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3714840552149734001.post-7174035553748694105</id><published>2010-02-21T21:22:00.000-08:00</published><updated>2010-02-23T07:14:10.284-08:00</updated><title type='text'>Day 33</title><content type='html'>I finished the HTTP server on time for my demo on Friday, which went smoothly.  This week Micah and I will be in Chicago doing some work for a web based company.  Their website hosts coupons for businesses.  A business, say Gino's East will post a possible coupon on their website for maybe 50% off a large pizza, and if 300 people sign up for the coupon, then Gino's will carry through with it.  Anyone who wants the coupon can sign up for it on the day it is hosted, but tomorrow brings a new coupon and the end to the sales of the old one. They have been very successful, and their site is pretty awesome.&lt;br /&gt;&lt;br /&gt;Ok, I will just share some of the basic tid-bits of how the server worked.&lt;br /&gt;&lt;br /&gt;I made a very very basic site for the server to host in order to test to make sure it worked.  This site had certain requirements which my server had to support.  It had to have a few basic pages (like the initial page '/index.html and a homepage), catch incorrect URL requests and respond with a 404, support common MIME types (images, pdf, even small video files), have an Echo page which would spit back out the arguments past to it via the URL, and handle several requests at the same time.&lt;br /&gt;&lt;br /&gt;Hosting the basic pages was fairly straight forward once you know how to format a request and response.  The most basic request header looked like this:&lt;br /&gt;&lt;br /&gt;GET /index.html HTTP/1.1&lt;br /&gt;Host: localhost:80&lt;br /&gt;&lt;br /&gt;The form is   Request type     page requested   protocol&lt;br /&gt;Host:   resource name : port&lt;br /&gt;&lt;br /&gt;The resource name could be localhost  or could ben something like www.google.com.&lt;br /&gt;&lt;br /&gt;The most basic response header would look like this:&lt;br /&gt;&lt;br /&gt;HTTP/1.1 200 OK&lt;br /&gt;Content-Type: text/html&lt;br /&gt;Content-Length: 500&lt;br /&gt;&lt;br /&gt;The form is  Protocol   response code and response type  (for an error page the code would be 404  and type Not Found)&lt;br /&gt;&lt;br /&gt;Typically there is a flurry of other information like cookie and browser information.  After the header would follow the body of the response.&lt;br /&gt;&lt;br /&gt;For my home page, and like I said... super basic pages, the response body would just be some html like&lt;br /&gt;&lt;%html&gt;&lt;%h1&gt;This is the home page!&lt;/%h1&gt;&lt;/%html&gt;&lt;br /&gt;&lt;br /&gt;Sweet website right?&lt;br /&gt;&lt;br /&gt;But then for a page with an image or pdf there were a lot of extra steps.  First, in the response header you have to figure out what the page's MIME type will be, and then you have to get the size of the page.  An image would be like image/jpeg or image/gif, and then you send the size viz the Content-Length param.&lt;br /&gt;&lt;br /&gt;Once you ship the header, you have to send the response body, which will contain the image file.  TCP/IP sends all files in little chunks, so you can't just ship the whole image at once.  You have to break it up into individual bytes and stream it onto an output stream.   This was a bit of a pain at first because even with some of the built in Java support for these IO streams, it can be a bit tricky figuring out which types to use, and how to make all the needed conversions.&lt;br /&gt;&lt;br /&gt;For example, to send an image as a byte stream given only its location there are several steps you need to take.  First, in Java, you need to create a File object for the image.  For this, you need a File Output Stream to read the file and put it into local memory.  Then you need to turn that file into a byte stream, and get its size.  Finally you write that byte stream into a Byte Array Output Stream, which can then ship the bytes onto your Socket's output stream.&lt;br /&gt;&lt;br /&gt;A fairly lengthy process to merely ship photo's from computer to computer, but it is reliable and will work with virtually any file type.&lt;br /&gt;&lt;br /&gt;At last, making an echo page is pretty simple.  When you receive a request with some input params, they are tide into the URL something like this:&lt;br /&gt;www.justinmmartin.com:80/index.html?a=1&amp;amp;b=2&amp;amp;c=3&lt;br /&gt;&lt;br /&gt;where a,b,c are the params.  The request has the params in the initial GET line:&lt;br /&gt;&lt;br /&gt;GET /index.html?a=1&amp;amp;b=2&amp;amp;c=3 HTTP/1.1&lt;br /&gt;&lt;br /&gt;So you can just parse out the string, snatch up the params by splitting the string on certain characters, and then add them back into HTML to be shipped out in your response.&lt;br /&gt;&lt;br /&gt;A relatively broad summary for what needs to be done to create a basic server, but hopefully you get the picture.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3714840552149734001-7174035553748694105?l=8thlightapprenticeship.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://8thlightapprenticeship.blogspot.com/feeds/7174035553748694105/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/02/day-33.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/7174035553748694105'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/7174035553748694105'/><link rel='alternate' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/02/day-33.html' title='Day 33'/><author><name>Justin</name><uri>http://www.blogger.com/profile/04054497811526894325</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://3.bp.blogspot.com/_snSMUhgzWLE/S0KeHj1cwNI/AAAAAAAAAAQ/f9gAgDyjN2A/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3714840552149734001.post-8893947809547191904</id><published>2010-02-19T02:00:00.000-08:00</published><updated>2010-02-19T02:19:22.449-08:00</updated><title type='text'>Day 32</title><content type='html'>I learned a LOT today... well yesterday, last night, and this morning.   Basically, the last few days I learned all about how to make a Socket Server and how HTTP requests work, but I really didn't know how to make them happen.  Today, I learned that.  There is a massive difference between understanding the principles behind how something should work, and the understanding required to actually make that something work.  &lt;br /&gt;Today I learned how an HTTP server, and all the communication involved in the process, works - in practice.  &lt;br /&gt;I learned how to form real, and usable requests and response.  &lt;br /&gt;I learned how to use them to display different types of html pages.  &lt;br /&gt;I learned how to link them to a file system, such that a request routes directly to a directory, and from it, derives the appropriate response.  &lt;br /&gt;I learned how to run multiple connections.  &lt;br /&gt;I re-learned how to make a build.xml file to run an ant process so that I can snatch out a .jar file.  &lt;br /&gt;I learned about pretty much every type of input and output stream Java has to offer, as well has how to link them up in unison to move files around in efficient manners.&lt;br /&gt;I learned how to use chunked response, although not in practice... But i am pretty sure I could put it into practice in a reasonable amount of time.&lt;br /&gt;I learned how to send different MIME types across the web so that I can display images and such from a local file onto a browser.&lt;br /&gt;&lt;br /&gt;And I learned a whole lot of other stuff in order to learn how to learn what I needed to learn!  This is likely the most important thing I derived from the long day of hardship.&lt;br /&gt;&lt;br /&gt;Here is the rub... its now like 4:15 AM and I am not quite finished implementing all the mime types (though pretty close) or being able to pick up parameters (another fairly short matter).  I gotta have it done by about noon tomorrow so... Imma sleep and blog more this weekend when my brain can recollect details.&lt;br /&gt;&lt;br /&gt;P.S.     telnet is  pretty sweet terminal command.  check it out&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3714840552149734001-8893947809547191904?l=8thlightapprenticeship.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://8thlightapprenticeship.blogspot.com/feeds/8893947809547191904/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/02/day-32.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/8893947809547191904'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/8893947809547191904'/><link rel='alternate' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/02/day-32.html' title='Day 32'/><author><name>Justin</name><uri>http://www.blogger.com/profile/04054497811526894325</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://3.bp.blogspot.com/_snSMUhgzWLE/S0KeHj1cwNI/AAAAAAAAAAQ/f9gAgDyjN2A/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3714840552149734001.post-6222351874875999483</id><published>2010-02-17T21:05:00.000-08:00</published><updated>2010-02-17T22:36:13.221-08:00</updated><title type='text'>Day 31</title><content type='html'>I am just going to title this post because I know the connotation it will inevitably invoke.&lt;br /&gt;&lt;span style="font-weight:bold;"&gt; How the SocketServer services the Client's Socket&lt;/span&gt;&lt;br /&gt;I apologize if you find this unnecessary or inappropriate, but I can only imagine what is going through Kichu's head while he reads this.&lt;br /&gt;&lt;br /&gt;Creating a multi-threaded system is always interesting.  It is extremely difficult to be certain none of your threads will collide.  It is virtually impossible to be certain if you have no tests.  There are always a multitude of unexpected errors, race conditions, and concurrent modification issues (yes yes, I know this is a java error name) that can pop out and surprise you... or worse, lurk around until your not paying attention and then bite you in the a**.   This is why it is important to be consistently coding in a thread safe manner, using locks and semaphores when you can, testing lots of possible variations of how the code can be run, and running your tests several times in a row each time you make a threading change.&lt;br /&gt;&lt;br /&gt;For my Socket Server I had to spawn up a flurry of threads to run many simultaneous actions.  So first, a brief over view of how the Socket Server worked, and then I will explain how I remained thread safe.&lt;br /&gt;&lt;br /&gt;Some application would start up the Socket Server, which would create a Server Socket to watch a specific port.  Then presumably this application would like to be able to accomplish others tasks while the Server Socket is simultaneously monitoring its specific port, thus the Server Socket needs to sit in its own thread called the ServerSocketThread. &lt;br /&gt;&lt;br /&gt;The Server Socket is in a constant loop, checking to see if any Client Sockets have tried to talk on the specified port, for as long as the Server Socket is let to be open.  If a Client Socket attempts to connect on this port, the Server Socket needs to accept the client's request.  To accept, the Server Socket must create a server side socket to pair with the Client Socket, and then instruct this server side socket, called the SocketServicer, to serve the Client Socket.  The SocketServicer has to serve the Client Socket while the Server Socket is still monitoring the port, thus a new thread, called a nobleServiceThread, must be created for every single Client Socket- SocketServicer pair. &lt;br /&gt;&lt;br /&gt;Once the SocketServicer has finished serving the Client Socket,  the nobleServiceThread will automatically close itself and end the connection as well as terminate itself. &lt;br /&gt;&lt;br /&gt;If the Server wants to close one of it's Server Sockets, the Server Socket will have to make sure all of it's SocketServicers and nobleServiceThreads are closed and terminated before it can be closed.  There must, therefore, be a list of all of the nobleServiceThreads.  The Server Socket must loop through this nobleServiceThreads list and terminate each thread.  To simply kill an active Socket, however, would mean you are suddenly cutting a client off in the middle of an interaction, and that is bad practice.  Thus the nobleServiceThreads must first be given a chance for the Socket to finish and close up before they are cut off, and as such must be given a TimeOut Period before they are automatically cut off regardless of status.  Once cut off, the deactive thread must be removed from the list.&lt;br /&gt;&lt;br /&gt;Ok, now down to business.&lt;br /&gt;&lt;br /&gt;There are a few smaller and somewhat trivial threading issues, some of which involving testing, but I am just going to go over the biggest and most interesting one I encountered.&lt;br /&gt;&lt;br /&gt;So we have this list of nobleServiceThreads that each are running a Socket which can finish at any time.  We also have a Server Socket which might want to close at any time, thus having to close all of the nobleServiceThreads.  Thus, right away we can see the race condition.  Can you guess what it is? &lt;br /&gt;If, while looping through and closing the list of nobleServiceThreads, a Socket finishes it's interactions and decides to close, it could potentially remove itself from the list we are iterating through. This means we could be trying to remove a thread that is at the same time removing itself. Lets look at some code:&lt;br /&gt;&lt;br /&gt;First, here is the Server Socket's thread/loop which watches a port and accepts incoming Client Sockets:&lt;br /&gt;&lt;pre  style="background:#ffffff;color:#000000;"&gt;private Thread makeSocketThread&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;br /&gt; &lt;span style=" ;color:#800080;"&gt;{&lt;/span&gt;&lt;br /&gt;   &lt;span style=" font-weight:bold; color:#800000;"&gt;return&lt;/span&gt; new Thread&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;new Runnable&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;br /&gt;   &lt;span style=" background:#dd0000; font-weight:bold; font-style:italic; color:#ffffff;"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;     public &lt;span style=" font-weight:bold; color:#800000;"&gt;void&lt;/span&gt; run&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;br /&gt;     &lt;span style=" background:#dd0000; font-weight:bold; font-style:italic; color:#ffffff;"&gt;{&lt;/span&gt;&lt;br /&gt;       &lt;span style=" font-weight:bold; color:#800000;"&gt;while&lt;/span&gt; &lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;serverSocketOpen&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;br /&gt;       &lt;span style=" background:#dd0000; font-weight:bold; font-style:italic; color:#ffffff;"&gt;{&lt;/span&gt;&lt;br /&gt;         runServerSocket&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;span style=" ;color:#800080;"&gt;;&lt;/span&gt;&lt;br /&gt;       &lt;span style=" background:#dd0000; font-weight:bold; font-style:italic; color:#ffffff;"&gt;}&lt;/span&gt;&lt;br /&gt;     &lt;span style=" background:#dd0000; font-weight:bold; font-style:italic; color:#ffffff;"&gt;}&lt;/span&gt;&lt;br /&gt;   &lt;span style=" background:#dd0000; font-weight:bold; font-style:italic; color:#ffffff;"&gt;}&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;span style=" ;color:#800080;"&gt;;&lt;/span&gt;&lt;br /&gt; &lt;span style=" ;color:#800080;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt; private &lt;span style=" font-weight:bold; color:#800000;"&gt;void&lt;/span&gt; runServerSocket&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;br /&gt; &lt;span style=" ;color:#800080;"&gt;{&lt;/span&gt;&lt;br /&gt;   try&lt;br /&gt;   &lt;span style=" ;color:#800080;"&gt;{&lt;/span&gt;&lt;br /&gt;     Socket clientSocket &lt;span style=" ;color:#808030;"&gt;=&lt;/span&gt; serverSocket&lt;span style=" ;color:#808030;"&gt;.&lt;/span&gt;accept&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;span style=" ;color:#800080;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;     Thread servicerThread &lt;span style=" ;color:#808030;"&gt;=&lt;/span&gt; new Thread&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;new ServiceRunner&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;clientSocket&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;span style=" ;color:#800080;"&gt;;&lt;/span&gt;&lt;br /&gt;     nobleServiceThreads&lt;span style=" ;color:#808030;"&gt;.&lt;/span&gt;add&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;servicerThread&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;span style=" ;color:#800080;"&gt;;&lt;/span&gt;&lt;br /&gt;     servicerThread&lt;span style=" ;color:#808030;"&gt;.&lt;/span&gt;start&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;span style=" ;color:#800080;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;   &lt;span style=" ;color:#800080;"&gt;}&lt;/span&gt;&lt;br /&gt;   catch &lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;IOException e&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;br /&gt;   &lt;span style=" ;color:#800080;"&gt;{&lt;/span&gt;&lt;br /&gt;   &lt;span style=" ;color:#800080;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style=" ;color:#800080;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;We can see that as long as the Server Socket is open, it will continue to make new threads for incoming Clients.&lt;br /&gt;&lt;br /&gt;Here is what the nobleServiceThread does:&lt;br /&gt;&lt;br /&gt;&lt;pre  style="background:#ffffff;color:#000000;"&gt;&lt;span style=" font-weight:bold; color:#800000;"&gt;private&lt;/span&gt; &lt;span style=" font-weight:bold; color:#800000;"&gt;class&lt;/span&gt; ServiceRunner &lt;span style=" font-weight:bold; color:#800000;"&gt;implements&lt;/span&gt; Runnable&lt;br /&gt; &lt;span style=" ;color:#800080;"&gt;{&lt;/span&gt;&lt;br /&gt;   &lt;span style=" font-weight:bold; color:#bb7977;"&gt;Socket&lt;/span&gt; clientSocket&lt;span style=" ;color:#800080;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;   &lt;span style=" font-weight:bold; color:#800000;"&gt;public&lt;/span&gt; ServiceRunner&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;&lt;span style=" font-weight:bold; color:#bb7977;"&gt;Socket&lt;/span&gt; clientSocket&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;br /&gt;   &lt;span style=" ;color:#800080;"&gt;{&lt;/span&gt;&lt;br /&gt;     &lt;span style=" font-weight:bold; color:#800000;"&gt;this&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;.&lt;/span&gt;clientSocket &lt;span style=" ;color:#808030;"&gt;=&lt;/span&gt; clientSocket&lt;span style=" ;color:#800080;"&gt;;&lt;/span&gt;&lt;br /&gt;   &lt;span style=" ;color:#800080;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;   &lt;span style=" font-weight:bold; color:#800000;"&gt;public&lt;/span&gt; &lt;span style=" ;color:#bb7977;"&gt;void&lt;/span&gt; run&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;br /&gt;   &lt;span style=" ;color:#800080;"&gt;{&lt;/span&gt;&lt;br /&gt;     &lt;span style=" font-weight:bold; color:#800000;"&gt;try&lt;/span&gt;&lt;br /&gt;     &lt;span style=" ;color:#800080;"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;       applicationServer&lt;span style=" ;color:#808030;"&gt;.&lt;/span&gt;serve&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;clientSocket&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;span style=" ;color:#800080;"&gt;;&lt;/span&gt;&lt;br /&gt;       clientSocket&lt;span style=" ;color:#808030;"&gt;.&lt;/span&gt;close&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;span style=" ;color:#800080;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;     &lt;span style=" ;color:#800080;"&gt;}&lt;/span&gt;&lt;br /&gt;     &lt;span style=" font-weight:bold; color:#800000;"&gt;catch&lt;/span&gt; &lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;&lt;span style=" font-weight:bold; color:#bb7977;"&gt;IOException&lt;/span&gt; e&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;br /&gt;     &lt;span style=" ;color:#800080;"&gt;{&lt;/span&gt;&lt;br /&gt;       e&lt;span style=" ;color:#808030;"&gt;.&lt;/span&gt;printStackTrace&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;span style=" ;color:#800080;"&gt;;&lt;/span&gt;&lt;br /&gt;     &lt;span style=" ;color:#800080;"&gt;}&lt;/span&gt;&lt;br /&gt;     &lt;span style=" font-weight:bold; color:#800000;"&gt;finally&lt;/span&gt;&lt;span style=" ;color:#800080;"&gt;{&lt;/span&gt;&lt;br /&gt;       lastBreath&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;span style=" ;color:#800080;"&gt;;&lt;/span&gt;&lt;br /&gt;     &lt;span style=" ;color:#800080;"&gt;}&lt;/span&gt;&lt;br /&gt;   &lt;span style=" ;color:#800080;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;   &lt;span style=" font-weight:bold; color:#800000;"&gt;private&lt;/span&gt; &lt;span style=" ;color:#bb7977;"&gt;void&lt;/span&gt; lastBreath&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;br /&gt;   &lt;span style=" ;color:#800080;"&gt;{&lt;/span&gt;&lt;br /&gt;      nobleServiceThreads&lt;span style=" ;color:#808030;"&gt;.&lt;/span&gt;remove&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;&lt;span style=" font-weight:bold; color:#bb7977;"&gt;Thread&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;.&lt;/span&gt;currentThread&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;span style=" ;color:#800080;"&gt;;&lt;/span&gt;&lt;br /&gt;   &lt;span style=" ;color:#800080;"&gt;}&lt;/span&gt;&lt;br /&gt; &lt;span style=" ;color:#800080;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;I call them nobleServiceThreads because if they are about to be killed, their very last wish is to remove themselves from the list such that they don't burden the ServerSocket with dead weight.  How kind.&lt;br /&gt;&lt;br /&gt;The first step to preventing the thread from removing itself from the list while it is being removed elsewhere, is to make the nobleServiceThreads list a Synchronized list:&lt;br /&gt;&lt;br /&gt;&lt;pre style='color:#000000;background:#ffffff;'&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;private&lt;/span&gt; List&amp;lt;Thread&gt; nobleServiceThreads = Collections.synchronizedList(new ArrayList&amp;lt;Thread&gt;())&lt;span style='color:#808030; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Next, since we don't want a thread to be potentially modifying our list while we are iterating through it, we don't use an iterator to go through the list.  Instead we just loop while the list isn't empty:&lt;br /&gt;&lt;br /&gt;&lt;pre style='color:#000000;background:#ffffff;'&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;public&lt;/span&gt; void close() &lt;span style='color:#800000; font-weight:bold; '&gt;throws&lt;/span&gt; IOException, InterruptedException&lt;br /&gt;  &lt;span style='color:#800080; '&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span style='color:#800000; font-weight:bold; '&gt;if&lt;/span&gt; &lt;span style='color:#808030; '&gt;(&lt;/span&gt;serverSocketOpen&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span style='color:#800080; '&gt;{&lt;/span&gt;&lt;br /&gt;      serverSocketOpen &lt;span style='color:#808030; '&gt;=&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;false&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;      &lt;span style='color:#800000; font-weight:bold; '&gt;while&lt;/span&gt; &lt;span style='color:#808030; '&gt;(&lt;/span&gt;nobleServiceThreads&lt;span style='color:#808030; '&gt;.&lt;/span&gt;size&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt; &lt;span style='color:#808030; '&gt;&gt;&lt;/span&gt; &lt;span style='color:#008c00; '&gt;0&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;br /&gt;      &lt;span style='color:#800080; '&gt;{&lt;/span&gt;&lt;br /&gt;        nobleServiceThreads&lt;span style='color:#808030; '&gt;.&lt;/span&gt;get&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#008c00; '&gt;0&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#808030; '&gt;.&lt;/span&gt;join&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;        nobleServiceThreads&lt;span style='color:#808030; '&gt;.&lt;/span&gt;remove&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#008c00; '&gt;0&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;      &lt;span style='color:#800080; '&gt;}&lt;/span&gt;&lt;br /&gt;      serverSocket&lt;span style='color:#808030; '&gt;.&lt;/span&gt;close&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span style='color:#800080; '&gt;}&lt;/span&gt;&lt;br /&gt;    &lt;span style='color:#800000; font-weight:bold; '&gt;else&lt;/span&gt;&lt;br /&gt;      serverSocket&lt;span style='color:#808030; '&gt;.&lt;/span&gt;close&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span style='color:#800080; '&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Now this is pretty good, but we still have an issue.  This one is a little tougher to guess.   If, and this actually happened about 1/5 times when I ran the tests, a nobleServiceThread is active right as the while (nobleServiceThreads.size() &gt; 0)  is checked, and then right before the very next line, the nobleServiceThread removes itself from the list - then the nobleServiceThreads.get(0) could return null (if this was the very last thread).&lt;br /&gt;&lt;br /&gt;This is a tough issue.  For awhile I was almost tempted to put in 100 if statements checking to see if the thread was still there before I removed it, but of course that wouldn't change much.  So instead, with Micah's help, here is the solution I've got:&lt;br /&gt;&lt;br /&gt;&lt;pre style='color:#000000;background:#ffffff;'&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;public&lt;/span&gt; void close() &lt;span style='color:#800000; font-weight:bold; '&gt;throws&lt;/span&gt; IOException, InterruptedException&lt;br /&gt;  &lt;span style='color:#800080; '&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span style='color:#800000; font-weight:bold; '&gt;if&lt;/span&gt; &lt;span style='color:#808030; '&gt;(&lt;/span&gt;serverSocketOpen&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span style='color:#800080; '&gt;{&lt;/span&gt;&lt;br /&gt;      serverSocketOpen &lt;span style='color:#808030; '&gt;=&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;false&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;      serverSocket&lt;span style='color:#808030; '&gt;.&lt;/span&gt;close&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;      serverSocketThread&lt;span style='color:#808030; '&gt;.&lt;/span&gt;join&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;      &lt;span style='color:#800000; font-weight:bold; '&gt;while&lt;/span&gt; &lt;span style='color:#808030; '&gt;(&lt;/span&gt;nobleServiceThreads&lt;span style='color:#808030; '&gt;.&lt;/span&gt;size&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt; &lt;span style='color:#808030; '&gt;&gt;&lt;/span&gt; &lt;span style='color:#008c00; '&gt;0&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;br /&gt;      &lt;span style='color:#800080; '&gt;{&lt;/span&gt;&lt;br /&gt;        &lt;span style='color:#bb7977; font-weight:bold; '&gt;Thread&lt;/span&gt; thread &lt;span style='color:#808030; '&gt;=&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;null&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;        &lt;span style='color:#800000; font-weight:bold; '&gt;synchronized&lt;/span&gt; &lt;span style='color:#808030; '&gt;(&lt;/span&gt;mutex&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;br /&gt;        &lt;span style='color:#800080; '&gt;{&lt;/span&gt;&lt;br /&gt;          &lt;span style='color:#800000; font-weight:bold; '&gt;if&lt;/span&gt; &lt;span style='color:#808030; '&gt;(&lt;/span&gt;nobleServiceThreads&lt;span style='color:#808030; '&gt;.&lt;/span&gt;size&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt; &lt;span style='color:#808030; '&gt;&gt;&lt;/span&gt; &lt;span style='color:#008c00; '&gt;0&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;br /&gt;          &lt;span style='color:#800080; '&gt;{&lt;/span&gt;&lt;br /&gt;            thread &lt;span style='color:#808030; '&gt;=&lt;/span&gt; nobleServiceThreads&lt;span style='color:#808030; '&gt;.&lt;/span&gt;get&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#008c00; '&gt;0&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;          &lt;span style='color:#800080; '&gt;}&lt;/span&gt;&lt;br /&gt;        &lt;span style='color:#800080; '&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;        &lt;span style='color:#800000; font-weight:bold; '&gt;if&lt;/span&gt; &lt;span style='color:#808030; '&gt;(&lt;/span&gt;thread &lt;span style='color:#808030; '&gt;!&lt;/span&gt;&lt;span style='color:#808030; '&gt;=&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;null&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;br /&gt;        &lt;span style='color:#800080; '&gt;{&lt;/span&gt;&lt;br /&gt;          thread&lt;span style='color:#808030; '&gt;.&lt;/span&gt;join&lt;span style='color:#808030; '&gt;(&lt;/span&gt;TIMEOUT_PERIOD&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;          &lt;span style='color:#800000; font-weight:bold; '&gt;synchronized&lt;/span&gt; &lt;span style='color:#808030; '&gt;(&lt;/span&gt;mutex&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;br /&gt;          &lt;span style='color:#800080; '&gt;{&lt;/span&gt;&lt;br /&gt;            &lt;span style='color:#800000; font-weight:bold; '&gt;if&lt;/span&gt; &lt;span style='color:#808030; '&gt;(&lt;/span&gt;nobleServiceThreads&lt;span style='color:#808030; '&gt;.&lt;/span&gt;contains&lt;span style='color:#808030; '&gt;(&lt;/span&gt;thread&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;br /&gt;            &lt;span style='color:#800080; '&gt;{&lt;/span&gt;&lt;br /&gt;              nobleServiceThreads&lt;span style='color:#808030; '&gt;.&lt;/span&gt;remove&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#008c00; '&gt;0&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;            &lt;span style='color:#800080; '&gt;}&lt;/span&gt;&lt;br /&gt;          &lt;span style='color:#800080; '&gt;}&lt;/span&gt;&lt;br /&gt;        &lt;span style='color:#800080; '&gt;}&lt;/span&gt;&lt;br /&gt;      &lt;span style='color:#800080; '&gt;}&lt;/span&gt;&lt;br /&gt;    &lt;span style='color:#800080; '&gt;}&lt;/span&gt;&lt;br /&gt;    &lt;span style='color:#800000; font-weight:bold; '&gt;else&lt;/span&gt;&lt;br /&gt;      serverSocket&lt;span style='color:#808030; '&gt;.&lt;/span&gt;close&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;  &lt;span style='color:#800080; '&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The mutex is just a regular object that the synchronized block can hold onto, thus preventing anything else, trying to use the same mutex in a different synchronized block, from acting.  Here is how the nobleServiceThread changed:&lt;br /&gt;&lt;br /&gt;&lt;pre style='color:#000000;background:#ffffff;'&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;private&lt;/span&gt; void lastBreath()&lt;br /&gt;    &lt;span style='color:#800080; '&gt;{&lt;/span&gt;&lt;br /&gt;      &lt;span style='color:#800000; font-weight:bold; '&gt;synchronized&lt;/span&gt; &lt;span style='color:#808030; '&gt;(&lt;/span&gt;mutex&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;br /&gt;       &lt;span style='color:#800080; '&gt;{&lt;/span&gt;&lt;br /&gt;         nobleServiceThreads&lt;span style='color:#808030; '&gt;.&lt;/span&gt;remove&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#bb7977; font-weight:bold; '&gt;Thread&lt;/span&gt;&lt;span style='color:#808030; '&gt;.&lt;/span&gt;currentThread&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;       &lt;span style='color:#800080; '&gt;}&lt;/span&gt;&lt;br /&gt;    &lt;span style='color:#800080; '&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This prevents the nobleServiceThread from removing itself from the list if the ServerSocket is looking at this same nobleServiceThread to remove it.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Now you might ask  " Since the nobleServiceThread's lastBreath is used in the finally{ ... } clause (which will execute in the end, no matter what, when you try to kill the thread), why not just call interrupt on the thread as soon as you've got it?"&lt;br /&gt;&lt;br /&gt;This is because the applicationServer.serve() method might be talking to a client.  If it is waiting on a response from the client, and thus is in a reading block, than the interrupt wont reach the thread until the reading block is finished.  Thus, the interrupt could potentially wait forever while the thread waits for a response.&lt;br /&gt;&lt;br /&gt;The interrupt signal actually only reaches the thread in 3 instances.  When the thread is in a wait(), join(), or sleep() method.  So a thread can only be interrupted when it isn't doing anything.  (In case you didn't know, a thread is in wait() while it is waiting for its chance to use the processor, and in a join() when the application is telling it to finish its last task and then terminate).  So if you send an interrupt signal to a thread while it is performing some task, a flag will be marked and next time the thread is waiting, the JVM will check the flag and terminate the thread.&lt;br /&gt;&lt;br /&gt;I must give credit to the Software Craftsmanship Articles 8-11 written by Uncle Bob, since they walked through many of the same steps I listen here.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3714840552149734001-6222351874875999483?l=8thlightapprenticeship.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://8thlightapprenticeship.blogspot.com/feeds/6222351874875999483/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/02/day-31.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/6222351874875999483'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/6222351874875999483'/><link rel='alternate' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/02/day-31.html' title='Day 31'/><author><name>Justin</name><uri>http://www.blogger.com/profile/04054497811526894325</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://3.bp.blogspot.com/_snSMUhgzWLE/S0KeHj1cwNI/AAAAAAAAAAQ/f9gAgDyjN2A/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3714840552149734001.post-6088643907004021595</id><published>2010-02-16T22:16:00.000-08:00</published><updated>2010-02-17T08:19:57.305-08:00</updated><title type='text'>Day 30</title><content type='html'>I am sorry, but I had just a very unpleasant Git rebasing experience, where there was a conflict in just about every line of every file, but of course it only showed me one or two conflicted files at a time.  Thus I would remove a flurry of retarded conflicts, add the files and then rebase --continue, and once gain there would be more stupidly conflicted files.  I was trying to rebase about 20  commits at once, probably not a good idea in the first place, but either way I failed to pick a good commit to rebase onto I guess, and thus my rebase failed.  Now for whatever reason a few of the tests aren't passing and I don't know why.  &lt;br /&gt;&lt;br /&gt;A URL, or Uniform Resource Locator, is the standard addresser used for most http interaction; however it is not limited to http.  &lt;br /&gt;A URL is composed of two main parts, the protocol identifier and the resource name.&lt;br /&gt;http://    www.starcraft2.com &lt;br /&gt;|____|    | ___________________|&lt;br /&gt;protocol    resource name&lt;br /&gt;&lt;br /&gt;There are several different types of protocols, other than http, like FTP (File Transfer Protocol) or one we all see quite often, File.  The File protocol is the one used locally on your computer to navigate your system.&lt;br /&gt;&lt;br /&gt;The resource name has 4 different components, 2 of which are optional and often implied.&lt;br /&gt;There is the:&lt;br /&gt;Host Name - the name of the machine where the resource lives - for the starcraft2 URL this is the full www.starcraft2.com&lt;br /&gt;&lt;br /&gt;File Name - path name to the file on the machine - if you went to www.starcraft2.com/features, the /features portion is both the file name, and  what is called a 'relative URL' (meaning it is a locator relative to the base URL)&lt;br /&gt;&lt;br /&gt;Port Number - this is typically implied, but can also be specified.  For most sites you will ever go to, the port number is 80&lt;br /&gt;&lt;br /&gt;Reference - a reference to an anchor in a specified location in a file.  This is optional, and you typically wont notice this.&lt;br /&gt;&lt;br /&gt;I will expand the resource name to its full form so you can see the components:&lt;br /&gt;&lt;br /&gt;www.yahoo.com:80/index.html&lt;br /&gt;|______________| |__| |_________|      Host name - Port - File name&lt;br /&gt;For most browsers, when the site ends with .com/  this implies a  /index.html     This isn't universally true, but for most websites that is the case.  For example, this doesn't work for www.starcraft2.com because, I believe, their site is so pro and Flash based, that they find these norms irrelevant (try typing it, the error page is funny).&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Connecting to a page, without a browser, is actually pretty easy.   One easy way is to go to your terminal and type:&lt;br /&gt;&lt;br /&gt;curl www.starcraft2.com    this wont actually give you a connection, but will just print out the source of the page.  If you want to save the source using curl, you can type:&lt;br /&gt;&lt;br /&gt;curl www.starcraft2.com &gt;&gt; ~/Desktop/starcraftSource.txt     &lt;br /&gt;&lt;br /&gt;Most languages have built in methods to connect to a URL, and I know you are all gonna hate it, but I will show you the JAVA way since I am making a Java Socket Server.&lt;br /&gt;&lt;br /&gt;&lt;pre style='color:#000000;background:#ffffff;'&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;import&lt;/span&gt; java&lt;span style='color:#808030; '&gt;.&lt;/span&gt;net&lt;span style='color:#808030; '&gt;.&lt;/span&gt;&lt;span style='color:#808030; '&gt;*&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;import&lt;/span&gt; java&lt;span style='color:#808030; '&gt;.&lt;/span&gt;io&lt;span style='color:#808030; '&gt;.&lt;/span&gt;&lt;span style='color:#808030; '&gt;*&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;public class URLReader &lt;span style='color:#800080; '&gt;{&lt;/span&gt;&lt;br /&gt;    public &lt;span style='color:#800000; font-weight:bold; '&gt;static&lt;/span&gt; &lt;span style='color:#800000; font-weight:bold; '&gt;void&lt;/span&gt; &lt;span style='color:#400000; '&gt;main&lt;/span&gt;&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#603000; '&gt;String&lt;/span&gt;&lt;span style='color:#808030; '&gt;[&lt;/span&gt;&lt;span style='color:#808030; '&gt;]&lt;/span&gt; args&lt;span style='color:#808030; '&gt;)&lt;/span&gt; throws Exception &lt;span style='color:#800080; '&gt;{&lt;/span&gt;&lt;br /&gt;    URL sc2 &lt;span style='color:#808030; '&gt;=&lt;/span&gt; new URL&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#0000e6; '&gt;www.starcraft2.com&lt;/span&gt;&lt;span style='color:#800000; '&gt;"&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;  URLConnection sc2connection &lt;span style='color:#808030; '&gt;=&lt;/span&gt; sc2&lt;span style='color:#808030; '&gt;.&lt;/span&gt;openConnection&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;    BufferedReader br &lt;span style='color:#808030; '&gt;=&lt;/span&gt; new BufferedReader&lt;span style='color:#808030; '&gt;(&lt;/span&gt;new InputStreamReader&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;br /&gt;                sc2connection&lt;span style='color:#808030; '&gt;.&lt;/span&gt;openStream&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style='color:#603000; '&gt;String&lt;/span&gt; inputLine&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style='color:#800000; font-weight:bold; '&gt;while&lt;/span&gt; &lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#808030; '&gt;(&lt;/span&gt;inputLine &lt;span style='color:#808030; '&gt;=&lt;/span&gt; in&lt;span style='color:#808030; '&gt;.&lt;/span&gt;readLine&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt; &lt;span style='color:#808030; '&gt;!&lt;/span&gt;&lt;span style='color:#808030; '&gt;=&lt;/span&gt; null&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;br /&gt;        System&lt;span style='color:#808030; '&gt;.&lt;/span&gt;out&lt;span style='color:#808030; '&gt;.&lt;/span&gt;println&lt;span style='color:#808030; '&gt;(&lt;/span&gt;inputLine&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    in&lt;span style='color:#808030; '&gt;.&lt;/span&gt;close&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span style='color:#800080; '&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#800080; '&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This will open a connection, grab all the html, and print it out.  There are other things you can do with the connection, like write to the server.&lt;br /&gt;&lt;br /&gt;Most html pages have 'forms' - GUI objects that allow interaction with the site.  User to HTML page interaction is written into the URL by your browser, and then sent to the server.  Once the server receives the new URL, it process it, builds a response, and sends back a bunch more HTML for the browser to view.&lt;br /&gt;Lots of HTML forms use HTML POST METHOD to send data to the server.  This is called 'posting to a URL'.  The server recognizes a post, and then responds.&lt;br /&gt;&lt;br /&gt;If you know what objects are meant for interaction, or the form the URL takes after an interaction, then you can just write that URL directly to your connection, and see the response.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Later today I will go over a lot of the interesting Threading issues involved with making a Socket Server.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3714840552149734001-6088643907004021595?l=8thlightapprenticeship.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://8thlightapprenticeship.blogspot.com/feeds/6088643907004021595/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/02/day-30.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/6088643907004021595'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/6088643907004021595'/><link rel='alternate' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/02/day-30.html' title='Day 30'/><author><name>Justin</name><uri>http://www.blogger.com/profile/04054497811526894325</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://3.bp.blogspot.com/_snSMUhgzWLE/S0KeHj1cwNI/AAAAAAAAAAQ/f9gAgDyjN2A/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3714840552149734001.post-3253546321220817178</id><published>2010-02-15T20:35:00.000-08:00</published><updated>2010-02-16T12:10:51.272-08:00</updated><title type='text'>Day 29</title><content type='html'>Programming a java HTTP Socket Server is proving to be quite interesting.  I spent several hours today just reading and taking notes of the Hypertext Transfer Protocols and all the complexity of moving information around the internet.  Then I actually got some help from the Craftsmanship Articles written by Uncle Bob, which I had read last year.  It turns out that Alphonse and Jerry created their own Socket Server in java, which is quite similar to a part of what I need to do.  I also just got done reading a rather interesting article about what it means to program an AI, and it turned the idea of human intelligence on its head, if i may.&lt;br /&gt;&lt;br /&gt;There is a plethora of detail in HTTP, and the RFC documents are very dense and a tough read.  I found the only way I can really absorb much from it is by taking notes and trying to spit back the knowledge I acquired from these documents.  &lt;br /&gt;&lt;br /&gt;HTTP has gone through a few versions now, starting with HTTP/0.9 which was extremely basic, and evolving into HTTP/1.1 which seems to be the standard these days.  In its most basic form, all the HTTP is, is a standard way to ask for or send to a program some packets of data. &lt;br /&gt;&lt;br /&gt;All HTTP interactions happen through a Request - Response form.  First a client (a program connected to a server) sends a request to a server.  Once the server receives this request, it processes it, and builds and sends the appropriate response.  If the client wants any further information, it must package up and send another request.  Often there are several intermediaries as well, such as Proxies or Gateways, which will receive a message from the client and then perhaps perform some manipulation before forwarding the message to the server.  &lt;br /&gt;&lt;br /&gt;Most programs using HTTP to interact will also have a cache.  This is some local memory used to store different requests and responses, already packaged and ready to be sent.  Using a cache can save a server or client a lot of processing time, so that the only real limitation they face will be the time it takes to get back a response.&lt;br /&gt;Caches can also be particularly useful if there several proxies, gateways, or intermediate servers sitting between the Client and the Origin Server.  If, for example, a client needs to send a request through proxy A and B before reaching the server, then both proxy A and proxy B can build up a cache to save time.  Proxy A could save the Client's request, and the response coming back from the Origin Server.  This way, the next time Proxy A gets that same request, it can just send the stored response right away without having to wait to hear back from the server.&lt;br /&gt;&lt;br /&gt;When I say 'package' a request or response, I mean forming a proper HTTP message.  The desired data in any message is called the entity of that message.  The entity can't be sent on its own because it might not be in a familiar form for many different programs on the web, so it must be packaged into a formated HTTP message.  These typically consist of a few header-fields which define certain basics about the entity, like its length or perhaps encryption type, and then the message-body which will contain the entity.  &lt;br /&gt;&lt;br /&gt;Typically if an HTTP formated message wants to send complicated data structures it will use MIME types. A MIME, Multi-purpose Internet Mail Extension, is just a standard way or form to send complicated data in HTTP messages.  There are a variety of MIMEs, and I have much more to learn about them in order to understand how they actually vary.&lt;br /&gt;&lt;br /&gt;A Socket Server is a type of server that uses Sockets to handle multiple requests.  Say you have a server hosting your website which provides some service to clients.  The most basic of servers will be able to talk to just one client at a time, and will focus all of its attention at that one client (spending far far too much time just waiting for the next request); but say you want your website talking to multiple clients at the same time.  You might use a Socket Server to create a Server Socket for each port you wish to talk on, and then generate a Socket for each new client it wishes to talk to.  So a Socket Server will make Server Sockets.  A Server Socket is a place holder that is watching for any communication on a port, like port 80 (the standard port for communication on the internet).  Once the Server Socket sees a client trying to talk to your server on its specified port, it will create a Socket for the client to talk to.  The Socket will then handle any requests from that one client, and send responses back once it is able to get some processor time to use the program sitting on your website.&lt;br /&gt;&lt;br /&gt;Its been pretty cool learning how to get programs talking over the web, and I am excited to make my own socket server and see it talk with my browser!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3714840552149734001-3253546321220817178?l=8thlightapprenticeship.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://8thlightapprenticeship.blogspot.com/feeds/3253546321220817178/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/02/day-29.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/3253546321220817178'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/3253546321220817178'/><link rel='alternate' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/02/day-29.html' title='Day 29'/><author><name>Justin</name><uri>http://www.blogger.com/profile/04054497811526894325</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://3.bp.blogspot.com/_snSMUhgzWLE/S0KeHj1cwNI/AAAAAAAAAAQ/f9gAgDyjN2A/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3714840552149734001.post-2495854280277758295</id><published>2010-02-12T19:23:00.000-08:00</published><updated>2010-02-12T20:03:15.171-08:00</updated><title type='text'>Day 28</title><content type='html'>So I first must apologize for not blogging on Thursday.  I know day 26 says Thursday, but that was actually done Wednesday night, and then I fell asleep before I submitted, so I submitted it right when I woke up.  Thursday I was still trapped in Philadelphia, and Micah spent the whole morning trying to find a flight home.  I was feeling under weather, and we were riding a roller coaster, trying time and time again to get on a flight.  Finally after a few attempts, we made it to the airport for a flight that had not yet been canceled.  We then had a very anti climatic sprint to get to our gate, only to find out that we had to wait another hour and a half for the airline to find another flight attendant.  I didn't get home until around 6:00 and we had lost an hour from the flight, so the day was quite unproductive, other than the fact that we made it home.&lt;br /&gt;&lt;br /&gt;Today, I had hoped to make up for the lack of work completed on Thursday, unfortunately today was manual labor day.  There were several tasks that needed to be done at the office, and being the apprentice - I was put to work.  I literally got about 5 lines of code down today.  On a more lightening note, one side of the office looks radically different now!  &lt;br /&gt;First I had to assemble 4 new chairs, which was actually a fairly painless process.  &lt;br /&gt;Then came a broken toilet that needed fixing.  A relatively quick trip to ACE and a little tweaking to get the flush mechanism operating at its full potential.  And let me tell you, there are under par flush handles and there are excellent flush handles.  My first go at it, Micah was disappointed at the give of the handle and that it required so much motion before the flushing actually began.  On my second go at it, I successfully measured the exact give to action ratio to create a handle that is both satisfyingly smooth in its motion as well as efficient in its reaction to the toilet's depositor.&lt;br /&gt;&lt;br /&gt;After the toilet came the real task.  This was actually after I had ordered lunch for everyone, though I might add that I failed in this endeavor because I forgot we had a vegetarian in the office.  Fortunately, the pizza place had failed to deliver on my failed request, and thus two wrong made a right and there was no meat on the pizza.  Unfortunately, this was discovered after Colin (he who prefers the veggies over the remains of a carcass) had already compensated for my thoughtlessness and created a delightful Peanut Butter, Pretzel, Banana, and Jelly sandwich on Rye bread.&lt;br /&gt;&lt;br /&gt;So my real task came after this lunch, just as I thought I might be able to get some coding done, when some guys brought in 4 brand new tables that needed assembly.  Not just the IKEA  - stick some pre-made pegs in pre-drilled holes.  No, these were big, heavy, and highly demanding tables which give you no assistance on assembly.  As if tables can give you assistance... but either way, these were beastly projects.  Each had four legs with a base that had 8 screws which had to be positioned after first measuring the proper distances from each side.  Before the screws could be placed, I had to drill little holes to guide the screws in properly.  So in total, each table required about 12 measurements, 16 pencil markings, 32 holes drilled, 32 screws screwed in the guided holes, and then finally 4 legs to be screwed onto their respective base paltes.  I tried making a measurement template after the first table (as Doug suggested), but we had no paper large enough to span the table and the cardboard template I tried was too small and too inaccurate.  &lt;br /&gt;&lt;br /&gt;What made it all far... far worse, was the electric drill ran out of battery before even the first table was completed.  As a result, the majority of the screws were placed in by hand through a variety of combinations of unintended uses for tools.  If you never have screwed in thick screws into fairly hardwood... it isn't an easy task.  I am a fairly strong fellow, and even using my full body weight, sometimes I couldn't get the screws to budge.  Thank goodness for mechanical advantage!&lt;br /&gt;&lt;br /&gt;I am happy to say, that even though I was sweating at the job for a very long time, I defeated Doug's expectations that I would still be there when he returned on Monday!  Take that Mr. IOnlyUsePoweredDrills ( go java CamelCase) !!  No offense intended of course, its actually a reflection of frustration for 8th Light owning a battery powered drill with no backup battery. &lt;br /&gt;&lt;br /&gt;This weekend I will makeup for all the lost time these last two days, and then start on my new assignment of creating an HTTP Server from scratch.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3714840552149734001-2495854280277758295?l=8thlightapprenticeship.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://8thlightapprenticeship.blogspot.com/feeds/2495854280277758295/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/02/day-28.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/2495854280277758295'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/2495854280277758295'/><link rel='alternate' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/02/day-28.html' title='Day 28'/><author><name>Justin</name><uri>http://www.blogger.com/profile/04054497811526894325</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://3.bp.blogspot.com/_snSMUhgzWLE/S0KeHj1cwNI/AAAAAAAAAAQ/f9gAgDyjN2A/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3714840552149734001.post-2534145241354558090</id><published>2010-02-11T05:35:00.000-08:00</published><updated>2010-02-12T20:06:49.445-08:00</updated><title type='text'>Day 26</title><content type='html'>"Do not try to bend the spoon.  That's impossible.  Instead... only try to realize the truth.  There is no spoon.  Then you'll see, that it is not the spoon that bends, it is only yourself."&lt;br /&gt;&lt;br /&gt;I wanted to place that quote at the end, but it seemed like such a fitting introduction that it belonged at the start.&lt;br /&gt;&lt;br /&gt;Making massive changes to your code, without changing a single line.  &lt;br /&gt;&lt;br /&gt;Often you will find yourself working on a project, when an unexpected requirement pops up and seems to demand that you perform a complete redesign or restructuring of your code.  You might then find you have no idea where to start or how to proceed.  You look around for awhile, testing out small changes in various places, but never getting the feel that you are going in the right direction.  Finally, you stumble across an area that looks important, so you make a change that seems logical, watch as your tests fail in the way you expect, and then proceed to change your tests to fit a new criterion.  However, once you get to your tests you realize that they are actually testing exactly what you had wanted them to!  These tests, which are at the center of your massive overhaul, are properly testing both your old system and your new system... but you know that this is supposed to be a big change!  What's going on?&lt;br /&gt;&lt;br /&gt;This exact thing happened to me the other day.  I had developed a system for weeks, carefully designing each facet, and it was almost just the way I wanted it.  Then I suddenly discovered there was a fundamental change that was needed to fulfill a requirement.  Not knowing where to start, I began to fiddle around in a variety of places trying to get a foothold on what I needed to do.  Finally, I made a change to the code, saw a test fail, then changed the test... but the change didn't feel right.  I made the change anyway, and observed the green flash before me once again.  It was at that point that I realized this was all wrong.  I realized that I wasn't trying to change the code at all, I was just trying to change what it meant.  The massive overhaul and fundamental change that needed to occur was in my mind.  &lt;br /&gt;&lt;br /&gt;After the fact, it seemed rather obvious, but I got trapped into thinking- since my code only did one thing, it could only mean one thing.  This, of course, was not the case.   I was making a change that would affect every part of my system, but would change none of the functionality, just the interpretation.  &lt;br /&gt;&lt;br /&gt;I found a few signals that indicate when the change is in the theme and not in the scheme.  &lt;br /&gt;The biggest is that you have no idea where to make a change.  You designed this system from the start and you know it inside and out, yet you can't seem to find what you need to tweak to get started on this big change.   &lt;br /&gt;Another is that the tests are yelling at you for trying to change them.  You seem to think you know what to change, but when you make the according change to the tests it feels completely wrong.  The tests seem to fight the change.&lt;br /&gt;The last big one I can think of is you can't completely understand what this change means in terms of your code.  You know what it should allow you to do, but you don't quite understand the new mind set you are supposed to settle into.&lt;br /&gt;&lt;br /&gt;These three things likely indicate that either your system is already the way it is meant to be and you just need to figure out why, or that your system sucks and you should rewrite it all.  It could also mean that your original problem is far more complicated that you first anticipated, but if thats the case your tests are probably screaming at you because they unsatisfied or just plain wrong.&lt;br /&gt;&lt;br /&gt;Basically, try to remember to   'Free your mind'&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3714840552149734001-2534145241354558090?l=8thlightapprenticeship.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://8thlightapprenticeship.blogspot.com/feeds/2534145241354558090/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/02/day-26.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/2534145241354558090'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/2534145241354558090'/><link rel='alternate' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/02/day-26.html' title='Day 26'/><author><name>Justin</name><uri>http://www.blogger.com/profile/04054497811526894325</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://3.bp.blogspot.com/_snSMUhgzWLE/S0KeHj1cwNI/AAAAAAAAAAQ/f9gAgDyjN2A/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3714840552149734001.post-723588999498773977</id><published>2010-02-09T22:46:00.000-08:00</published><updated>2010-02-10T07:11:22.346-08:00</updated><title type='text'>Day 25</title><content type='html'>It appears I will be trapped in Philadelphia until Friday because of severe weather conditions!  It is supposed to snow 10-15 inches tonight, so tonight we all went and stocked up on groceries and supplies.&lt;br /&gt;&lt;br /&gt;Anyway, today I was got to sit in on a very engaging and enlightening meeting with a new client of 8th Light's. Micah, Paul, Craig, and I were introduced to this companies exec board, who then sat down with us and described their dilemma.  They had a huge amount of data, but they had to use other companies to access it.  Some of the data was collected through one of their websites, which was created and hosted by a company they hired, and as such they had to go through this company to get any of their data.   There is also a huge data bank which they do not own, but have a license to use; yet they still had been going through a third party to gain access to this data.&lt;br /&gt;&lt;br /&gt;The gist of it is that they wanted all this data under one roof.  Our client knew the power of this knowledge, and they wanted to hold it and completely own it.  So 8th Light's job would be to create a system that could store and interact with this data, after merging a huge amount of data in from several sources.&lt;br /&gt;&lt;br /&gt;From an apprentice stand point, this was a gold mine to observe.  I got to meet some very ambitious and driven people, who couldn't help but think big.  I got to see the manner in which a Craftsman might respond to the requests and dreams of enthusiastic clients, and it was always in the affirmative.  And I also got to see the outlining of a project from nothing to something very achievable.&lt;br /&gt;&lt;br /&gt;First the client described their debacle, and then we would ask chains of questions to get a deeper understanding so that we could formulate possible solutions.  Then the client explained what they were looking for, and what they imagined their system would do, and once again we asked questions to contemplate how we might implement this system. Next,  Micah and Paul began outlining what it meant to use the Agile process, or to work in short iterations with rigorous customer interaction and frequent releases.  We proceeded to define several Epics, or big chunks of functionality that the client thought were crucial.  Once these Epic had been ordered, or at least once we knew which one had to be first, we then broke the Epic into Stories and estimated.  Finally, we showed them the stories with the estimates, and gave them an idea of how soon we could get them the functionality they desired.&lt;br /&gt;&lt;br /&gt;All in all a very educational experience.  I now have an understanding of how to began a project from scratch, and how to lead the customer along your chain of thought.  I am also remarkably exhausted from waking up extremely early and getting a mere hour of sleep.  must collapse... arrrgggghhh... ZZzzzz&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3714840552149734001-723588999498773977?l=8thlightapprenticeship.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://8thlightapprenticeship.blogspot.com/feeds/723588999498773977/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/02/day-25.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/723588999498773977'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/723588999498773977'/><link rel='alternate' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/02/day-25.html' title='Day 25'/><author><name>Justin</name><uri>http://www.blogger.com/profile/04054497811526894325</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://3.bp.blogspot.com/_snSMUhgzWLE/S0KeHj1cwNI/AAAAAAAAAAQ/f9gAgDyjN2A/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3714840552149734001.post-641344492087552337</id><published>2010-02-08T23:06:00.000-08:00</published><updated>2010-02-12T20:13:44.798-08:00</updated><title type='text'>Day 24</title><content type='html'>So while driving home from work today, I drove by a house which left their garage door open.  They had left their car out in the snow because their garage was so overwhelmingly packed with stuff that they no longer had room for their car.  When I saw this, the two things came to mind.  The first was my Grandma, who is the type of person who could never throw anything away, and as a result has no room in her garage.  The second was what a program would look like if she had written it.&lt;br /&gt;&lt;br /&gt;Often I, and many other developers I know, have the temptation to comment out some code and keep it around just in case it might come in handy later.  This happens quite often when you are spiking, or when (and god knows why) you are not using version control.  You write a tid-bit of code,  find a better way to rewrite the code, but save the old code just in case your new idea fails.  Do this over and over, and things can get pretty ugly.&lt;br /&gt;&lt;br /&gt;I recently wrote some C and X86 assembly to write an operating system for one of my classes.  My group and I really had no idea how to start going about writing our OS, so quite frequently we would save old code we had written so that we wouldn't have to reinvent the wheel.  As a result, in some files we had to doing some hunting just to find the real production code through the haze of the comments.  This is a Dirty Garage.&lt;br /&gt;&lt;br /&gt;Uncle Bob uses the metaphor of a Dirty Kitchen for poorly written code.  If you are a chef working at a restaurant on a very busy night, and rather than cleaning up pans or knives after every use, you instead just toss the dirty ones aside and grab the nearest clean on.  At first, you will be able to get a bunch of dinners out quite rapidly, since you waste no time cleaning anything; however, as the night progresses you will find it more and more difficult to get any clean pans and eventually you virtually stop cooking all together and spend most of your time hunting down clean tools.   The same thing is true with software.  If you rush to get a lot done really quickly, and you push off keeping your code clean, then eventually you will hit a point where you are spending more time trying to figure out what is going on instead of developing.&lt;br /&gt;&lt;br /&gt;If my Grandma were to write a program, I imagine that it would be so densely packed with commented and saved code, that unveiling any functionality would be quite a challenge.  This is a Dirty Garage. Where you have so much saved junk in your files that you no longer have any room for that which is meant to occupy your production files, your functioning code.  Where you fear deleting code because you think it might be useful again in the future.  Sometimes this can be true, and if you are just messing around and trying to refactor, often commenting out code for later or for reference can be valuable.  Often though, you will comment out a block, forget about it, and it will linger and rot your code.  Perhaps you hand your project off to another developer who is too afraid to delete the commented code because he/she thinks it might have some unspoken value.&lt;br /&gt;&lt;br /&gt;Although a Dirty Kitchen can be more harmful than a Dirty Garage... no one wants to park their car in a garage full of junk.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3714840552149734001-641344492087552337?l=8thlightapprenticeship.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://8thlightapprenticeship.blogspot.com/feeds/641344492087552337/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/02/day-24.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/641344492087552337'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/641344492087552337'/><link rel='alternate' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/02/day-24.html' title='Day 24'/><author><name>Justin</name><uri>http://www.blogger.com/profile/04054497811526894325</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://3.bp.blogspot.com/_snSMUhgzWLE/S0KeHj1cwNI/AAAAAAAAAAQ/f9gAgDyjN2A/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3714840552149734001.post-2060286854147845184</id><published>2010-02-07T18:39:00.000-08:00</published><updated>2010-02-07T22:06:20.745-08:00</updated><title type='text'>Day 23</title><content type='html'>A light weight and 'humble' user interface is the way to go.  When making a UI for some application of website it is important to make sure you draw a line between your logic and your interface.  Typically you don't want anything important happening in a text box or a button.  You want the button to only know where it is, when its clicked, and how it looks.  &lt;br /&gt;&lt;br /&gt;Say your making a calculator application.  This calculator has a screen, to display results, and a bunch of buttons for numbers and operations.  &lt;br /&gt;&lt;br /&gt;First lets look at what happens if you program this the bad way.  &lt;br /&gt;You start making the application by first making a main class to store which buttons have been pressed and all the needed info, and then by creating a bunch of buttons.  You write a test to make sure there is a number '1' button, and then you make this button.  Then you test that when pressed, this button will output a 1.  You proceed to do make a new button for all the number 0-9, each button being specifically designed for its number.   Every single one of these buttons have a set of tests that are virtually identical, checking to make sure this button is a certain size, making sure it is clickable, making sure it changes form when being clicked, making sure it tells your main class to record the button's info.  All of these tests for every button, and then you add 1 different tests that makes sure then number 1 button outputs a 1, and a 2 outputs a 2, and so forth.&lt;br /&gt;&lt;br /&gt;Already you have huge amounts of duplication and a rigid form, but it gets worse.  Next you start making the operation buttons.  You make an add button, once again repeating all the steps for a button but this time adding a few extra tests to make sure this button takes inputs from the main class.  Then you make a multiply button (and here is where it gets bad), but you realize your gonna just have to do some addition several times, and you don't want to rewrite the addition code... So you tell your multiply button to 'press' the add button over and over to get multiplication. This is sick.  Buttons should not be pressing other buttons! But you persevere.  You proceed to make subtraction and division in the same manner with the button's 'clicked()' function doing all the math.&lt;br /&gt;&lt;br /&gt;Finally you put all these buttons on a panel and have main display the inputs and outputs on some text panel and show your friends your cool new calculator.  Then one of them asks "Hey this is really swell, but can you make a version for the terminal?  I want to be able to type 1 + 1 = ? and get a result,".  You of course, being the savvy and eager coder that you are, say "Most certainly! I already have all the logic, I just have to change the inputs!".   So you go back to your program and start trying to figure out how you will change the inputs.  As you scour for ways, you realize even if you changed the inputs all of your operations are inside the buttons!  You can't just erase all your code and you know you shouldn't copy paste it somewhere else because then you loose all your tests.  You can't bring your tests because they all test the operations by pretending to click the buttons.  And you realize you are stuck...&lt;br /&gt;&lt;br /&gt;Then you commit the sin of all sins, and make your terminal based calculator by getting the text inputs and then telling your terminal app to... press buttons...&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Not only does tying logic to the UI force you to repeat a ton of code that can't be reused, it also makes for rigid tests that are dependent on your UI.&lt;br /&gt;&lt;br /&gt;When you do it the correct way, you make a very light UI and keep all your logic behind closed doors.  You start by making your main calculator class.  Then you add in all of your operations, no buttons yet, making sure that they don't care who is using them, they just take numbers in and spit numbers out.  Once you have all your operations done and tested, you design a single button.  This button is simple, it just knows about buttony things like where it is and when its pressed.  &lt;br /&gt;&lt;br /&gt; Next you make a view class, which has a bunch of instances of these buttons, but all with different names like '1' and 'ADD', and yet all they do is get pressed and tell the view they were pressed.  The view, or this humble dialog, will keep track of all the basic information.  When a button is pressed, the view records it and saves the needed data.  If an operation button is pressed, the view makes sure it has the needed data, and then sends it all to the main calculator class and tell it do perform the operation.  The main class then sends the result right back to the view, which promptly displays it.&lt;br /&gt;&lt;br /&gt;Using this sort of design, you can keep all of your business logic well isolated and tested, and you get to make any sort of UI you want.  Say your friend sees your new calculator and asks you to make the terminal version now.  This is easy as pie, all you have to do is make another humble view!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3714840552149734001-2060286854147845184?l=8thlightapprenticeship.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://8thlightapprenticeship.blogspot.com/feeds/2060286854147845184/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/02/day-23.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/2060286854147845184'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/2060286854147845184'/><link rel='alternate' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/02/day-23.html' title='Day 23'/><author><name>Justin</name><uri>http://www.blogger.com/profile/04054497811526894325</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://3.bp.blogspot.com/_snSMUhgzWLE/S0KeHj1cwNI/AAAAAAAAAAQ/f9gAgDyjN2A/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3714840552149734001.post-1895921078023952751</id><published>2010-02-04T21:38:00.000-08:00</published><updated>2010-02-05T08:14:41.633-08:00</updated><title type='text'>Day 22</title><content type='html'>I need to make today's post very brief because I have been very busy today, and really want to finish my current project so I can get started on something new tomorrow.&lt;br /&gt;&lt;br /&gt;I wish I had something really cool or interesting to say, but today I spent a very large amount of my time doing very tedious and rather annoying work.  Making User Interfaces is pretty boring.  Well... I should be more clear.  The logic behind the UI can be a lot of fun.  I have learned a lot about the complexities and everything that happens behind the scenes with User Inputs and such, but the actual scene is realllyyy annoying to make.&lt;br /&gt;&lt;br /&gt;I spent hours today just trying to get a cursor (or as a later learned, it is actually called the caret) to pixel perfect fit the text across different types of input panels.  The problem is that the text lines up in drastically different ways in, for example, a text box vs. a text area.  Text boxes always have the text centered, and thus the caret must also be centered.  In a text area, the text will start at the very top, and will of course span across several lines, thus the caret must operate in a fundamentally different way than in a text box.  &lt;br /&gt;&lt;br /&gt;Now if you are just trying to get everything to work, you can hack in easy ways to make the caret look right, without it actually being able to truly work right.  For example you could easily code in an exact length for the caret, and exact positions for it to start on every line, but then you could never change the size of the font or the area itself.  You could also design drastically different carets for a text box and a text area, but the problem is that there is just enough similarities between how they have to be made that you would end up with a lot of duplicate code.  &lt;br /&gt;&lt;br /&gt;In the end I found ways to get pixel perfect carets for the different input panels, using mostly all the same code with very little duplication, but it took large amounts of experimentation and fiddling with different offsets and such.&lt;br /&gt;&lt;br /&gt;What made it worse was, and I hate to say this, trying to accomplish this with TDD.  It was a mistake.  Any change I had to make to the size of the caret, or the position/coordinates I wanted it to be at, or the manner in which it was positioned... I had to make these changes in every test as well as in the production code.  This is wrong, and is not how coding should be done.  I am inclined to say that when designing UIs, it is better to just put some tests in after you know you have everything looking the way you want.  I mean... tests just can't tell you how something will look.  You can write a test that seems to make sense in how the positioning will work, but then  you run the program and everything is completely misaligned or the cursor is actually 2 pixels too long at the top and 3 pixels to short on the bottom.  There are just too many nit picky little things involved in the presentation of UIs that TDD can't help you with.  &lt;br /&gt;&lt;br /&gt;Please, if you disagree or know a better way, tell me.&lt;br /&gt;&lt;br /&gt;Friday -&lt;br /&gt;Afternote:&lt;br /&gt;&lt;br /&gt;Paul suggested I read the Humble Dialog Box by Michael Feathers, which is an excellent article on how to separate your UI from all your logic.  I will blog further about this today.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3714840552149734001-1895921078023952751?l=8thlightapprenticeship.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://8thlightapprenticeship.blogspot.com/feeds/1895921078023952751/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/02/day-22.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/1895921078023952751'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/1895921078023952751'/><link rel='alternate' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/02/day-22.html' title='Day 22'/><author><name>Justin</name><uri>http://www.blogger.com/profile/04054497811526894325</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://3.bp.blogspot.com/_snSMUhgzWLE/S0KeHj1cwNI/AAAAAAAAAAQ/f9gAgDyjN2A/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3714840552149734001.post-8205683775994804000</id><published>2010-02-03T20:45:00.000-08:00</published><updated>2010-02-03T21:31:03.024-08:00</updated><title type='text'>Day 21</title><content type='html'>One issue I am consistently having is what I will refer to as coding A.D.D.  It is drastically slowing my speed, and typically doesn't lead to anything valuable.  Coding A.D.D. is where you are working on a project, either writing new production code or trying to change existing code to fit an unanticipated change, and you aren't exactly sure where to go or what to do.  Instead of taking one idea through to the end and trying to at least getting something to work in a linear fashion, you work spastically and jump from idea to idea without actually following through with any of them. &lt;br /&gt;&lt;br /&gt;To look at it from another angle, linear thinking would be throwing points onto a graph one after another all going in the same direction, and at the end you connect all the points to form an functional straight line.  Coding A.D.D. is more like plotting points like throwing darts at a dart board.  They are scattered and sparse, have no real pattern, and when you try to connect them all you get is a big mess.&lt;br /&gt;&lt;br /&gt;This is what I frequently end up doing, but rather than trying to connect all the dots, I just erase all the extra code I wrote and start over again.  My brain doesn't work in a linear manner, instead I tend to pop out idea after idea, each seeming better than before but really not getting me anywhere.  It certainly gives me a greater understanding of the problem, when I try every solution I can think of, but I usually end up using my first strategy to get the job done anyway.  It is extremely time consuming  and frustrating, and worst of all, it leads to far less progress.  &lt;br /&gt;&lt;br /&gt;I find that I typically don't find the better solution to a problem until I come back to it a few hours or a few days later.  When I look at it again later, the better solution pours into my mind in its entirety, and I know almost exactly how I want to improve my code.  This is much more effective and efficient.  &lt;br /&gt;&lt;br /&gt;I suppose the problem is discipline.  Micah said, and it seems rather obvious now, that is almost always better just to get it working first.  Get some good tests, get the functionality out of the way - even if you are certain there is a better way to do it - just go with what works.  Then when you come back to it, you know the worst you can do is leave it working.  I also believe it is easier to refactor and redesign when you acquire extra understanding from seeing the code work as it should.  This will make it easier to see a clear solution.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3714840552149734001-8205683775994804000?l=8thlightapprenticeship.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://8thlightapprenticeship.blogspot.com/feeds/8205683775994804000/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/02/day-21.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/8205683775994804000'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/8205683775994804000'/><link rel='alternate' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/02/day-21.html' title='Day 21'/><author><name>Justin</name><uri>http://www.blogger.com/profile/04054497811526894325</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://3.bp.blogspot.com/_snSMUhgzWLE/S0KeHj1cwNI/AAAAAAAAAAQ/f9gAgDyjN2A/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3714840552149734001.post-5181159269285987726</id><published>2010-02-02T16:51:00.000-08:00</published><updated>2010-02-02T17:53:48.576-08:00</updated><title type='text'>Day 20</title><content type='html'>One thing I wanted to write a bit about is selling your skills to clients.  Though not the immediate concern of most developers, it is still something that someone has to do.  On Friday I was with Micah M. and Micah B. as we sat down to meet with a possible future client.  These were the same guys who had the PHP code from the seventh realm of hell.  These poor guys had an excellent idea, and they needed someone who could make it a reality.  &lt;br /&gt;&lt;br /&gt;They had a website with thousands of hits every week and nearly as many bug reports.  The founder spoke about how he wished he could wake up in the morning and not dread all the emails he was going to have read about the many bugs people kept finding.  They had gone through many developers and a few different companies, just trying to get any sort of website out there to start getting a fan base.  After first having a group of developers fail, they found another group which got the website started, and then another group after that to try and maintain and slowly start getting rid of bugs.&lt;br /&gt;&lt;br /&gt;These guys had no idea how different this process could be.  They didn't know that there was an Agile process with developer - customer interaction and iterations.  They had no idea there was this test driven development thing.  I don't know that they could fathom having a good experience working with programmers.&lt;br /&gt;&lt;br /&gt;Micah had to break to them that they had been working with people doing it all wrong.  He had to hit them with the bad news...  but then he got to lift them with the news that a better way does exist, and that he knew what it was.&lt;br /&gt;&lt;br /&gt;First, he went over, and it took quite a bit of time..., the list of things that were wrong with their current website's code.  It was possible that the clients still thought it would be possible for 8thLight to work on the existing code base.  Micah made it exceedingly clear that this was simply not reasonable.  &lt;br /&gt;&lt;br /&gt;Hahaha, there was one moment I recall when the clients proposed that 8th Light would take over the upkeep of the current website.  Now, you must understand that the entire time Micah was presenting all the reasons why this code was awful, he had a rather stern and tensely maintained expression.  It was pretty tough to tell what he was feeling, all you could see was that he was being honest.  But when they proposed that he actually work on this code, it was as though all the muscles that had once been tense had suddenly gone limp and a wave of what can only be described as disgusted terror washed over him.  They started laughing, and quickly after Micah regained his composure.  The point was received.&lt;br /&gt;&lt;br /&gt;After describing all the issues, and basically the reasons why it wouldn't be worth it for them to have anyone continue working on their existing code, Micah proceeded on to the good news.  &lt;br /&gt;&lt;br /&gt;This part was pretty amazing.  Even though, and probably because, Micah remained just as calm and collected while presenting the good new, the clients were radiant with excitement.  Here are these guys who have been waiting in Pergatory for a long time, and suddenly they see the light (the 8th Light ;-) ).  And its not some preacher or enthusiastic peon overly excited to take them to a better place, but instead it is an experienced traveler who 'has been down both paths and will take them on the one less traveled by.  And that made all the difference.'  &lt;br /&gt;&lt;br /&gt;The way I see it, these guys were in unfamiliar territory.  They didn't know exactly what was right and what wasn't in this whole software world.  They could only go on their instincts and their ability to decide who is worthy of their trust.  And this is the point.  It doesn't matter if you are selling the right product or the right idea.  What matters is that your customer trusts you, and by that trust believes that YOU are right.  The product could be flawless, but if you customer doesn't know much about it, and doesn't trust you, then the products perfection counts for nothing.  &lt;br /&gt;&lt;br /&gt;This is what Micah did.  He wasn't trying to hype up 8th Light's methods and the Agile methodology.  He wasn't trying to sound really excited about how excellent this manner of developing was.  He was just being honest, straightforward, clear, and precise.   He convinced them, through expertise and experience, that HE was right.  It then follows that the ideas he was sharing with them were also right.  &lt;br /&gt;&lt;br /&gt;They, of course, got really excited.  The clients began talking about how excellent it would feel to not have to wake up to bug reports.  To be able to press one button, see a lot of green, and know that their program is working.  Then there was the excitement for the future, and all the amazing things their website would do.  &lt;br /&gt;&lt;br /&gt;It seems that the key is to demonstrate an understanding, and to be clear and honest in order to build up a very important trust that is necessary for all business interactions.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3714840552149734001-5181159269285987726?l=8thlightapprenticeship.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://8thlightapprenticeship.blogspot.com/feeds/5181159269285987726/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/02/day-20.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/5181159269285987726'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/5181159269285987726'/><link rel='alternate' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/02/day-20.html' title='Day 20'/><author><name>Justin</name><uri>http://www.blogger.com/profile/04054497811526894325</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://3.bp.blogspot.com/_snSMUhgzWLE/S0KeHj1cwNI/AAAAAAAAAAQ/f9gAgDyjN2A/S220/me.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3714840552149734001.post-834622888690691974</id><published>2010-01-31T21:27:00.000-08:00</published><updated>2010-02-01T19:55:36.338-08:00</updated><title type='text'>Day 19</title><content type='html'>Some serious refactoring and boolean reduction.  My last post showed an attempt at making a long if statement more readable, using a technique that really didn't fit the situation.  I used some hidden logic to generate some numbers with no clear meaning, to decide what action to take next.  Though the action was clear, how I arrived on this action was not.  I also drastically increased the amount of code in order to obtain only a bit more clarity.&lt;br /&gt;&lt;br /&gt;Micah and I went back to thoroughly refactored and reduced the if statement.  This was made quite easy because of a comprehensive test base, so that our refactoring could focus solely on simplification without worrying about function.&lt;br /&gt;&lt;br /&gt;The process of simplication is pretty amazing.  Though somewhat time consuming and attention demanding, it yielded some interesting results.  As we refactored, we simply looked for patterns in the code, and through these patterns we searched for a higher level of abstraction.  Bit by bit we were able to generalize and generalize until we would suddenly hit a new understanding, at which point great leaps of simplification could be made.&lt;br /&gt;&lt;br /&gt;So after many itterations and cycles of refactoring we discovered what the logic really meant, and thus were able to greatly reduce the number of lines of code it took to express the same algorithm.&lt;br /&gt;&lt;br /&gt;Once again, this is logic to decide what words need to be selected while dragging the mouse over some text after you double click and hold (in some word processors and this one, when you double click and drag the selection mode switches from individual characters to full words)  .  All of the 'isRightOf ' sorts of references refer to the position of the mouse in relation to the cursor and selected text.&lt;br /&gt;Here was the process:&lt;br /&gt;&lt;br /&gt;Starting with the If-Else chain I showed on my last post, we started refactoring out some of the conditionals into expressive methods:&lt;br /&gt;&lt;br /&gt;&lt;pre  style="background:#ffffff;color:#000000;"&gt;public &lt;span style=" font-weight:bold; color:#800000;"&gt;void&lt;/span&gt; invoke&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span style=" ;color:#800080;"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span style=" font-weight:bold; color:#800000;"&gt;if&lt;/span&gt; &lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;mouseIndex &lt;span style=" ;color:#808030;"&gt;&gt;&lt;/span&gt; boxInfo&lt;span style=" ;color:#808030;"&gt;.&lt;/span&gt;findWordsRightEdge&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;boxInfo&lt;span style=" ;color:#808030;"&gt;.&lt;/span&gt;cursorIndex&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span style=" ;color:#800080;"&gt;{&lt;/span&gt;&lt;br /&gt; &lt;span style=" font-weight:bold; color:#800000;"&gt;if&lt;/span&gt; &lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;mouseIndex &lt;span style=" ;color:#808030;"&gt;&gt;&lt;/span&gt; boxInfo&lt;span style=" ;color:#808030;"&gt;.&lt;/span&gt;selectionIndex&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;br /&gt; &lt;span style=" ;color:#800080;"&gt;{&lt;/span&gt;&lt;br /&gt;   boxInfo&lt;span style=" ;color:#808030;"&gt;.&lt;/span&gt;selectionIndex &lt;span style=" ;color:#808030;"&gt;=&lt;/span&gt; boxInfo&lt;span style=" ;color:#808030;"&gt;.&lt;/span&gt;cursorIndex&lt;span style=" ;color:#800080;"&gt;;&lt;/span&gt;&lt;br /&gt;   boxInfo&lt;span style=" ;color:#808030;"&gt;.&lt;/span&gt;cursorIndex &lt;span style=" ;color:#808030;"&gt;=&lt;/span&gt; boxInfo&lt;span style=" ;color:#808030;"&gt;.&lt;/span&gt;findWordsRightEdge&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;mouseIndex&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;span style=" ;color:#800080;"&gt;;&lt;/span&gt;&lt;br /&gt; &lt;span style=" ;color:#800080;"&gt;}&lt;/span&gt;&lt;br /&gt; &lt;span style=" font-weight:bold; color:#800000;"&gt;else&lt;/span&gt; &lt;span style=" font-weight:bold; color:#800000;"&gt;if&lt;/span&gt; &lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;boxInfo&lt;span style=" ;color:#808030;"&gt;.&lt;/span&gt;cursorIndex &lt;span style=" ;color:#808030;"&gt;&amp;lt;&lt;/span&gt; boxInfo&lt;span style=" ;color:#808030;"&gt;.&lt;/span&gt;selectionIndex&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;br /&gt;   boxInfo&lt;span style=" ;color:#808030;"&gt;.&lt;/span&gt;cursorIndex &lt;span style=" ;color:#808030;"&gt;=&lt;/span&gt; boxInfo&lt;span style=" ;color:#808030;"&gt;.&lt;/span&gt;findWordsLeftEdge&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;mouseIndex&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;span style=" ;color:#800080;"&gt;;&lt;/span&gt;&lt;br /&gt; &lt;span style=" font-weight:bold; color:#800000;"&gt;else&lt;/span&gt;&lt;br /&gt;   boxInfo&lt;span style=" ;color:#808030;"&gt;.&lt;/span&gt;cursorIndex &lt;span style=" ;color:#808030;"&gt;=&lt;/span&gt; boxInfo&lt;span style=" ;color:#808030;"&gt;.&lt;/span&gt;findWordsRightEdge&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;mouseIndex&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;span style=" ;color:#800080;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style=" ;color:#800080;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style=" font-weight:bold; color:#800000;"&gt;else&lt;/span&gt; &lt;span style=" font-weight:bold; color:#800000;"&gt;if&lt;/span&gt; &lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;mouseIndex &lt;span style=" ;color:#808030;"&gt;&amp;lt;&lt;/span&gt; boxInfo&lt;span style=" ;color:#808030;"&gt;.&lt;/span&gt;findWordsLeftEdge&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;boxInfo&lt;span style=" ;color:#808030;"&gt;.&lt;/span&gt;cursorIndex&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt; &lt;span style=" ;color:#808030;"&gt;&amp;amp;&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;&amp;amp;&lt;/span&gt; mouseIndex &lt;span style=" ;color:#808030;"&gt;&gt;&lt;/span&gt; boxInfo&lt;span style=" ;color:#808030;"&gt;.&lt;/span&gt;selectionIndex&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span style=" ;color:#800080;"&gt;{&lt;/span&gt;&lt;br /&gt; boxInfo&lt;span style=" ;color:#808030;"&gt;.&lt;/span&gt;cursorIndex &lt;span style=" ;color:#808030;"&gt;=&lt;/span&gt; boxInfo&lt;span style=" ;color:#808030;"&gt;.&lt;/span&gt;findWordsRightEdge&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;mouseIndex&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;span style=" ;color:#800080;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style=" ;color:#800080;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style=" font-weight:bold; color:#800000;"&gt;else&lt;/span&gt; &lt;span style=" font-weight:bold; color:#800000;"&gt;if&lt;/span&gt; &lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;mouseIndex &lt;span style=" ;color:#808030;"&gt;&amp;lt;&lt;/span&gt; boxInfo&lt;span style=" ;color:#808030;"&gt;.&lt;/span&gt;selectionIndex &lt;span style=" ;color:#808030;"&gt;&amp;amp;&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;&amp;amp;&lt;/span&gt; mouseIndex &lt;span style=" ;color:#808030;"&gt;&amp;lt;&lt;/span&gt; boxInfo&lt;span style=" ;color:#808030;"&gt;.&lt;/span&gt;findWordsLeftEdge&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;boxInfo&lt;span style=" ;color:#808030;"&gt;.&lt;/span&gt;cursorIndex&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;br /&gt;&lt;span style=" ;color:#800080;"&gt;{&lt;/span&gt;&lt;br /&gt; &lt;span style=" font-weight:bold; color:#800000;"&gt;if&lt;/span&gt; &lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;boxInfo&lt;span style=" ;color:#808030;"&gt;.&lt;/span&gt;cursorIndex &lt;span style=" ;color:#808030;"&gt;&gt;&lt;/span&gt; boxInfo&lt;span style=" ;color:#808030;"&gt;.&lt;/span&gt;selectionIndex&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;br /&gt;   boxInfo&lt;span style=" ;color:#808030;"&gt;.&lt;/span&gt;selectionIndex &lt;span style=" ;color:#808030;"&gt;=&lt;/span&gt; boxInfo&lt;span style=" ;color:#808030;"&gt;.&lt;/span&gt;cursorIndex&lt;span style=" ;color:#800080;"&gt;;&lt;/span&gt;&lt;br /&gt; boxInfo&lt;span style=" ;color:#808030;"&gt;.&lt;/span&gt;cursorIndex &lt;span style=" ;color:#808030;"&gt;=&lt;/span&gt; boxInfo&lt;span style=" ;color:#808030;"&gt;.&lt;/span&gt;findWordsLeftEdge&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;mouseIndex&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;span style=" ;color:#800080;"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style=" ;color:#800080;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style=" ;color:#800080;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;With a limited understanding of what the true nature of this logic was, we tried several different naming schemes to see what worked:&lt;br /&gt;&lt;br /&gt;&lt;pre  style="background:#ffffff;color:#000000;"&gt;&lt;span style=" font-weight:bold; color:#800000;"&gt;if&lt;/span&gt; &lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;isRightOfCursor&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;br /&gt; &lt;span style=" ;color:#800080;"&gt;{&lt;/span&gt;&lt;br /&gt;   &lt;span style=" font-weight:bold; color:#800000;"&gt;if&lt;/span&gt; &lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;isRightOfSelectionOnOriginalWord&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;br /&gt;   &lt;span style=" ;color:#800080;"&gt;{&lt;/span&gt;&lt;br /&gt;     swapSelectionDirectionAndExtendToRight&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;span style=" ;color:#800080;"&gt;;&lt;/span&gt;&lt;br /&gt;   &lt;span style=" ;color:#800080;"&gt;}&lt;/span&gt;&lt;br /&gt;   &lt;span style=" font-weight:bold; color:#800000;"&gt;else&lt;/span&gt; &lt;span style=" font-weight:bold; color:#800000;"&gt;if&lt;/span&gt; &lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;isSelectionFacingLeft&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;br /&gt;     reduceSelectionFromLeft&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;span style=" ;color:#800080;"&gt;;&lt;/span&gt;&lt;br /&gt;   &lt;span style=" font-weight:bold; color:#800000;"&gt;else&lt;/span&gt;&lt;br /&gt;     extendSelectionToRight&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;span style=" ;color:#800080;"&gt;;&lt;/span&gt;&lt;br /&gt; &lt;span style=" ;color:#800080;"&gt;}&lt;/span&gt;&lt;br /&gt; &lt;span style=" font-weight:bold; color:#800000;"&gt;else&lt;/span&gt; &lt;span style=" font-weight:bold; color:#800000;"&gt;if&lt;/span&gt; &lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;isLeftOfCursorInsideSelection&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;br /&gt; &lt;span style=" ;color:#800080;"&gt;{&lt;/span&gt;&lt;br /&gt;   reduceSelectionFromRight&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;span style=" ;color:#800080;"&gt;;&lt;/span&gt;&lt;br /&gt; &lt;span style=" ;color:#800080;"&gt;}&lt;/span&gt;&lt;br /&gt; &lt;span style=" font-weight:bold; color:#800000;"&gt;else&lt;/span&gt; &lt;span style=" font-weight:bold; color:#800000;"&gt;if&lt;/span&gt; &lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;isLeftOfSelection&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;br /&gt; &lt;span style=" ;color:#800080;"&gt;{&lt;/span&gt;&lt;br /&gt;   &lt;span style=" font-weight:bold; color:#800000;"&gt;if&lt;/span&gt; &lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;isSelectionFacingRight&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;br /&gt;     swapSelectionDirection&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;span style=" ;color:#800080;"&gt;;&lt;/span&gt;&lt;br /&gt;   extendSelectionToTheLeft&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;span style=" ;color:#800080;"&gt;;&lt;/span&gt;&lt;br /&gt; &lt;span style=" ;color:#800080;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style=" background:#dd0000; font-weight:bold; font-style:italic; color:#ffffff;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Then we worked to get some symmetry to simplify it:&lt;br /&gt;&lt;br /&gt;&lt;pre  style="background:#ffffff;color:#000000;"&gt;&lt;span style=" font-weight:bold; color:#800000;"&gt;if&lt;/span&gt; &lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;isRightOfCursor&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;br /&gt; &lt;span style=" ;color:#800080;"&gt;{&lt;/span&gt;&lt;br /&gt;   &lt;span style=" font-weight:bold; color:#800000;"&gt;if&lt;/span&gt; &lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;isInsideSelection&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;br /&gt;     reduceSelectionFromLeft&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;span style=" ;color:#800080;"&gt;;&lt;/span&gt;&lt;br /&gt;   &lt;span style=" font-weight:bold; color:#800000;"&gt;else&lt;/span&gt; &lt;span style=" font-weight:bold; color:#800000;"&gt;if&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;isRightOfSelection&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;br /&gt;   &lt;span style=" ;color:#800080;"&gt;{&lt;/span&gt;&lt;br /&gt;     &lt;span style=" font-weight:bold; color:#800000;"&gt;if&lt;/span&gt; &lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;isSelectionFacingLeft&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;br /&gt;       swapSelectionDirection&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;span style=" ;color:#800080;"&gt;;&lt;/span&gt;&lt;br /&gt;     extendSelectionToRight&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;span style=" ;color:#800080;"&gt;;&lt;/span&gt;&lt;br /&gt;   &lt;span style=" ;color:#800080;"&gt;}&lt;/span&gt;&lt;br /&gt; &lt;span style=" ;color:#800080;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style=" font-weight:bold; color:#800000;"&gt;else&lt;/span&gt; &lt;span style=" font-weight:bold; color:#800000;"&gt;if&lt;/span&gt; &lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;isLeftOfCursor&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;br /&gt; &lt;span style=" ;color:#800080;"&gt;{&lt;/span&gt;&lt;br /&gt;   &lt;span style=" font-weight:bold; color:#800000;"&gt;if&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;isInsideSelection&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;br /&gt;     reduceSelectionFromRight&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;span style=" ;color:#800080;"&gt;;&lt;/span&gt;&lt;br /&gt;   &lt;span style=" font-weight:bold; color:#800000;"&gt;else&lt;/span&gt; &lt;span style=" font-weight:bold; color:#800000;"&gt;if&lt;/span&gt; &lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;isLeftOfSelection&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;br /&gt;   &lt;span style=" ;color:#800080;"&gt;{&lt;/span&gt;&lt;br /&gt;     &lt;span style=" font-weight:bold; color:#800000;"&gt;if&lt;/span&gt; &lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;isSelectionFacingRight&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;br /&gt;       swapSelectionDirection&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;span style=" ;color:#800080;"&gt;;&lt;/span&gt;&lt;br /&gt;     extendSelectionToTheLeft&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;span style=" ;color:#800080;"&gt;;&lt;/span&gt;&lt;br /&gt;   &lt;span style=" ;color:#800080;"&gt;}&lt;/span&gt;&lt;br /&gt; &lt;span style=" ;color:#800080;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;This new format gave us the idea that we have a head and a tail, since the Cursor is always at the head we could say the selection ends at the tail.  Now we have a direction and position built into our abstraction:&lt;br /&gt;&lt;br /&gt;&lt;pre  style="background:#ffffff;color:#000000;"&gt;&lt;span style=" font-weight:bold; color:#800000;"&gt;if&lt;/span&gt; &lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;isRightOfHead&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;br /&gt;  &lt;span style=" ;color:#800080;"&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span style=" font-weight:bold; color:#800000;"&gt;if&lt;/span&gt; &lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;!&lt;/span&gt;isRightOfTail&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;br /&gt;      reduceSelectionFromLeft&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;span style=" ;color:#800080;"&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span style=" font-weight:bold; color:#800000;"&gt;else&lt;/span&gt; &lt;span style=" font-weight:bold; color:#800000;"&gt;if&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;isRightOfTail&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span style=" ;color:#800080;"&gt;{&lt;/span&gt;&lt;br /&gt;      &lt;span style=" font-weight:bold; color:#800000;"&gt;if&lt;/span&gt; &lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;isSelectionFacingLeft&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;br /&gt;        swapSelectionDirection&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;span style=" ;color:#800080;"&gt;;&lt;/span&gt;&lt;br /&gt;      extendSelectionToRight&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;span style=" ;color:#800080;"&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span style=" ;color:#800080;"&gt;}&lt;/span&gt;&lt;br /&gt;  &lt;span style=" ;color:#800080;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style=" font-weight:bold; color:#800000;"&gt;else&lt;/span&gt; &lt;span style=" font-weight:bold; color:#800000;"&gt;if&lt;/span&gt; &lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;!&lt;/span&gt; isRightOfHead&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;br /&gt;  &lt;span style=" ;color:#800080;"&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span style=" font-weight:bold; color:#800000;"&gt;if&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;isRightOfTail&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;br /&gt;      reduceSelectionFromRight&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;span style=" ;color:#800080;"&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span style=" font-weight:bold; color:#800000;"&gt;else&lt;/span&gt; &lt;span style=" font-weight:bold; color:#800000;"&gt;if&lt;/span&gt; &lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;!&lt;/span&gt;RightOfTail&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;br /&gt;    &lt;span style=" ;color:#800080;"&gt;{&lt;/span&gt;&lt;br /&gt;      &lt;span style=" font-weight:bold; color:#800000;"&gt;if&lt;/span&gt; &lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;isSelectionFacingRight&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;br /&gt;        swapSelectionDirection&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;span style=" ;color:#800080;"&gt;;&lt;/span&gt;&lt;br /&gt;      extendSelectionToTheLeft&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;span style=" ;color:#800080;"&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span style=" ;color:#800080;"&gt;}&lt;/span&gt;&lt;br /&gt;  &lt;span style=" ;color:#800080;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;A little Simplification:&lt;br /&gt;&lt;br /&gt;&lt;pre  style="background:#ffffff;color:#000000;"&gt;&lt;span style=" font-weight:bold; color:#800000;"&gt;if&lt;/span&gt; &lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;isRightOfHead&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;br /&gt;  &lt;span style=" ;color:#800080;"&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span style=" font-weight:bold; color:#800000;"&gt;if&lt;/span&gt; &lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;!&lt;/span&gt;isRightOfTail&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;br /&gt;      reduceSelectionFromLeft&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;span style=" ;color:#800080;"&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span style=" font-weight:bold; color:#800000;"&gt;else&lt;/span&gt;&lt;br /&gt;    &lt;span style=" ;color:#800080;"&gt;{&lt;/span&gt;&lt;br /&gt;      &lt;span style=" font-weight:bold; color:#800000;"&gt;if&lt;/span&gt; &lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;isSelectionFacingLeft&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;br /&gt;        swapSelectionDirection&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;span style=" ;color:#800080;"&gt;;&lt;/span&gt;&lt;br /&gt;      extendSelectionToRight&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;span style=" ;color:#800080;"&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span style=" ;color:#800080;"&gt;}&lt;/span&gt;&lt;br /&gt;  &lt;span style=" ;color:#800080;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style=" font-weight:bold; color:#800000;"&gt;else&lt;/span&gt;&lt;br /&gt;  &lt;span style=" ;color:#800080;"&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span style=" font-weight:bold; color:#800000;"&gt;if&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;isRightOfTail&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;br /&gt;      reduceSelectionFromRight&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;span style=" ;color:#800080;"&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span style=" font-weight:bold; color:#800000;"&gt;else&lt;/span&gt;&lt;br /&gt;    &lt;span style=" ;color:#800080;"&gt;{&lt;/span&gt;&lt;br /&gt;      &lt;span style=" font-weight:bold; color:#800000;"&gt;if&lt;/span&gt; &lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;isSelectionFacingRight&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;br /&gt;        swapSelectionDirection&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;span style=" ;color:#800080;"&gt;;&lt;/span&gt;&lt;br /&gt;      extendSelectionToTheLeft&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;span style=" ;color:#800080;"&gt;;&lt;/span&gt;&lt;br /&gt;    &lt;span style=" ;color:#800080;"&gt;}&lt;/span&gt;&lt;br /&gt;  &lt;span style=" ;color:#800080;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Now its clear that we are only doing 2 things.  Moving the head and swapping the head and the tail (which is really just turning around).  This allowed us to simplify the actions and lead us closer to a good solution.  (also a little extra extracting methods to variables and such):&lt;br /&gt;&lt;br /&gt;&lt;pre  style="background:#ffffff;color:#000000;"&gt;&lt;span style=" font-weight:bold; color:#800000;"&gt;if&lt;/span&gt; &lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;rightOfHead&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;br /&gt;   &lt;span style=" ;color:#800080;"&gt;{&lt;/span&gt;&lt;br /&gt;     &lt;span style=" font-weight:bold; color:#800000;"&gt;if&lt;/span&gt; &lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;!&lt;/span&gt;rightOfTail&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;br /&gt;       repositionHead&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;boxInfo&lt;span style=" ;color:#808030;"&gt;.&lt;/span&gt;findWordsLeftEdge&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;mouseIndex&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;span style=" ;color:#800080;"&gt;;&lt;/span&gt;&lt;br /&gt;     &lt;span style=" font-weight:bold; color:#800000;"&gt;else&lt;/span&gt;&lt;br /&gt;     &lt;span style=" ;color:#800080;"&gt;{&lt;/span&gt;&lt;br /&gt;       &lt;span style=" font-weight:bold; color:#800000;"&gt;if&lt;/span&gt; &lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;!&lt;/span&gt;selectionFacingRight&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;br /&gt;         turnAround&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;span style=" ;color:#800080;"&gt;;&lt;/span&gt;&lt;br /&gt;       repositionHead&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;boxInfo&lt;span style=" ;color:#808030;"&gt;.&lt;/span&gt;findWordsRightEdge&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;mouseIndex&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;span style=" ;color:#800080;"&gt;;&lt;/span&gt;&lt;br /&gt;     &lt;span style=" ;color:#800080;"&gt;}&lt;/span&gt;&lt;br /&gt;   &lt;span style=" ;color:#800080;"&gt;}&lt;/span&gt;&lt;br /&gt;   &lt;span style=" font-weight:bold; color:#800000;"&gt;else&lt;/span&gt;&lt;br /&gt;   &lt;span style=" ;color:#800080;"&gt;{&lt;/span&gt;&lt;br /&gt;     &lt;span style=" font-weight:bold; color:#800000;"&gt;if&lt;/span&gt; &lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;rightOfTail&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;br /&gt;       repositionHead&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;boxInfo&lt;span style=" ;color:#808030;"&gt;.&lt;/span&gt;findWordsRightEdge&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;mouseIndex&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;span style=" ;color:#800080;"&gt;;&lt;/span&gt;&lt;br /&gt;     &lt;span style=" font-weight:bold; color:#800000;"&gt;else&lt;/span&gt;&lt;br /&gt;     &lt;span style=" ;color:#800080;"&gt;{&lt;/span&gt;&lt;br /&gt;       &lt;span style=" font-weight:bold; color:#800000;"&gt;if&lt;/span&gt; &lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;selectionFacingRight&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;br /&gt;         turnAround&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;span style=" ;color:#800080;"&gt;;&lt;/span&gt;&lt;br /&gt;       repositionHead&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;boxInfo&lt;span style=" ;color:#808030;"&gt;.&lt;/span&gt;findWordsLeftEdge&lt;span style=" ;color:#808030;"&gt;(&lt;/span&gt;mouseIndex&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;span style=" ;color:#808030;"&gt;)&lt;/span&gt;&lt;span style=" ;color:#800080;"&gt;;&lt;/span&gt;&lt;br /&gt;     &lt;span style=" ;color:#800080;"&gt;}&lt;/span&gt;&lt;br /&gt;   &lt;span style=" ;color:#800080;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;At last it is clear, for the most part, what is going on.  We will always be moving the head, and we will be turning around only if the mouse is trailing the tail.  If we are going to the right, we will always be positioning the cursor on the right edge of the word.  Going to the left, the cursor is on the left edge of the word.  This understanding leads us to these two boolean equations, and their respective actions:&lt;br /&gt;&lt;br /&gt;&lt;pre style='color:#000000;background:#ffffff;'&gt;boolean isMouseTrailingTheTail &lt;span style='color:#808030; '&gt;=&lt;/span&gt; selectionFacingRight &lt;span style='color:#808030; '&gt;&amp;amp;&lt;/span&gt;&lt;span style='color:#808030; '&gt;&amp;amp;&lt;/span&gt; &lt;span style='color:#808030; '&gt;!&lt;/span&gt;rightOfTail &lt;span style='color:#808030; '&gt;|&lt;/span&gt;&lt;span style='color:#808030; '&gt;|&lt;/span&gt; &lt;span style='color:#808030; '&gt;!&lt;/span&gt;selectionFacingRight &lt;span style='color:#808030; '&gt;&amp;amp;&lt;/span&gt;&lt;span style='color:#808030; '&gt;&amp;amp;&lt;/span&gt; rightOfTail&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;boolean isHeadingToTheRight &lt;span style='color:#808030; '&gt;=&lt;/span&gt; selectionFacingRight &lt;span style='color:#808030; '&gt;&amp;amp;&lt;/span&gt;&lt;span style='color:#808030; '&gt;&amp;amp;&lt;/span&gt; &lt;span style='color:#808030; '&gt;!&lt;/span&gt;isMouseTrailingTheTail &lt;span style='color:#808030; '&gt;|&lt;/span&gt;&lt;span style='color:#808030; '&gt;|&lt;/span&gt; &lt;span style='color:#808030; '&gt;!&lt;/span&gt;selectionFacingRight &lt;span style='color:#808030; '&gt;&amp;amp;&lt;/span&gt;&lt;span style='color:#808030; '&gt;&amp;amp;&lt;/span&gt; isMouseTrailingTheTail&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;if&lt;/span&gt;&lt;span style='color:#808030; '&gt;(&lt;/span&gt;isMouseTrailingTheTail&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;br /&gt;  turnAround&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;if&lt;/span&gt;&lt;span style='color:#808030; '&gt;(&lt;/span&gt;isHeadingToTheRight&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;br /&gt;  repositionHead&lt;span style='color:#808030; '&gt;(&lt;/span&gt;boxInfo&lt;span style='color:#808030; '&gt;.&lt;/span&gt;findWordsRightEdge&lt;span style='color:#808030; '&gt;(&lt;/span&gt;mouseIndex&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;else&lt;/span&gt;&lt;br /&gt;  repositionHead&lt;span style='color:#808030; '&gt;(&lt;/span&gt;boxInfo&lt;span style='color:#808030; '&gt;.&lt;/span&gt;findWordsLeftEdge&lt;span style='color:#808030; '&gt;(&lt;/span&gt;mouseIndex&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Then with some boolean arithmetic and De' Morgan's Law I found a remarkably simple and, after the fact, obvious solution:&lt;br /&gt;&lt;br /&gt;&lt;pre style='color:#000000;background:#ffffff;'&gt;boolean isMouseTrailingTheTail &lt;span style='color:#808030; '&gt;=&lt;/span&gt; selectionFacingRight &lt;span style='color:#808030; '&gt;&amp;amp;&lt;/span&gt;&lt;span style='color:#808030; '&gt;&amp;amp;&lt;/span&gt; &lt;span style='color:#808030; '&gt;!&lt;/span&gt;rightOfTail &lt;span style='color:#808030; '&gt;|&lt;/span&gt;&lt;span style='color:#808030; '&gt;|&lt;/span&gt; &lt;span style='color:#808030; '&gt;!&lt;/span&gt;selectionFacingRight &lt;span style='color:#808030; '&gt;&amp;amp;&lt;/span&gt;&lt;span style='color:#808030; '&gt;&amp;amp;&lt;/span&gt; rightOfTail&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;if&lt;/span&gt;&lt;span style='color:#808030; '&gt;(&lt;/span&gt;isMouseTrailingTheTail&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;br /&gt;  turnAround&lt;span style='color:#808030; '&gt;(&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;if&lt;/span&gt;&lt;span style='color:#808030; '&gt;(&lt;/span&gt;rightOfTail&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;br /&gt;  repositionHead&lt;span style='color:#808030; '&gt;(&lt;/span&gt;boxInfo&lt;span style='color:#808030; '&gt;.&lt;/span&gt;findWordsRightEdge&lt;span style='color:#808030; '&gt;(&lt;/span&gt;mouseIndex&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span style='color:#800000; font-weight:bold; '&gt;else&lt;/span&gt;&lt;br /&gt;  repositionHead&lt;span style='color:#808030; '&gt;(&lt;/span&gt;boxInfo&lt;span style='color:#808030; '&gt;.&lt;/span&gt;findWordsLeftEdge&lt;span style='color:#808030; '&gt;(&lt;/span&gt;mouseIndex&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#808030; '&gt;)&lt;/span&gt;&lt;span style='color:#800080; '&gt;;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;A massive simplification, clarification, and reduction for what was once an incomprehensible If-Else chain.  This new form is leaps and bounds better than the switch statement.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3714840552149734001-834622888690691974?l=8thlightapprenticeship.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://8thlightapprenticeship.blogspot.com/feeds/834622888690691974/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/02/day-19.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/834622888690691974'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/834622888690691974'/><link rel='alternate' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/02/day-19.html' title='Day 19'/><author><name>Justin</name><uri>http://www.blogger.com/profile/04054497811526894325</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://3.bp.blogspot.com/_snSMUhgzWLE/S0KeHj1cwNI/AAAAAAAAAAQ/f9gAgDyjN2A/S220/me.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3714840552149734001.post-2889084626642280546</id><published>2010-01-28T23:20:00.000-08:00</published><updated>2010-01-29T07:40:59.937-08:00</updated><title type='text'>Day 18</title><content type='html'>Switch statement.  Most of the time it seems like a judgement call whether or not they are actually better than chains of if statements.  &lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Today I had a very large If-Else statement, and I needed some way to make it more transparent.  I wanted to use a jump table or hash-map to solve this.  I would create some key determined by a few common factors, and then assign a method to each key in the hash-map.  Unfortunately... to the best of my understanding, Java doesn't allow you to place method calls in has-maps.  I would have had to use the Command pattern, make some 'Runnable' classes for each of the methods I wanted, and then stick these runnable objects into the hash-map in place of the methods.  &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;A whole new Command Pattern seemed overkill to simplify my one method with the if-else chain, so instead I did Java's equivalent to a jump table.  A switch statement in Java actually compiles directly down to a jump table.  I find this a bit annoying because if Java is just going to make a jump table anyway, they should let me make one too.  Either way, I used the same basic principle to create a code, and then use the code to select the correct method.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The if statement was being used to decide some word selection criterion.  Say you double click and hold on a word,  if you then begin moving your cursor over another word, many text areas will jump into a word selection mode and select the entire word at once rather than just following your cursor.  So here was the if statement:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;      if (mouseIndex &gt; boxInfo.findWordsRightEdge(boxInfo.cursorIndex))&lt;br /&gt;      {&lt;br /&gt;        if (mouseIndex &gt; boxInfo.selectionIndex)&lt;br /&gt;        {&lt;br /&gt;          boxInfo.selectionIndex = boxInfo.cursorIndex;&lt;br /&gt;          boxInfo.cursorIndex = boxInfo.findWordsRightEdge(mouseIndex);&lt;br /&gt;        }&lt;br /&gt;        else if (boxInfo.cursorIndex &lt; boxInfo.selectionIndex)&lt;br /&gt;          boxInfo.cursorIndex = boxInfo.findWordsLeftEdge(mouseIndex);&lt;br /&gt;        else&lt;br /&gt;          boxInfo.cursorIndex = boxInfo.findWordsRightEdge(mouseIndex);&lt;br /&gt;      }&lt;br /&gt;      else if (mouseIndex &lt; boxInfo.findWordsLeftEdge(boxInfo.cursorIndex) &amp;&amp; mouseIndex &gt; boxInfo.selectionIndex)&lt;br /&gt;      {&lt;br /&gt;        boxInfo.cursorIndex = boxInfo.findWordsRightEdge(mouseIndex);&lt;br /&gt;      }&lt;br /&gt;      else if (mouseIndex &lt; boxInfo.selectionIndex &amp;&amp; mouseIndex &lt; boxInfo.findWordsLeftEdge(boxInfo.cursorIndex))&lt;br /&gt;      {&lt;br /&gt;        if (boxInfo.cursorIndex &gt; boxInfo.selectionIndex)&lt;br /&gt;          boxInfo.selectionIndex = boxInfo.cursorIndex;&lt;br /&gt;        boxInfo.cursorIndex = boxInfo.findWordsLeftEdge(mouseIndex);&lt;br /&gt;      }&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Unfortunately blogspot makes it rather difficult to display code, and the if statement is hardly readable even properly formated, so good luck reading that...&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So to refactor this I created a method object, and used a few criterion to determine an index, and then plugged this into a switch statement.  I then made a descriptive method for each action.  Here is the refactored code:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;    public void makeProperWordSelection()&lt;br /&gt;    {&lt;br /&gt;&lt;br /&gt;      switch (calculateSelectionDispatchIndex())&lt;br /&gt;      {&lt;br /&gt;        case 0:&lt;br /&gt;          extendSelectionToRight();&lt;br /&gt;          break;&lt;br /&gt;        case 1:&lt;br /&gt;          extendSelectionToRight();&lt;br /&gt;          break;&lt;br /&gt;        case 2:&lt;br /&gt;          reduceSelectionFromTheLeft();&lt;br /&gt;          break;&lt;br /&gt;        case 3:&lt;br /&gt;          swapSelectionDirectionAndExtendToRight();&lt;br /&gt;          break;&lt;br /&gt;        case 4:&lt;br /&gt;          swapSelectionDirectionAndExtendToLeft();&lt;br /&gt;          break;&lt;br /&gt;        case 5:&lt;br /&gt;          reduceSelectionFromTheRight();&lt;br /&gt;          break;&lt;br /&gt;        case 6:&lt;br /&gt;          extendSelectionToLeft();&lt;br /&gt;          break;&lt;br /&gt;      }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    private int calculateSelectionDispatchIndex()&lt;br /&gt;    {&lt;br /&gt;      int dispatchIndex = 0;&lt;br /&gt;      if (mouseIndex &gt; boxInfo.getSelectionIndex())&lt;br /&gt;        dispatchIndex += 1;&lt;br /&gt;      if (boxInfo.getCursorIndex() &lt; boxInfo.getSelectionIndex())&lt;br /&gt;        dispatchIndex += 2;&lt;br /&gt;      if (mouseIndex &lt; boxInfo.findWordsLeftEdge(boxInfo.getCursorIndex()))&lt;br /&gt;        dispatchIndex += 4;&lt;br /&gt;      return dispatchIndex;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    private void swapSelectionDirectionAndExtendToLeft()&lt;br /&gt;    {&lt;br /&gt;      boxInfo.setSelectionIndex(boxInfo.getCursorIndex());&lt;br /&gt;      boxInfo.setCursorIndex(boxInfo.findWordsLeftEdge(mouseIndex));&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    private void reduceSelectionFromTheRight()&lt;br /&gt;    {&lt;br /&gt;      boxInfo.setCursorIndex(boxInfo.findWordsRightEdge(mouseIndex));&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    private void extendSelectionToLeft()&lt;br /&gt;    {&lt;br /&gt;      boxInfo.setCursorIndex(boxInfo.findWordsLeftEdge(mouseIndex));&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    private void reduceSelectionFromTheLeft()&lt;br /&gt;    {&lt;br /&gt;      boxInfo.setCursorIndex(boxInfo.findWordsLeftEdge(mouseIndex));&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    private void swapSelectionDirectionAndExtendToRight()&lt;br /&gt;    {&lt;br /&gt;      boxInfo.setSelectionIndex(boxInfo.getCursorIndex());&lt;br /&gt;      boxInfo.setCursorIndex(boxInfo.findWordsRightEdge(mouseIndex));&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    private void extendSelectionToRight()&lt;br /&gt;    {&lt;br /&gt;      boxInfo.setCursorIndex(boxInfo.findWordsRightEdge(mouseIndex));&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;Its debate-able whether or not this is actually better, but I think it at least makes it more readable if you are looking for a specific outcome.  It just so happens that it lined up much better with the tests.&lt;br /&gt;I'd like to hear if you think this helps or not, and if not, how you would refactor.&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3714840552149734001-2889084626642280546?l=8thlightapprenticeship.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://8thlightapprenticeship.blogspot.com/feeds/2889084626642280546/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/01/day-18.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/2889084626642280546'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/2889084626642280546'/><link rel='alternate' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/01/day-18.html' title='Day 18'/><author><name>Justin</name><uri>http://www.blogger.com/profile/04054497811526894325</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://3.bp.blogspot.com/_snSMUhgzWLE/S0KeHj1cwNI/AAAAAAAAAAQ/f9gAgDyjN2A/S220/me.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3714840552149734001.post-4014277740512238309</id><published>2010-01-27T17:44:00.000-08:00</published><updated>2010-01-27T19:59:28.096-08:00</updated><title type='text'>Day 17</title><content type='html'>Lots of busy work today.  Micah was trying to whip together a quick website that could do HD video streaming.  As a result, I spent a lot of time fishing for HD videos we could use as well as getting converters to get the video format we needed.  Blasted watermarks...  Useable free converters are a rare commodity.  Also, who knew there were so many versions and formats for .mp4 files alone?  Its kinda ridiculous.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Streaming videos was another topic we looked into.  As it turns out, real streaming is actually fairly rare.  YouTube by default doesn't actual, at least for all the videos I looked at, use streaming.  True streaming is where the video data is only on your computer for as long as it needs to be.  Typically there is a slight buffer, so the video is loaded for just a few seconds before the portion which you are watching, but after you watch it - it is gone.  It doesn't save the video on your computer, nor does it keep downloading if you stop watching.  It only downloads as much as is needed to create a reasonable buffer.&lt;/div&gt;&lt;div&gt;Most sites will simple download the video onto your computer and play it from your computer's memory rather than from a live feed.  What is often mistook for streaming is when the video is downloaded, but starts playing before it is complete.  This is what most websites seem to do, and as a result the file is actually on the computer...&lt;/div&gt;&lt;div&gt; Now that I think about it... in a way that seems to be breaking copyright laws in some manner.  A sight like Pandora, which 'streams' songs like a radio, is actually creating copy after copy of those songs on the client's computer.  Since the files are already on your computer, the distribution has already been achieved.  In most cases the client never knows this, and the file is deleted once they close the browser or perhaps when the cache is cleared; however, it is actually quite easy to capture those files.  All you have to do is find the source of the file (which the browser tells you by the way...) and then redirect the download to say... your desktop.  &lt;/div&gt;&lt;div&gt;This isn't so easy with real streaming.  I don't know of anyway, yet, to capture and save a live stream.  I am sure it is possible, but it certainly seems like it is less of a copyright violation.  You would actually have to be making a copy of the data that is otherwise free flowing through the web and your computer.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So how about that iPad?  I know a lot of people are saying its no big deal - it doesn't really have anything new - it's just a bigger iPhone.  I suggest you think twice.&lt;/div&gt;&lt;div&gt;Consider the difference between a little car and a bigger car.  They are really just the same thing.  They basically have all the same parts, nothing exceptionally different... its just that one is bigger.  Consider that the purpose and goal of each car is to get the driver from point A to point B.  The size difference, however, is no small matter. giggle giggle.   There are a vast number of things you can do with a big car that you couldn't dream of doing with a small one, such as: hauling a trailer, driving many passengers, carrying lots of luggage or boxes, and a lot more.  Naturally a small car can do things the bigger car can't do as well, but the point is that the fact that they are drastically different in size makes a huge difference!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The iPad will have thousands of new possibilities and enormous potential because of its greater size.  It will live in a whole new niche of its own.  At first, I see this device being extremely desirable for most common house wives/husbands who use computers for just a few key things.  They like to have access to a computer in their kitchen, or study that they can use to write papers, surf the web, write emails, watch movies or videos, collect (but certainly not listen to) music, and so forth. These are the exact things which the iPad will offer.  Not only will it provide those things, it provides them in better ways, and for less of a dent in the piggy bank. &lt;/div&gt;&lt;div&gt;Soon after these house wives/husbands become addicted to the iPad, bringing it everywhere in the house that they go and almost making it a 5th limb, their spouses will begin to really want one too.  &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The next, and fairly obvious, niche the iPad will fill is the student's backpack.  It's easy to picture a classroom of students using iPads to take notes in class, read their text books, work on their homework, check and set their schedule, and even take quizzes or tests on secure networks.  How could anyone brush off the iPad as no big deal when it could completely revolutionize the way students interact with their classes.  Backpacks could transform from - heavy burdens filled with books, calculators, pencils, and other various materials  - to a lightweight carrier for a single 1.5lb electric device and maybe a few utensils. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;These are just two, out of many, clear niches that no other product has yet been able to fill, and that the iPad will slide into gloriously.  &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This is just the beginning.&lt;/div&gt;&lt;div&gt;If you don't think this product will succeed, sell all your apple stock and make it cheaper for me to buy it all up.&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;On a side note... I have to agree that its kinda crappy it doesn't have multitasking.  I sure hope they include this in later versions because its pretty stupid to not be able to write a paper while listening to Pandora.&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3714840552149734001-4014277740512238309?l=8thlightapprenticeship.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://8thlightapprenticeship.blogspot.com/feeds/4014277740512238309/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/01/day-17.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/4014277740512238309'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/4014277740512238309'/><link rel='alternate' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/01/day-17.html' title='Day 17'/><author><name>Justin</name><uri>http://www.blogger.com/profile/04054497811526894325</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://3.bp.blogspot.com/_snSMUhgzWLE/S0KeHj1cwNI/AAAAAAAAAAQ/f9gAgDyjN2A/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3714840552149734001.post-2758313419399031564</id><published>2010-01-26T18:54:00.000-08:00</published><updated>2010-01-26T20:13:27.053-08:00</updated><title type='text'>Day 16</title><content type='html'>Estimating a large project can be a very time consuming endeavor.  Today Micah and I were making estimating how many man days it would take to build up a project for a possible client.  First, Micah spent several hours splitting up the project into groups of stories, organized by topic and possible release points.  Then we sat down and estimated every single one of the stories, first briefly discussing what it would entail, and then sticking both hands out and giving some estimates.  I believe I have discussed the optimistic-realistic-pessimistic estimate strategy Micah uses, but what I would like to discuss is how long it all takes.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Some stories are easy to estimate and take 30 seconds to a minute to figure out.  Other stories can take a few minutes if we have to discuss, in a fair amount of detail, what it will require.  When you have a lot of stories to get through, this process just takes too long.  I would imagine the same danger comes in with SAT graders who, after spending the whole day grading, might start to rush a little bit.  Near the last few stories, the estimates begin to come off a bit faster.   Given, these are just estimates and not hard contracts, it could still be a concern.  It might be better to do just a few estimates at a time, or perhaps to charge a small fee to get an estimate since it takes so much time.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;"90% of confusion comes from bad naming" - Eric Smith.  Its funny that he said this today, because I also got a text from a previous co-worker today quoting some of my code: &lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: arial, sans-serif; font-size: 13px; "&gt;be_in_the_tab =  !conditional_no&lt;wbr&gt;t.nil? &lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: arial, sans-serif; font-size: 13px; "&gt;&lt;/span&gt;Its pretty awful...  I spent a few minutes myself just trying to figure out what I meant.  The issue is the name 'conditional_not' which was actually a boolean meant to represent if the word "not" was in a string.  This was for a cucumber step definition, which had an affirmative and negative version, so I wanted to keep the same logic but just reverse it if there was a 'not' in the acceptance test.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So true it is though.  One poorly named class can drastically confound the poor soul trying to unveil the intent of a package.  One inaccurately named method can hide the purpose of a class.  A single thoughtlessly named variable can transform a simple method into an enigma.  Just one boolean named 'conditional_not' can inspire a coworker to remind you of your ineptitude. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;If you can't think of the right name for a class, method, or variable at the time you need it, then remind yourself to change it later.  You don't want to be leaving behind a trail of confusion.  Just as a poor name can hide the purpose or goal of some code, a good name can make it clear as day.  &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3714840552149734001-2758313419399031564?l=8thlightapprenticeship.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://8thlightapprenticeship.blogspot.com/feeds/2758313419399031564/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/01/day-16.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/2758313419399031564'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/2758313419399031564'/><link rel='alternate' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/01/day-16.html' title='Day 16'/><author><name>Justin</name><uri>http://www.blogger.com/profile/04054497811526894325</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://3.bp.blogspot.com/_snSMUhgzWLE/S0KeHj1cwNI/AAAAAAAAAAQ/f9gAgDyjN2A/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3714840552149734001.post-8732241828669026290</id><published>2010-01-25T17:19:00.000-08:00</published><updated>2010-01-25T18:03:24.644-08:00</updated><title type='text'>Day 15</title><content type='html'>Its amazing what men can do.  Its simply astounding to look at a website, see that it works and has all these neat features and nic-nacs... and then you look at the code and your brain drips away into a coma.  These days, with Rails and all, its pretty easy to whip up a website, add some nice features, and show someone else your code without them vomiting.  In fact, they might actually be able to add on to your code without leading to code rot.  I think, however, it is the true test of man to be able to write an absolutely heaping... smoldering mass of what only a maladjusted juvenile from the pits of a decaying Sparta could call code, and then to be able to add features to it.  Its kind of like going down a mile of slip and slide made of sand paper and coated with boiling oil saturated with salt... it takes some serious balls.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I saw this pile of code today.  I swear when Micah opened the file a small chunk of my soul escaped into the null ether.  Written primarily in PHP, coated in some HTML, and lathered with hidden chunks of JavaScript, this project was pretty nasty.  &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;To begin I did some wikiearch (its like research... but with wiki's) and I discovered that PHP is quite similar to Java or C++ in syntax, but is more of a dynamic language.  So unconcerned with my ability to decipher the meaning of some jolly PHP files, I joined up with Micah to look at the code.  &lt;/div&gt;&lt;div&gt;Normally when I see experienced programmers look at a new batch of code, even if it is pretty cryptic, I see little flares or sparks in their eyes as they catch something familiar and gain a greater understanding of the code's intent.  Sometimes I even see smirks as a connections are formed and the big picture sets in.   Micah's face was solid, unflinching, and deeply determined to find any meaning in the code.  &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;It's times like these that make me really appreciate knowing about this whole Agile - Craftsmanship world.  All I could picture, as we attempted to decrypt the code, was a team of men trying to change the color of a single item of text on a page and as a result were pulling out gobs of rapidly graying hair, screaming and yelling in the ancient spirit of the blame game, and a pilling up the corpses of the developers before them.   &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This is why I will now vow that:&lt;/div&gt;&lt;div&gt; &lt;/div&gt;&lt;div&gt;- I, Justin Martin, shall never, for any reason beholding, relinquish or let degrade my standards of code, and hereby choose to do unto my code that which I wish others would do unto me"&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Perhaps a bit much... but just like a pendulum, when you swing far to one side you can't help but swing far back to the other.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3714840552149734001-8732241828669026290?l=8thlightapprenticeship.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://8thlightapprenticeship.blogspot.com/feeds/8732241828669026290/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/01/day-15.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/8732241828669026290'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/8732241828669026290'/><link rel='alternate' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/01/day-15.html' title='Day 15'/><author><name>Justin</name><uri>http://www.blogger.com/profile/04054497811526894325</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://3.bp.blogspot.com/_snSMUhgzWLE/S0KeHj1cwNI/AAAAAAAAAAQ/f9gAgDyjN2A/S220/me.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3714840552149734001.post-5257731270286242350</id><published>2010-01-21T23:45:00.000-08:00</published><updated>2010-01-22T22:04:28.432-08:00</updated><title type='text'>Day 13</title><content type='html'>I got a lot of tid-bits of information today.  I spent much of the day making a Keynote presentation for one of our new potential client, using the mockups that I created from Balsamiq.  Micah and I then did some estimates on how many man-hours it would take to finish a workable minimum value sort of design.  I also attending an iteration meeting and a code review on another one of 8th Light's projects.  After work I went to a Scala User Group and heard a talk from Daniel Spiewak.  He was very impressive, offering good information along with answering a lot of excellent questions.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;From the code review I learned how difficult it can be working with a third party application.  Say you have set up an application with a design that fits it nicely, and a flow that suites all of your needs.  Then, suddenly your customer wants you to use an unanticipated third party program or web service in your application.  Even if you have a nicely organized, highly decoupled and flexible program, implementing a third party into the mix can be quite a challenge.  &lt;/div&gt;&lt;div&gt;The first challenge would of course be understanding how this third party program works.  This might be reasonable, but your employer wants you to start implementing it NOW.  So you start writing code, rather guessing how it works, and within less time than you might think, you get a bit of a mess.  The more you incorporate the third party app, the more you learn about it, and the more you realize that you were wrong when you started working with it.  Yet, you can't just go back and try again because your customer is expecting functionality and isn't all that pleased when you tell him/her that you have to take it away.&lt;/div&gt;&lt;div&gt;Another issue is that you might be fitting a square block into a round hole.  You have this pretty design that you are extremely pleased with, and suddenly you have to find a way to jam some ugliness into it.  Not saying all third party apps are ugly, but it seems like thats how they always appear when you first realize you have to fit it in with your design.  Of course, you can't suddenly redesign your entire program just to work with this third party app, because your customer would freak.  Instead you have to use some hodge-podge means to link everything together.  If your not super careful, which is extremely difficult but always easy in hindsight, you will wind up with a mess.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The way Micah and I did the estimating was pretty interesting, and made a lot of sense.  He set up a table with the features - an optimistic - a realistic - and a pessimistic estimate of how long the each feature would take.  Then he calculated the standard deviation for each feature, and for the project as a whole.  This gave us a pretty big range for how long this project might take, which I believe is necessary since it is virtually impossible to accurately estimate a fair sized project before you even get started.  &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;From the talk and after:&lt;/div&gt;&lt;div&gt; * Mix-in: A way to add functionality to a class or instance by making a new class or module which isn't meant to be instantiated.  In Ruby, you can do this by creating a module with some concrete methods, and then extend from this module in some other class.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;* Comet:  This is a HTTP means to maintain a long held link between a server and a browser.  Typically HTTP sends a request, waits for a response, then sends data.  This is a very tedious process, and doesn't fit all models.  Using Comet allows the server to keep an open connection and send data without receiving any reply.  Systems similar to Google Wave, with live updates, would use something like comet.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;* Actors:  An actor is actually a mathematical model for performing parallel or concurrent computation.  When using the model, everything is an actor.  Actors don't run sequentially or in a particular order, but run simultaneously.  Actors can send messages to one another, create new actors, and perform some specific actions.  Since everything is an actor, there is no supreme controller, thus actors can only talk to actors they know about.  One of the biggest advantages to the Actor Model is that it separates the sender from sent communications.&lt;/div&gt;&lt;div&gt;   - Supervised Actors:  This is an Actor Model, but with a supervisor for each actor that can monitor its activity.  The main purpose I gathered from the supervisor, is that if the actor is destroyed for whatever reason, the supervisor can see this and restart the actor.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;* Cake Pattern: The Cake Pattern is a way to implement Dependency Injection, largely in Scala.    &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3714840552149734001-5257731270286242350?l=8thlightapprenticeship.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://8thlightapprenticeship.blogspot.com/feeds/5257731270286242350/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/01/day-13.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/5257731270286242350'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/5257731270286242350'/><link rel='alternate' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/01/day-13.html' title='Day 13'/><author><name>Justin</name><uri>http://www.blogger.com/profile/04054497811526894325</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://3.bp.blogspot.com/_snSMUhgzWLE/S0KeHj1cwNI/AAAAAAAAAAQ/f9gAgDyjN2A/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3714840552149734001.post-4227437322261860245</id><published>2010-01-20T21:17:00.000-08:00</published><updated>2010-01-20T22:45:30.137-08:00</updated><title type='text'>Day 12</title><content type='html'>I spent today creating a mockup of a website we will be building for a client.  First I was using Photoshop to, rather tediously, make layer after layer to build up a flexible mockup.  I was making it in a similar manner to how I write a program.  I followed the Single Responsibility Principle in that I gave each layer a single purpose so that I could more easily reuse each layer, and mix and match them when the time came to make a Keynote presentation.&lt;div&gt;Then Micah found a cool mockup tool called Balsamiq mockup, which not only is design to make mockups, but also makes the mockup look... like a mockup.  All the components, like text panels and button, have a hand drawn - kindergarden sort of look.  This is especially cool because it emphasizes to the client that what you are presenting is in no way a hint towards the actual website design.  It emphasizes that the mockup's only purpose is to demonstrate how the website might function and flow, largely in order to get some feedback.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Design Patterns:&lt;/div&gt;&lt;div&gt;* Factory Method Pattern: The Factory Method Pattern is a way to design an application that can create objects and act upon them, without actually knowing what class defines the object.  It pushes the responsibility of defining which objects to instantiate to the subclasses.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The actual pattern is summed up in a single method, the Factory Method, and the rest is to make that method work.  This is either an abstract method, or a method with a simple default constructor that is to be overridden.  The Factory Method lies in the Creator class, and it returns an object called the Product.  The Product is actually an interface that defines the objects which the Factory Method is meant to create.  The Concrete Product is the implementation of the Product, and is actually created in the Concrete Creator, which implements the Creator.&lt;/div&gt;&lt;div&gt;So there is an application with a Factory Method.  This application is meant to be versatile, and can't know the classes of the objects it is creating, but must act on them none the less.  Some user of this application defines a Concrete Product and defines a Concrete Creator.  Another part of the application tells the Creator that it needs a Product. The Creator then uses its Factory Method, which has now been overridden by the Concrete Creator, to make a Product, and returns a Concrete Product from the Concrete Creator.  Then another part of the application can tell the Creator to perform some operation on the Concrete Product. The Creator can perform operations on the object without knowing its actual origin or class since the object implements the Product interface.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;A simple example of this comes in the form of ice cream, and everyone likes ice cream.  Say there is some ice cream cone maker that can put together a hot fudge ice cream cone.  This dream maker doesn't know what flavor of ice cream is in the cone, nor does it care.  All the dream maker knows is that it can put some fudge on some ice cream.  The dream maker or Creator will make a cone only when something tells it to.  The Creator will say ' I'm going to make a cone now' or run the Factory Method, at which point some other machine, the Concrete Creator, will supply the dream maker with a bucket of, say, vanilla ice cream or Concrete Product.  The dream maker will then scoop up the Product, put it in a cone, and perform its fudging operation on the Product.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;* Singleton Pattern: The Singleton Pattern is a simple pattern designed to help make sure there is one, and only one instance of a class. This is useful in situations where you have a system with several classes looking to use a Singleton, but if there are multiple instances of the Singleton, then the system breaks down.  Some examples of this would be if you had some application with a Context class that holds all the essential data for the app, or if you had an operating system with a file system storing all the information of the running processes.  Multiple unexpected contexts or file systems could complete destroy the program, thus you want to make sure there is always just one.&lt;/div&gt;&lt;div&gt;This works by designing a Singleton class that catches all attempts to construct it and with an easy and well known way to get the existing instance.  You would create a class which has some static reference to itself.  This reference could be initialized to null, or could be given a static instance.  The Singleton's constructor should be set to do nothing, to defeat attempts at re-instantiation.  You would also create a static getInstance() method, which would return the single instance. This would be the method all classes would use to get the Singleton instance.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;If you used lazy instantiation by starting the Singleton ref out as null, then you get the benefit of only creating an instance when it is needed, but then you also might get a nasty race condition.  Assuming in your getInstance() method you check to see if the ref is null before you instantiate it, then if you have two threads running which call getInstance() at the same time, it is possible that one thread will pass the conditional statement and then loose the processor before it creates an instance.  Then the other thread could create an instance, return the processor to the first thread, which would then create a second instance since it already checked for null.  So if you are using a Singleton in a multithreaded environment, you might be better off taking the safe route and sacrifice your lazy initialization to make sure you never end up with a race condition.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3714840552149734001-4227437322261860245?l=8thlightapprenticeship.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://8thlightapprenticeship.blogspot.com/feeds/4227437322261860245/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/01/day-12.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/4227437322261860245'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/4227437322261860245'/><link rel='alternate' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/01/day-12.html' title='Day 12'/><author><name>Justin</name><uri>http://www.blogger.com/profile/04054497811526894325</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://3.bp.blogspot.com/_snSMUhgzWLE/S0KeHj1cwNI/AAAAAAAAAAQ/f9gAgDyjN2A/S220/me.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3714840552149734001.post-2028959448662499913</id><published>2010-01-19T18:49:00.000-08:00</published><updated>2010-01-20T21:17:32.099-08:00</updated><title type='text'>Day 11</title><content type='html'>I started the day off by finishing the refactoring of the Painter classes, and their respective tests.  I then began thinking of the ways I could isolate regions to be individually marked as dirty and repainted with the appropriate painters.  The biggest issue is that anytime a region needs to be repainted, I need to discover what text lies in that region, if there was a selection in that region, and where the cursor was.  &lt;div&gt;Repainting all these different components independently and situationally might actually end up being slower than skipping all the extra logic, and just repainting the full region each time it is marked dirty.  To be certain that I am actually optimizing rather than slowing, I will need to find out what part of the painting process is slow. Once I have some metrics to determine which of the following takes longer - painting pixels, determining which pixels to paint, or defining regions - I can then move to minimize the time consuming actions to optimize the paint algorithm.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The last part of my day was spent working with Micah on a new Rails app.  We were trying to find ways to make accessing a bunch of the client's data intuitive for the users of the app.  Since we really weren't sure how these users wanted to view the data, we were basically shooting in the dark with some general solutions.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;To really know what the client wants, especially when you aren't sure how they want to use the app, is nearly impossible.  This is why we will present to them a basic and minimum functionality demo in order to get some feedback and hone in on a better solution to meet their needs.  We must stay flexible and not set our hearts on a certain solution.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Now I must begin making some general concepts of what the website will look like and how it will function using PhotoShop.  We will use the photoshop generated images to show the overall feel and flow of the website in powerpoint slides.  I suppose we wont begin really coding until we know we are heading in the right direction.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Design Patterns:&lt;/div&gt;&lt;div&gt;* Abstract Factory Pattern: The Abstract Factory Pattern can be used when there is a need for multiple groups of related objects without having to specify any concrete classes.  In other words, the AFP is useful if you have several themes, with multiple components, that you want to be interchangeable to one idea or niche. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This works by first creating an Abstract Factory class that is to be the interface the client uses to make its desired theme.  The Abstract Factory will have some concrete subclasses, one for each theme, which will implement the interface's abstract methods, and that will be used to generate the different components of the underlining idea for the respective theme.&lt;/div&gt;&lt;div&gt;There is also an interface for each of the different components of the underlining idea, and each theme will have its own implementation of these component interfaces.&lt;/div&gt;&lt;div&gt;Each of the Abstract Factory subclasses, call them Themed Factories, will depend on the corresponding concrete component classes.  &lt;/div&gt;&lt;div&gt;When then client asks its Abstract Factory reference to generate an instance of the underlining idea or a component, the operation is delegated to whatever Themed Factory is populating the reference.  In this way, the client never has to know about any of the concrete classes, but can receive instances of them none the less.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Say there is some simple clothing store.  This store sells just one top and one bottom, which differ depending on if its summer or winter.  This store wants some program to manage what items they are selling at any given point, and they hire you to make this system.  You decide that you can implement this using the Abstract Factory Pattern, and so you start designing away.  You make a ClothingFactory interface (the Abstract Factory) and then implement it with a concrete SummerClothingFactory and a WinterClothingFactory (Themed Factories).  You also create a TopClothing and a BottomClothing interface (Components), and then implement these with concrete summer and winter  -  top and bottom classes  (Themed Components). Finally you link the Themed Factories with their respective Themed Components so that the factories can generate instances of the components. &lt;/div&gt;&lt;div&gt;The client to your ClothingFactory, likely a cash register or online register, holds a reference to the factory.  The reference is populated, with either of the Themed Factories, by the application's main class, based off whether its summer or winter.  The client may then ask the factory for a top, or a bottom, and will get the appropriate clothing object without ever knowing about the different types.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;An excellent advantage to this is that if the store owners wanted to add footwear to their vast variety of clothing, you could easily add sneakers to the summer theme and snow shoes to the winter theme.  The Themed Factories could then be made to implement constructors for the footwear, and you would never have to worry about selling a t-shirt and shorts along with a pair of snow shoes.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3714840552149734001-2028959448662499913?l=8thlightapprenticeship.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://8thlightapprenticeship.blogspot.com/feeds/2028959448662499913/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/01/day-11.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/2028959448662499913'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/2028959448662499913'/><link rel='alternate' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/01/day-11.html' title='Day 11'/><author><name>Justin</name><uri>http://www.blogger.com/profile/04054497811526894325</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://3.bp.blogspot.com/_snSMUhgzWLE/S0KeHj1cwNI/AAAAAAAAAAQ/f9gAgDyjN2A/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3714840552149734001.post-5739141140975394540</id><published>2010-01-18T18:49:00.000-08:00</published><updated>2010-01-18T21:36:46.780-08:00</updated><title type='text'>Day 10</title><content type='html'>Today was all about optimizing the paint method for the TextInputPanel.  I spent awhile trying out a few different strategies, picking and choosing things that worked and that I liked, and finally decided on one.  It ended up being a combination of a Command Pattern, and another strategy that is similar to a Facade Pattern, but is lacking  in the logic.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I made a TextPanelPainter interface with an abstract paint(Graphics2D g2) method.  The subclasses would be a variety of single purpose painters like the TextPanelCursorPainter, or SelectionPainter, which would use an instance of the TextModel to change some data and draw the appropriate graphics.  This is the Command Pattern portion.  &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In order to avoid having to create a new instance of say the CursorPainter every time the cursor had to be redrawn, I created a PainterStore class.  The PainterStore would, upon initialization, make and save an instance of all the TextPanelPainters, as well as contain getters for each of them.  This way, everytime I needed a CursorPainter, I would ask my PainterStore instance for one.  This would be a Facade, if I gave the store all the logic, asked it for the painter I need, and then it spat out the appropriate painter based on the situation.  I may switch to the Facade Pattern if I find an easy way to implement it.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The TextInputPanel would have a single painter reference, and anytime the panel was marked as dirty, it would called paint() on the painter.  The painter would contain a reference to the paint job needed to be performed.  For example, if a selection was being made and the user was holding shift and pressing an arrow key, then a SelectionPainter would get placed in the painter reference.  When the key was finished being processed and the panel marked dirty, Limelight would then tell the panel to repaint, at which point the painter would call paint() and the SelectionPainter's paint method would update the selection instead of having to repaint absolutely everything.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Certain modification will be needed because when a region gets marked as dirty, it gets cleared and has to be completely repainted.  The concept should still work though.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Design Patterns:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;*Facade Pattern:  The Facade Pattern can be used to create a single unified interface to a batch of classes that the client wishes to use. &lt;/div&gt;&lt;div&gt;This is useful when there are two separate groups of classes which need to interact, but you want to avoid having a web of dependancies.  Instead of trying to mix and match the classes of the two groups, you can instead create a Facade which can sum up one of the two batches in a single easy to use interface. &lt;/div&gt;&lt;div&gt;This is done by creating a Facade class which know about all the classes of one of the two groups.  Next, several methods are added to the Facade which, using all of the classes of the one group, sum up the functionality of the full subsystem.  The second group can then call these methods on the Facade and use the full functionality of the subsystem, without ever having to know about any of the subsystem's classes.&lt;/div&gt;&lt;div&gt;An example of this would be if I had a textbox that needed to be constantly repainted for various reasons and there were a flurry of painter classes which could achieve this functionality.  If I didn't want the textbox to have to decide which of the many painters I wanted it to use, but instead wanted the textbox to just call a few paint methods from one class, I could use a Facade.  I would create a PainterFacade, that used all of the painter classes to create a few simple paint methods, or even just one paint method, for the text box.  This paint method would then look at the current text box state, and decide which of the painters was needed, and what it had to do.  &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;State/Objects for States Pattern:  The State Pattern can be used to give a class a variety of different behaviors using the same methods, dependent on the state.  &lt;/div&gt;&lt;div&gt;This can be useful if you have a situation in which you want all the operations for a task to occur in one class, but the operations depend on the state of an external source.  If for example you have a robotic dog that can take it self outside for a walk for a... oil change I suppose.  This robotic dog has some commands that say 'go outside', 'change oil', and 'come inside'.  These commands depend on the weather or the planet the robodog is on.  Thus in order to retain the same commands for different states, the robodog must implement the State Pattern, so that when it tries to moon walk it doesn't bring an umbrella instead of the Billy boots.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;To implement this, you must create some class for the Context, an interface or abstract class for the State, along with the need state subclasses, and have the Context hold a reference to the State.  Each of the State subclasses will implement the same set of methods in different ways, for the Context to use.  The Context can then call the same method on its State reference, and depending on which state it holds at a given time, it will get different results.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Say our robodog has the some State class with the 'go outside' method implemented differently for sunny days and rainy days.  It also has some Context class which holds a daily routine for the robodog.  The Context says that at 2 pm each day, robodog must 'go outside'.  The Context holds it State reference, and the state changes automatically based on the weather.  This way, come 2 pm when the Context tells robodog to 'go outside' by calling the appropriate method on the State reference, robodog will know to bring an umbrella for a rainy state and sunglasses for a sunny state.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3714840552149734001-5739141140975394540?l=8thlightapprenticeship.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://8thlightapprenticeship.blogspot.com/feeds/5739141140975394540/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/01/day-10.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/5739141140975394540'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/5739141140975394540'/><link rel='alternate' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/01/day-10.html' title='Day 10'/><author><name>Justin</name><uri>http://www.blogger.com/profile/04054497811526894325</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://3.bp.blogspot.com/_snSMUhgzWLE/S0KeHj1cwNI/AAAAAAAAAAQ/f9gAgDyjN2A/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3714840552149734001.post-2063599909778605063</id><published>2010-01-16T11:18:00.000-08:00</published><updated>2010-01-18T10:19:15.154-08:00</updated><title type='text'>Day 9</title><content type='html'>I spent Friday finishing up the text box which is now nearly in its final state.  Just before lunched I paired with Mike, a visitor to 8th Light, and gave him a general intro to Test Driven Development and Pair Programming.  At lunch I presented my two new testing patterns to the 8th Light guys, and got some general feedback.  For the rest of the day, I wrote the Mouse Processor, completed some linkage between the TextModel and both Key and Mouse processor.  All that remains to be done is optimize the repainting of the TextPanel at appropriate times.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Design Patterns:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;*Command Pattern:  The Command Pattern can be used to capture and store a request as an object, and then calling some abstract command, thus allowing you to populate clients with different and log-able operations.  &lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;To do this, a Command interface is created with an abstract execute() method and several concrete subclasses which are designed to define their own execute().  Whenever a request is made, it will call execute() on its instance of the Command interface.  The instances of the subclasses will know who their respective receivers are, and what steps must be taken to complete their action.&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt; This could be used to create a flexible barrier between some UI and application.  A user could initialize some request by pressing a button or clicking some start key, thereby calling the application to action.  Since the UI doesn't know who the request belongs to, or who the receiver of action will be, it would use its instance of a Command (given to it upon initialization) and call execute() which will generate the appropriate response.  &lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;So when, for example, a start button is created, it is given a Command object from the application.  This command object will be some concrete class named StartCommand, which is a subclass of a Command interface.   When the start button is clicked, it calls execute() on its Command object (of which the type is unknown to the button) which gets routed to the StartCommand.  The StartCommand is then able to follow through with the necessary actions to 'start', calling the appropriate methods on its receiver. &lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt; Using this strategy, all UI interactions can be separated from the application, and all dependancies will flow at the Command Interface.  It also means that all commands can be logged, and thus many of them could even be reversed.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;This is actually quite similar to the structure I set up for my KeyProcessor.  The TextInputPanel gets some keyPressed event which then uses some algorithm to select the appropriate processor.  The TextInputPanel then calls processKey() on the selected processor, which proceeds to make the needed changes on its receiver the TextModel.  The main difference is that for the Command Pattern I might have a KeyProcessor for each key which calls processKey() on its own KeyProcessor rather than having a Dispatcher in the keyPressed() method that decides who gets the command.  The basic idea is quite similar though.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;*Adapter Pattern:  The Adapter Pattern allows two unrelated or unconnected interfaces to be connected so that they may be used in conjunction.  This is done in one of two ways; either using a Class adapter or an Object adapter.  The class adapter will inherit from one of the interfaces, and implement the other, linking the methods of the inherited interface to the methods of the implemented class.  The object adapter will inherit from one interface and through some means get an instance of the other, and then connect the method calls from the parent by making calls on the instance.  The exact manner in which this occurs is a tid-bit illusive to me and I think depends largely on circumstance.&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;Though a stretch, one example of this could be that my TextInputPanel, through the TextModel, is an adapter for the TextLayout class.  A limelight app would be the Target, the TextInputPanel would be the Adapter, and the TextLayout would be the Adaptee.   This would be the object adapter case.  Limelight wants a Panel that can have some text and is clickable, and there is this TextLayout class out there that already has many methods to assist with these features, but isn't a Panel.  Thus the TextInputPanel is used to adapt the TextLayout's functionality by inheriting from the Limelight Panel, and holding an instance of the TextLayout. &lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;Limelight gets some MouseClick event, which is handed off to the TextInputPanel.  The TextInputPanel then takes the request and (through some indirection) gets some TextHitInfo from the TextLayout, and therefore adapts the Layout to the Panel.&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;Let me know if there are any clarifications you can give as to the exact nature or best way to use the object adapter.  I am not entirely certain as to how you get an instance of the Adaptee if it is meant to be an interface.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Now to optimize the painting of my panel.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3714840552149734001-2063599909778605063?l=8thlightapprenticeship.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://8thlightapprenticeship.blogspot.com/feeds/2063599909778605063/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/01/day-9.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/2063599909778605063'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/2063599909778605063'/><link rel='alternate' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/01/day-9.html' title='Day 9'/><author><name>Justin</name><uri>http://www.blogger.com/profile/04054497811526894325</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://3.bp.blogspot.com/_snSMUhgzWLE/S0KeHj1cwNI/AAAAAAAAAAQ/f9gAgDyjN2A/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3714840552149734001.post-7232183967360150898</id><published>2010-01-14T17:31:00.000-08:00</published><updated>2010-01-14T19:20:20.060-08:00</updated><title type='text'>Day 8</title><content type='html'>I am pleased to say I have two new design patterns to blog about today, but these are of a slightly different nature.  But first, a quick review of the day.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I spent about half the day today in an iteration meeting, observing and learning about one of 8th Light's productions.  Trying to figure out what is specifically going on in a project, with minimal detail, but just a broad outline could develop into a very valuable skill.  It is something I frequently see Uncle Bob do.  It seems like he doesn't have to read the code to know what is going on, he just sees the shape of the code and immediately can tell the codes intention, and then even a better shape or form it can take to accomplish the same end.  &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The rest of the day I spent trying to refactor my tests for the KeyProcessor.  It was especially challenging because I had never tested a framework like the Dispatcher I used, and so was struggling with the organization.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;But now, the two new design patterns.  &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Design Patterns:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;One of the reasons these two patterns are rather different is because they are actually for tests rather than production code.  Another reason they are a little different is because I just made both of them!  I came across them both in rapid succession, so the second pattern is actually an extension of the first pattern, but can also be used independently.  Using a bit of insight from both Micah and Uncle Bob (as well as a nice feature in JUnit) I was able to find a testing strategy that perfectly fit my problem.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The Test Nest Pattern:&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;-Intent:  To create a test file containing several tightly related test classes.&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;-Motivation:  Consider designing tests to describe a case where there is some base abstract class and several small derivative classes that implement one or just a few methods of the base class.  This could occur from using the Command Pattern, a Dispatcher/Jump Table, or other similar designs.  &lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;Having a file for each of the derived classes would not only seem overkill, since they are small and similar, but it would also make it more difficult to unveil the intent of the code using the tests.  Instead, it makes more sense to have all the tests for these derivatives in one file, maybe named after the base class.  The issue is that organizing the tests to be in accordance with their specific derivative becomes difficult.  &lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;One solution could be making a prefix title for each test, to first indicate which class it is for, and then describe the purpose of the test after the prefix.  However this solution would lead to both long and complicated names as well as a test file that is difficult to parse through.&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;Another solution is the Test Nest Pattern.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;-Structure:  Using JUnit's SuiteClass technology it is possible to create a Suite Class, and several internal Test Classes.  &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;Say you are trying to process all of the KeyEvents to use for some application.  To do this, you create an abstract KeyProcessor class. This class is used as a dispatcher, and in conjunction with an indexing algorithm, it properly selects a derivative class to handle the KeyEvent.  Each derivative implements a processKey() function, which is the derivatives only method.  Say there is a CmdKeyProcessor and a ShiftKeyProcessor derivative that you are looking to test in the same file.&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;So you name this file the KeyProcessorSuite and you create two static internal classes named CmdKeyProcessorTest and ShiftKeyProcessor test. Next, you pull out all of the common fields and statically define them at the suite level.  You could also statically define a standardSetUp() method that shares common setup steps that both test classes use.   You then must add two lines above the suite telling JUnit that this a suite file, and which classes belong to the suite.  It looks something like this:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;@RunWith(Suite.class)&lt;/div&gt;&lt;div&gt;@Suite.SuiteClasses({KeyProcessorSuite.CmdKeyProcessorTest.class, KeyProcessorSuite.ShiftKeyProcessorTest.class})&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;public class KeyProcessorSuite{&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;public static KeyProcessor processor;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;public static void standardSetUp(){...}&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;public static class CmdKeyProcessorTest{&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;  &lt;/span&gt;@Before &lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;  &lt;/span&gt;public void setUp() {&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;   &lt;/span&gt;standardSetUp();&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;   &lt;/span&gt;processor = new CmdKeyProcessor();&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;  &lt;/span&gt;}&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;  &lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;  &lt;/span&gt;@Test&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;  &lt;/span&gt;public void canProcessCharacters(){&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;   &lt;/span&gt;...&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;  &lt;/span&gt;}&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;}&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;public static class ShiftKeyProcessorTest{&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space: pre; "&gt;  &lt;/span&gt;@Before &lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space: pre; "&gt;  &lt;/span&gt;public void setUp() {&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space: pre; "&gt;   &lt;/span&gt;standardSetUp();&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space: pre; "&gt;   &lt;/span&gt;processor = new ShiftKeyProcessor();&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space: pre; "&gt;  &lt;/span&gt;}&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space: pre; "&gt;  &lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space: pre; "&gt;  &lt;/span&gt;@Test&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space: pre; "&gt;  &lt;/span&gt;public void canProcessCharacters(){&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space: pre; "&gt;   &lt;/span&gt;...&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space: pre; "&gt;  &lt;/span&gt;}&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space: pre; "&gt; &lt;/span&gt;}&lt;/div&gt;&lt;div&gt;}&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;And voila!  Each derivative class of KeyProcessor can get its own Nest for all its Tests in the KeyProcessorSuite.  It provides a simple and intuitive organization for all the tests, and fits it all into a single file.&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The Asserter Pattern:&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;-Intent: To provide a compact set of descriptive and reusable assertions.&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;-Motivation:  There is a general rule that each test should have only one assertion.  This could be a single assertEquals(int, int) or it could be a batch of closely related assertions checking the result of a single action.  As test after test is written using a batch of similar assertions, even with different check values, there is still a lot of duplicated code.  This should be avoided if possible.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;One solution to this would be to extract methods that contain batches of reoccurring assertions and that take the check values for arguments.  This is a practical solution if all the tests are in a single class, or if there is no underlining theme amongst the extracted assertion methods; however, if you are using a Test Nest Pattern and have several test classes, or if there is a theme in the extracted assertion methods, then this solution wont fit.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;This is where you would use the Asserter Pattern.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;-Structure: Using a separate or internal class,  it is possible to create a class meant specifically to contain all of the assertion methods.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;Say you have a TextBoxModel class, which contains all of the information of some abstraction.  Say there are a set of actions you preform on the this data, after which you must check a similar set of fields.  For example, you might have a set of three fields - int cursorIndex, int selectionIndex, boolean selectionOn - that define a selection, or a range of selected text.  Then whenever an arrow key is pressed (perhaps when shift is being held down) you will want to check the values of these three fields.   There is also another set of two fields - int cursorIndex, String text - that define the current text state. Whenever a character key or backspace is pressed, you want to check these two values.&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;You would then create a class (internal or external and static if it is inside a Test Nest Pattern), perhaps named TextModelAsserter, which would contain two assertion methods named - assertSelection, and assertTextState - that contain their respective assertions.  It might look something like this:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;public static class TextModelAsserter&lt;/div&gt;&lt;div&gt;  {&lt;/div&gt;&lt;div&gt;    TextModel boxInfo;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;    public TextModelAsserter(TextModel boxInfo)&lt;/div&gt;&lt;div&gt;    {&lt;/div&gt;&lt;div&gt;      this.boxInfo = boxInfo;&lt;/div&gt;&lt;div&gt;    }&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;    public void assertSelection(int cursorIndex, int selectionIndex, boolean selectionOn)&lt;/div&gt;&lt;div&gt;    {&lt;/div&gt;&lt;div&gt;      assertEquals(boxInfo.cursorIndex, cursorIndex);&lt;/div&gt;&lt;div&gt;      assertEquals(boxInfo.selectionIndex, selectionIndex);&lt;/div&gt;&lt;div&gt;      assertEquals(boxInfo.selectionOn, selectionOn);&lt;/div&gt;&lt;div&gt;    }&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;    public void assertTextState(int cursorIndex, String text)&lt;/div&gt;&lt;div&gt;    {&lt;/div&gt;&lt;div&gt;      assertEquals(cursorIndex, boxInfo.cursorIndex);&lt;/div&gt;&lt;div&gt;      assertEquals(text, boxInfo.text.toString());&lt;/div&gt;&lt;div&gt;    }&lt;/div&gt;&lt;div&gt;  }&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;Next, you create a field of this class - TextModelAsserter asserter - in your test class, and then an instance of it, passing it the appropriate parameters, in a setup method.  Using this instance, you can easily make precise and compact assertions, which not only speed up how quickly you can write solid tests, but also gives them a clean and regular look.  You could use it something like this:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;   @Test&lt;/div&gt;&lt;div&gt;    public void canProcessBackSpace()&lt;/div&gt;&lt;div&gt;    {&lt;/div&gt;&lt;div&gt;      processor.processKey(KeyEvent.VK_BACK_SPACE);&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;      asserter.assertTextState(0, "ere are four words");&lt;/div&gt;&lt;div&gt;    }&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;    @Test&lt;/div&gt;&lt;div&gt;    public void canProcessRightArrow()&lt;/div&gt;&lt;div&gt;    {&lt;/div&gt;&lt;div&gt;      processor.processKey(KeyEvent.VK_RIGHT);&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;      asserter.assertSelection(2, 4, false);&lt;/div&gt;&lt;div&gt;    }&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;And now you have a quick and easy way to make single lined, well organized, themed assertions throughout a single test class or across several test classes or Nests.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Tomorrow I get to finish writing up my KeyProcessor tests and code using there two new patterns I discovered!  &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3714840552149734001-7232183967360150898?l=8thlightapprenticeship.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://8thlightapprenticeship.blogspot.com/feeds/7232183967360150898/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/01/day-8.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/7232183967360150898'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/7232183967360150898'/><link rel='alternate' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/01/day-8.html' title='Day 8'/><author><name>Justin</name><uri>http://www.blogger.com/profile/04054497811526894325</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://3.bp.blogspot.com/_snSMUhgzWLE/S0KeHj1cwNI/AAAAAAAAAAQ/f9gAgDyjN2A/S220/me.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3714840552149734001.post-3107095537518564341</id><published>2010-01-13T17:33:00.000-08:00</published><updated>2010-01-13T18:57:02.259-08:00</updated><title type='text'>Day 7</title><content type='html'>Lots of coding today.  I spent the majority of the day coding away and implementing my KeyProcessor Dispatcher strategy.  It felt good to be using TDD and switching around from class to class, all the while knowing everything still worked.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Now to try something a little different.   There are still things I would like to include everyday, like notions of what it means to be a Craftsman, but I think I am going to get into the habit of adding at least two design patterns to my repertoire each day.  Right now, I would like to focus on my architectural skills, and then latter on I will focus more on languages.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Notions of What It means to be a Craftsman:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;* Having the Test Right Feeling:  Previously, when I was spiking and trying to figure out how the text box would work, I always felt like I was hacking together some albatross of a program, and just hoped things would work.  It still felt great when I got to see things work they way I thought, but more often then not... I ended up having to make several attempts to get it right, and was never completely sure something would work.  &lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;I would describe the Test Right Feeling as a sense of satisfaction from knowing that almost everything you type out is going to work just how you want it to.  Its a confidence in your coding solution, because you explicit wrote out the problem.  Most of the time you don't even feel the need to click the test button since you are so certain it will work, but you do it anyway because green makes you happy.  &lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;A Craftsman should be at home with the Test Right Feeling.  It should be ingrained into him, and terribly important to him.  Although, he can of course leave his comfort zone if need be, he always knows he has his home if he needs it.   &lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;In a way its like the difference between a carefree and reckless swordsman, hacking away at his foes in the middle of the battle field vs. the well disciplined Roman warrior who stays in formation and guards his brothers in arms.  The swordsman might run out and rapidly chop up the enemy, but he is more likely to die quickly and leave his brethren hanging.  The disciplined Roman will fight side by side, guarding the man on either side; and though he may not kill as quickly, he will certainly grind his enemy into nothing, while still staying alive and protecting his allies.   &lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;The Roman has safety in his shield, formation, and brethren.  These are his tests.  They give him the confidence in every step forward he makes.  If he has he shield up, and his feet in synch with the ranks, he knows he will end victorious.  And though it can be fun to hack away at your foes, recklessly but quickly getting the job done,  in the long run you wont be able to match the frag count of the man who carefully and guardedly gets the job done.  &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;* Put your Tests to the Test:  Getting back into the groove of testing today, I began rapidly coding away: test, red, green ... test, red, green... test, red, green.   In the process, I was constantly refactoring and keeping my production code neat, extracting methods with meaningful names, and removing any duplication.  All the while, I neglected my tests.  I wrote them, then made them pass, and then moved on to a new test.  I forgot that it is not only important to keep your production code clean, but equally important to keep your tests clean.  Since your tests are a form of documentation to your code,  they better be just as easy to read, if not easier.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Design Patterns:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Bridge Pattern:  The Bridge pattern is useful when you have some object, say a Text Panel, and you want to have multiple implementations of this Text Panel.  You want to have a TextBoxPanel and a TextAreaPanel.  So first you try out making an abstract TextPanel, and then having two implementations of it.  Then you realize that you want each TextPanel to have the option of either Plain Text or Rich Text.  So you then try implement another TextPanel that you call the RichTextPanel, and you implement another version of the TextBoxPanel and TextAreaPanel for the RichTextPanel.  Already you notice this getting rather nasty.&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;The Bridge Pattern is a way to separate the Abstraction (TextPanel) from the Implementation (TextModel (either Plain Text or Rich Text)) making them both easily extendable and independent.  &lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;To do this, you create two separate abstract classes, TextPanel and TextModel, where the Abstraction will interact with the client and the Implementation will manipulate and handle the data or implementation.  Next, you add some concrete derivative to each of these abstract classes to fulfill your intentions.  You create a dual hierarchy where each piece on one side of the hierarchy is compatible with those on the other side.  Thus you could have a TextBoxPanel with a RichTextModel or PlainTextModel, and likewise with the TextAreaPanel.  &lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;The Bridge comes through the connection between the Abstraction and Implementation.  Typically the derivatives of the Abstraction call a method of the Abstraction, which then transfers the method call to the Implementation, which hands it down to an Implementation derivative; however, the system can work in either direction.&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;I used it in just this way except I would have, for example, the PlainTextModel calls a markAsDirty() method on the TextModel, which hands this off to the TextPanel, and then to a TextBoxPanel to indicate that this particular TextBoxPanel needs to be repainted.  &lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;The value of this is of course that it allows for easy expansion, but also that it hides the details of the TextPanel, in the TextModel, from the client.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Flip-Flop Pattern:  Not an official design pattern, but still a useful one according to Uncle Bob.  This pattern can be used when ever you have two concrete, or heavy abstract, classes that are cyclically dependent.  In order to obey the Dependancy Inversion Principle, you don't want either of these classes depending on the other, let alone both.  In order to resolve this debacle, you can add an interface on top of each of the two classes, each of which holds a reference to the methods used by the other class.  Then you just draw crisscrossing dependancies to the corresponding interfaces and voila.  Naturally this is why its called a flip-flop... since you flip, and then flop the dependancies. Yes.  Like pancakes. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Tidbits:&lt;/div&gt;&lt;div&gt;Using typed arraylists:  ArrayList &lt; &amp;amp;type &gt; &lt;type&amp;amp;&gt;&lt;type&gt;list = new ArrayList &lt; &amp;amp;type &gt; &lt;type&amp;amp;&gt;&lt;type&gt;(size)&lt;/type&gt;&lt;/type&amp;amp;&gt;&lt;/type&gt;&lt;/type&amp;amp;&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Interfaces can only have abstract methods, no fields or data&lt;/div&gt;&lt;div&gt;Classes implement, not extend interfaces&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Also, keep in mind the  Abstraction vs. Instability graph, and the Main Sequence.  Plot how abstract a class is vs. how unstable (the more classes that depend on it, the more stable it is -&gt; the fewer the more unstable).  The Main Sequence is where classes should be and is drawn something like this:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;A  |.\&lt;/div&gt;&lt;div&gt;B  |...\&lt;/div&gt;&lt;div&gt;S  |......\&lt;/div&gt;&lt;div&gt;T  |........\  Main Sequence&lt;/div&gt;&lt;div&gt;R  |..........\&lt;/div&gt;&lt;div&gt;A  |............\&lt;/div&gt;&lt;div&gt;C  |...............\&lt;/div&gt;&lt;div&gt;T  |___________\_&lt;/div&gt;&lt;div&gt;.......UNSTABLE&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3714840552149734001-3107095537518564341?l=8thlightapprenticeship.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://8thlightapprenticeship.blogspot.com/feeds/3107095537518564341/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/01/day-7.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/3107095537518564341'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/3107095537518564341'/><link rel='alternate' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/01/day-7.html' title='Day 7'/><author><name>Justin</name><uri>http://www.blogger.com/profile/04054497811526894325</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://3.bp.blogspot.com/_snSMUhgzWLE/S0KeHj1cwNI/AAAAAAAAAAQ/f9gAgDyjN2A/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3714840552149734001.post-6368572059964032823</id><published>2010-01-13T07:15:00.000-08:00</published><updated>2010-01-13T08:40:18.068-08:00</updated><title type='text'>Day 6</title><content type='html'>Yesterday was an enormously busy day, and I didn't have time to finish my blog.  &lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Micah and I took a look at my design to see where improvements could be made.  I'm happy to say, we found several areas in which it could be improved, and some areas where things already seemed like they could work.  The first thing we did was compare my design against S.O.L.I.D. which I will go over a little more later.  Then we played around with a few strategies until we found one that seemed to fit best.   The rest of the day I spent re-factoring my code, rewriting code using TDD, and trying to implement my new design.  &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;What I learned:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Underlining Principles of being a Software Craftsman:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;* Using a standard to test your design:  One standard I typically used is SOLID, for Object Oriented Design.  The acronym S.O.L.I.D. was coined by Uncle Bob at Object Mentor. It stands for:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;S&lt;/b&gt;ingle Responsibility Principle:  A class should hold one concept, with one reason to change&lt;/div&gt;&lt;div&gt;&lt;b&gt;O&lt;/b&gt;pen/Closed Principle: A class should be Open for extension, Closed for modification&lt;/div&gt;&lt;div&gt;&lt;b&gt;L&lt;/b&gt;iskov Subsitution Principle: A child class must be able to substitute its parent class&lt;/div&gt;&lt;div&gt;&lt;b&gt;I&lt;/b&gt;nterface Segregation Principle: No client should be forced to depend on methods it doesn't use&lt;/div&gt;&lt;div&gt;&lt;b&gt;D&lt;/b&gt;ependancy Inversion Principle: Always try to avoid dependancies on concrete classes&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;These design standards (not all of which apply for all languages, like ISP in Ruby) can lead you closer to a robust and flexible design.  Or at least, they will help you stay away from rigid and fragile designs.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;* Personal Code Review:  It is overwhelmingly helpful if you look over your code a few days after you wrote it.  When your purpose behind doing some little trick, or some conditional is no longer quite so clear, you are able to see some weaknesses in your code.  &lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;Its rather like when writing a paper, and then going over it right after you write it with the intention of making sure everything you said makes sense.  This is typically ineffective because your intentions, with the words you used, are still clear to you, but if you give your paper to someone else, they can point out where your words might not match your interpretation or intent.  &lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;Writing code is very similar, even though your code may function as you intended, it might not read as easily as you thought it would.  Or at lease, it is likely that you can do a little more refactoring to make your intentions pop out of the code so obviously that it only take one look to understand what you are getting at.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;* If you can write a mock yourself, write the mock yourself:  This one stems right from Micah, who believes that adding complex mocking frameworks, adds needless complexity.  Instead, if you ever need a mock object, write it yourself.  &lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;This has several advantages, the most prominent of which is that once you have written a good MockClass, you can use it anytime, anywhere.  For example, yesterday I was trying to mock out a FocusEvent in Java, and I needed to pass a Component derivative for the constructor.  Well it turns out, Micah has already written convenient mocks that I could use.  Other advantages are that, you always know what your mocks can and can't do, and that you can keep it as simple and lightweight as possible.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;General Knowledge of Language:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;* Parallel inheritance structures can be dangerous:  They might start out pretty, and you can add some nice abstract classes or interfaces to help segregate them, but eventually decay is inevitable... That is, assuming they continue to grow.  There will be a point where if you want to make an addition to one side of the structure, that addition must be able to handle all the cases of the other side.  This isn't too bad with just two or three derived classes,  but thou shalt not make four.  Five is right out.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;* Just a note on abstract classes.  A class is abstract if it has at least one abstract method.  Though, you can declare a class as abstract even without an abstract method, thats just a phony. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Design Patterns:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;* Strategy Pattern (aka Policy Pattern):  The Strategy Pattern is way to use a variety of different algorithms for a single context at run time.  Say you wanted to make a simple calculator that could add, subtract, and multiply.  You could use the Strategy Pattern, with the calculator interaction with your user as the context, and the three operations as your strategies.&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;In Java, you would create a Calculator class, which had a means to interact with the user, and which would contain a reference to a Strategy Interface.  The Strategy Interface would have an calculate method, and three derived classes which would implement this method.  Then in the context, or the Calculator class, you would pass any of the operation strategies as an argument of the Calculator constructor, and then call calculate on the strategy reference to use the desired operation.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Now to finish implementing my KeyProcessor using the dispatcher!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3714840552149734001-6368572059964032823?l=8thlightapprenticeship.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://8thlightapprenticeship.blogspot.com/feeds/6368572059964032823/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/01/day-6.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/6368572059964032823'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/6368572059964032823'/><link rel='alternate' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/01/day-6.html' title='Day 6'/><author><name>Justin</name><uri>http://www.blogger.com/profile/04054497811526894325</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://3.bp.blogspot.com/_snSMUhgzWLE/S0KeHj1cwNI/AAAAAAAAAAQ/f9gAgDyjN2A/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3714840552149734001.post-6509612352968451495</id><published>2010-01-11T17:12:00.000-08:00</published><updated>2010-01-13T08:23:20.755-08:00</updated><title type='text'>Day 5</title><content type='html'>Today I finished designing my TextBox.  At first I tried using a Chain of Responsibilities design pattern to help sort through all the possible key press and mouse click events, but then I switch to using a Dispatcher because of some insight from my father.  I will explain these more later.  After finishing my design, since Micah was no with me in the office today, I began coding my new design.  When Micah and I review the design, there are likely to be some changes, possibly so much so that everything I coded today will go to waste.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;What I learned today:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Underlining Principles of being a Software Craftsman:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;*Experimenting with multiple Design Patterns:  I am sure once a Craftsman reaches a certain point, they can simple pick up on the code scent and rapidly unveil the most logical Design Patter; however, before that point is reached, trying multiple patterns to a given problem might prove not only to create a better solution, but also to be a valuable learning experience.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;General Knowledge of Language:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;* Data classes, or classes composed of very little functional code and nearly all variables,  can be dangerous.  They typically will lead to procedural code, which is undesirable in Object Oriented software.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;* It is usually better to avoid inheritance.  If there is a way around it, even if you have to share instances of a class, you should use the lesser of two evils.  &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;* Cyclic dependancies are typically a bad sign, however it is acceptable if two classes are logically dependent.  In other cases you should stick an interface in between.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Design Patterns:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;* Dispatcher / Jump Table:  Though not really a design pattern so much as a strategy, I used it as a pattern to mold my code around.  Typically a Dispatcher or Jump Table is an array of functions with indices as the result of some equation of operation.  A common example is how C++ uses Jump Tables to access methods in a class.  &lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;I used a Dispatcher as an array of objects rather than functions.  Each object was an instance of class designed to handle a different event.  It was used to eliminate a flurry of  if-else statements in order to determine which Key had been pressed, and if there were any modifiers (shift, command, alt being held down).   I created an array of 16 different objects, each was the derivative of a KeyProcessor interface, and each had a processKey(int keyCode) method.  Using 4 deciding factors, and scaling each, I created a simple algorithm to properly dispatch the KeyEvent to the proper handler.  &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;* Chain of Responsibility Pattern:  This patter works just as you might imagine from the name.  It begins with some request that needs to be handle.  This request is sent to some main processing object which checks to see if it can handle it, and if not, passes it along to the next processing object in the chain.  If the next processing object can't handle the request, it the passes it along, and so forth until the request finally reaches something that can handle it.  Typically there will be a well defined mechanism to pass requests along the chain, such that new processing objects can be easily added.  The Chain of Responsibility pattern can actually be quite similar to a dispatcher with a pyramid like structure of responsibility. &lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;I was going to use the Chain of Responsibility pattern just like a dispatcher, having high level links passing KeyEvents down to lower level links based off the same criteria I used to created my dispatcher algorithm.  The chain would have been more like a tree, and each level would have a binary decision of which direction to pass the event on.  In the end, this would have eliminated a large portion of the if-else chain, but would still contain several conditional statements.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Thats pretty much it for today.  I have faith that tomorrow my design will withstand the scrutiny of Micah!  Of course, it wouldn't surprise me if he had one simple improvement, which somehow alluded me, and that drastically alters my design...&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3714840552149734001-6509612352968451495?l=8thlightapprenticeship.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://8thlightapprenticeship.blogspot.com/feeds/6509612352968451495/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/01/day-5.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/6509612352968451495'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/6509612352968451495'/><link rel='alternate' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/01/day-5.html' title='Day 5'/><author><name>Justin</name><uri>http://www.blogger.com/profile/04054497811526894325</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://3.bp.blogspot.com/_snSMUhgzWLE/S0KeHj1cwNI/AAAAAAAAAAQ/f9gAgDyjN2A/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3714840552149734001.post-3183812035229721219</id><published>2010-01-07T20:15:00.000-08:00</published><updated>2010-01-07T20:54:11.333-08:00</updated><title type='text'>Day 4</title><content type='html'>Unfortunately much of today was spent doing things other than writing code, but I still was able to gather some useful information.  I attended another iteration meeting with a different client today, and naturally it was a bit different.  I also began designing through uml documentation, my text box's final form.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;What I learned today:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Underlining Principles of being a Software Craftsman:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;*Estimating tasks and using the point system - Accurately assessing how long any task will take, how difficult it will be, and thus how many points it should be worth, is never easy.  The points might initially be based off of man ours, but quickly a point becomes a point based on how many points you judged another similar task would take.  This means the point system is usually indefinite.  Especially when you just begin talking about a feature or task, write it on a note card, and are suddenly trying to guess the full extent of its complexity.  Of course any developer will get better and better at this over time, but still can be surprised that a task took three times as long as he/she thought.  &lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;One strategy that I saw today to counteract this issue is having a group of developers all vote at once on a feature.  They would hold out there hands and on three stick out fingers according to how many points they thought the task was worth, as if they were playing a game of rock paper scissors.  This can increase the accuracy of the estimation, when you average all of the guesses together, but it still isn't perfect.  &lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;The challenge in estimating points leads to the challenge in calculating a team's average velocity (where velocity is how many points they finish in an iteration).  A team's velocity might be 18 one iteration, and just a few weeks later it might suddenly be half that.  This makes me think that there has to be a better and more accurate way of judging the speed of any group of developers, but I haven't thought of one yet...&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;*Taking a step back and looking at the big picture - After Spiking out my text box for a few days, I got a pretty good understanding of how each and every piece should work.  I was constantly fiddling, moving things around, trying out new ideas, and experimenting with different strategies.  I was pretty confident that I understood how to make a text box.  &lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;Then Micah asked me to design the text box, how I would write it in my final version, in its entirety.  He told me to write it down on paper using the UML design structure.  So after I did a little research, I got a pen and paper and started drawing boxes and connecting lines together.  The more I drew the worse everything got.  It wasn't long before I realized a pen... just wasn't going to work out.  Micah of course already knew this, and by the time I went over to him he was holding a pencil and big eraser for me to use.  &lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;I tried again, and this time I had an even better idea of how I wanted my system to work.  As I began to tie my classes together started holding more and more of my task in my brain at once.  Then there was a single moment when an awesome wave rushed through me and I realized I had moved out several levels of abstraction and was now holding my entire project in my brain in full detail.  It was at this point that I began noticing many patterns, and a repetitive nature I had not seen when I was first hacking away at my code.  &lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;This was my Rubik's Cube moment.  When I saw strategies I could use to solve my problem as a whole rather than side by side.  I felt like an architect who had just made a model of my building, tore it down, and began making sketches.&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;I think this is another thing that defines a Craftsman.  A Craftsman will have the ability to see the big picture, and draw lines between what seemed to be unconnected places.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;General Knowledge of Language:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Unfortunately I didn't do a whole lot of coding today so I didn't learn any general rules of languages.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Specific Knowledge:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt; *Macs and PCs use the ctrl and command buttons quite differently.  On a Mac you can use Cmd to jump to opposing ends of text (in a text box) and use Alt to jump to the end of a word.  A PC however uses Ctrl to jump to the end of words, and for Java Swing text boxes at least, Alt doesn't let you do a arrow jumping...  I know this is world shaking, but it is interesting none the less.  Also, Ctrl C is actually an ASCII character.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Thats all for today.  Lots of driving through thick snow, and sitting in on iteration meetings.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3714840552149734001-3183812035229721219?l=8thlightapprenticeship.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://8thlightapprenticeship.blogspot.com/feeds/3183812035229721219/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/01/day-4.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/3183812035229721219'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/3183812035229721219'/><link rel='alternate' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/01/day-4.html' title='Day 4'/><author><name>Justin</name><uri>http://www.blogger.com/profile/04054497811526894325</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://3.bp.blogspot.com/_snSMUhgzWLE/S0KeHj1cwNI/AAAAAAAAAAQ/f9gAgDyjN2A/S220/me.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3714840552149734001.post-6027947726899156281</id><published>2010-01-06T17:02:00.000-08:00</published><updated>2010-01-06T18:35:30.088-08:00</updated><title type='text'>Day 3</title><content type='html'>Once again today I worked on finishing up the text box, getting mouse selection, copy paste cut, select all, and other similar features.  I also sat in on an iteration meeting with one of 8thLight's clients.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;What I learned today:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Underlining Principles of being a Software Craftsman:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;* Customer Interaction - A Craftsman needs to always know that he can never know exactly what his customer wants.  Most of the time, not even the customer knows what he/she wants at the start of a project.  This is why it is important to have a constant feed back process and interaction between the Craftsman and the customer. When you consider any craft like wood work, designing a building, or painting a portrait, there is always in interaction between the crafter and his customer.  A carpenter asks the customer what they want, and perhaps shows some styles that the customer might like before making the table, or dresser, or anything of the like.  An architect will typically write up several drafts, present them, and the make changes according to the requests of the customer.  A painter painting a portrait has his customer directly in front of him/her.  All these crafts require Craftsman/Customer interaction.  &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;Software has to take this interaction even one step further.  Software isn't like a chair, that has one main purpose.  It isn't like a building, that once built, requires minimal to no interaction at all with the architect.  And it is quite different that painting a portrait, which has the complete specifications laid out in front of it and just needs some flavor.  No, software is a constantly changing, continuously dynamic, and relentlessly evolving entity that can't simply be spelled out at the start.  Software's interactive nature alone requires it to be nurtured to fruition.  All these crafts have another thing in common though... When the customer gets the end result, they know whether or not they like it.  &lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;This is another thing that separates a coder from a Craftsman.  A Craftsman must care about his/her craft and remain on a ceaseless quest to improve and satisfy.  It is because of this truth that a Craftsman must always be working with the customer.  If the customer isn't sure what they are looking for, then the Craftsman sure as h*ll better find out before spending weeks developing a product.  If the customer knows what they are looking for, but can't quite explain it completely or clearly, then the Craftsman needs to be interacting and presenting little demos to divulge what the customer is picturing.  However, this picture is always subject to change.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;Even after discovering what the customer is looking for, they might not want that two months later, and instead have a new picture or strategy in mind.  This is why the Agile Method teaches all programmers to use iterations.  Don't write the whole project all at once.  Write small bits at a time, and every one or two weeks (or sooner if it is reasonable) demonstrate the product and make sure you are still going in the write direction.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;General Knowledge of Language:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;* When using a language like Java, or C, with huge libraries already built in, be weary that anything you are writing might already exist in the library.  I wrote a few methods today, nothing huge but still took a decent chunk of time, that already existed in the Java libraries.  Though the preexisting methods weren't exactly what I needed, I at least could have used them as templates to save myself some time.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;* String buffers rule.  If ever you have a batch of text, constantly subject to change, use a StringBuffer instead of a regular String.  Anytime you add to a String you are actually creating a whole new string with the new text included into it.  With a StringBuffer you can just add stuff anywhere you want quite cheaply.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Specific Knowledge:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;More on making text boxes.&lt;/div&gt;&lt;div&gt; &lt;/div&gt;&lt;div&gt;* Making selection really useable. Once you have a batch of text selected, there is a lot you have to be able to do with it.&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;- Deselecting: There are actually hordes of ways to deselect text, such as: clicking but not dragging in the box, clicking and dragging on empty space inside the box, (depending on preferences) clicking outside the box, pressing an arrow key, pressing tab, and a few more too.  All of these need to be implemented before you can even begin to think you have a tolerable selection system.&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;- Deleting selected text:  Naturally you can do this by hitting the delete or BackSpace button, but you can also replace the text with another character.  This can be a little interesting when replacing the text with a capital letter (holding shift - the same key you use to select with arrow keys.  I checked to see if shift was pressed to see if I was in selection mode, so this popped up as a tiny bug), though not to difficult.  &lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;-Moving the cursor to opposite ends of the selection:  When you select some texts starting on the left and ending on the right and then you hit the left arrow (while everything is still selected) you need to pop the cursor back to where it started instead of one left of where it is now.&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;- Batch selecting:  Since there are a few keys you can hold to manipulate your scrolling (like holding command or alt and then an arrow key) you have to keep track of several manipulators at once.  &lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;  &lt;/span&gt;*In Java, all the extra keys like shift, alt, cntrl, and command are manipulators with their own codes.  When several of these are being held at once, the manipulators just add up to unique numbers.  They are all actually 1 bit in a binary string, so for example shift is bit 1 and when it is held and you call e.getManipulators (where e is a KeyEvent) it returns 1.  &lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;  &lt;/span&gt;Cntrl is bit 2, when getManipulators is called it returns 2.  &lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;  &lt;/span&gt;Cmd is bit 3, and returns 4.  &lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;  &lt;/span&gt;Alt is bit 4, and returns 8.  &lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;  &lt;/span&gt;When shift and cmd are both pressed, getManipulators will return 5.  So in order to tell if I still needed to be selecting text while multiple manipulators were being held, I just used the mod function to check to make sure the manipulators result was odd (thus shift is being held).  Then I could cmd shift select all text, or alt select some of the text.&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;  &lt;/span&gt;*To Alt select I also needed to search for the nearest space, to stop at the end of the word.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;-Finally, there was the Copy Paste Cut ordeal.  At first I tried out using a local string to be my personal clipboard.  This worked painlessly enough.  Just had to make sure the cursor ended up in the right spot, and the proper text was copied and unselected and such.&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;Then I had to put my fake clipboard into the real system clipboard.  Luckily Java has a nice Toolkit that gives this to you.  Toolkit.getDefaultToolkit().getSystemClipboard() -  The system clipboard uses something called a Transferable for it contents.  &lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;Putting text in was easy enough.  I used a StringSelection object (which is a Transferable) and then pushed that into the clipboard. &lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;Getting the text back out was only slightly more complicated since a Transferable can be text or pictures, or other unedigeties, thus I had to make sure it was holding text.  Did so with this:&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;&lt;/span&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;Transferable contents = systemClipboard.getContents(null);&lt;/div&gt;&lt;div&gt;    &lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;boolean hasText = (contents != null) &amp;amp;&amp;amp; &lt;span class="Apple-tab-span" style="white-space:pre"&gt;        &lt;/span&gt;contents.isDataFlavorSupported(DataFlavor.stringFlavor);&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;Then if hasText was true, I did a try catch to see if I could put the text into a String and voila!&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;* Mouse selection:  Fortunately there was some built in stuff to make mouse selection a little bit easier, but there was still a lot to think about to get it to work.  The TextLayout object I was using to hold the text for the text box had a method called hitTextChar( int x, int y) which returns a TextHitInfo.  You can then use the TextHitInfo to get the index of the character, see if you click the leading or trailing edge of the character, and all sorts of other useful tidbits.  &lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;Keeping track of the cursor, and selection indices could be a little tricky... especially around the edges, but not quite as hard as I had first imagined.  I ended up using most of the same code I used for scroll selecting, with a few tweaks.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Thats pretty much all.  There are probably some things I forgot to mention, and still a few things I have to do to make it completely smooth and wonderful. Then of course I have to rewrite most of it using TDD.  It wasn't nearly as simple as I had first imagined.  Such is always the case.  Murphy's Law never fails.  Things always take 3 times as long as you think.  Even if you realize this, and compensate, it will take 3 times as long as your new estimate.  Thats why I have decided to say everyone of my tasks and stories will take until the end of the universe to complete!  Doncha want me on your corporate team now? I'll only ever surprise you with my speediness.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3714840552149734001-6027947726899156281?l=8thlightapprenticeship.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://8thlightapprenticeship.blogspot.com/feeds/6027947726899156281/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/01/day-3.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/6027947726899156281'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/6027947726899156281'/><link rel='alternate' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/01/day-3.html' title='Day 3'/><author><name>Justin</name><uri>http://www.blogger.com/profile/04054497811526894325</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://3.bp.blogspot.com/_snSMUhgzWLE/S0KeHj1cwNI/AAAAAAAAAAQ/f9gAgDyjN2A/S220/me.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3714840552149734001.post-447265032582126975</id><published>2010-01-05T20:48:00.000-08:00</published><updated>2010-01-06T13:46:21.048-08:00</updated><title type='text'>Day 2</title><content type='html'>Today I spent most of my time working on making a text box.  It sounds menial, but surprisingly there is a lot to it.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Let me first try out my organization strategy again, and with it I will explain what I learned about the challenges of the dreaded text box.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;What I learned today:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Underlining Principles of being a Software Craftsman:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;* Spiking -  Although this is not directly an Agile method, it can be used as a strategy to practice being Agile.  Spiking is a technique a developer will apply when they really have no idea how to write their project or task.  Without knowledge of the organization, specific details, or even general gist of how he/she will write the code it is often exceedingly difficult to write any meaningful tests.  In the end, this could slow him/her down.  One way to get around this is to use spiking.  The developer will just start writing code and trying several strategies to figure out which ones are the best fit to the problem.  Whether it be just a few lines, or even a quick semi-functional program, Spiking can be used to gain a greater understanding of both the solution and the problem.  Once he/she has sufficient understanding of the problem, or at least a good place to start, he/she would delete the written code and start again from scratch with TDD.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;An analogy I thought of  that describes this strategy or pattern is how one goes about solving a Rubik's Cube.  If it is your first time ever solving a Rubik's Cube, you will likely try and do it one side at a time.  You will do a few spins, move some blocks around, get your first side and leap with glee with your success.  Then you will try getting another side, and in the process discover you have mess up the first side before you can get both.  You plow on through and you start throwing confetti as you get your second side.  Then comes the third side... and then the fourth...  and the fifth...  And finally when there is just the one side left, and you are terribly frustrated that it took you two years to get the fifth side, since you couldn't seem to keep the first and fourth ones together, you just throw down the cube. Every single turn you made messed up one or more sides.  You never finish the cube.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;This is the wrong way to solve a Rubik's Cube and the wrong way to write software.   A learned cuber will know that you don't necessarily solve it one side at a time, but instead use strategies that allow you to decouple all the sides leaving you the ability to get them all at once.  Though you wont get one side quite as fast (unless of course, as most learned cubers can, you can solve it uber fast), you will finish the whole cube much faster.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;This is similar to the difference between writing clean, well tested, organized, decoupled, and readable code vs. just hacking away to get things to work.  But to do this requires just a bit of foresight.  Though in some cases you can simply write tests and they will lead you to an excellent solution, it is also possible you will write a flurry of tests that have nothing to do with an end solution.  Just as it is important to know strategies to solve a Rubik's Cube, it is important to have some understanding of your software endeavor so that you may learn not to solve your problem one side at a time, and instead write effective tests that open the doors to solving the entire cube.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;General Knowledge of Language:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Nothing that stands out.  Lots of little tidbits about the Java libraries and mouse and key press events.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Specific Knowledge:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;* Writing a text box requires a lot of work...  &lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;- The cursor:  The cursor alone can be quite tricky to write.  When you consider that it is just a vertical line that you draw in between letters and not some magical object that just glides to its proper location, you can likely see it requires some thought.  &lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;  &lt;/span&gt;* First off, you need to make sure it doesn't get drawn on top of the letters.  This means you must have some way to know the exact size and spacing that every single character requires.&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;  &lt;/span&gt;* Then you must be certain it can scroll back and forth.  Thus, there has to be something keeping track of where the cursor is in relation to not only the text box, the text itself.  So it needs an X coordinate, as well as some character relation coordinate.  I used a index that keeps track of its index in the string, and I update it for any left-right scrolling, deleting, and adding of characters.&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;  &lt;/span&gt;* It has to be able to move with relation to spaces.  Though easy, it is something to think about.&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;  &lt;/span&gt;* It has to blink.  I used a separate thread that pops it on and off with a 500ms sleep&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;  &lt;/span&gt;* Finally, although there might be other things I am forgetting at the moment, it can't ever leave the text box.  Thus your indexer wont always match the require X coordinate.  I used an offset to make sure it never left the box when typing more than could in the box.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;- Scrolling:  Moving the visible letters side to side when there are more than can fit in the text box.  Equally challenging as making the cursor since there are several offsets to keep track of, or at least many ways in which the text offset can change.&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;- Highlighting &amp;amp; Selecting with the arrows:  Highlighting isn't too bad once you have a solid cursor.  All you need to do is fill a rectangle from where the cursor was to where it is, and then draw the letters on top of that.  Its selecting the letters that is more of the challenge.  You need some way of grabbing the highlighted text, even though the highlight is just a rectangle.  This can be done if you are keeping track of the relative index of the cursor to the characters, thus when you highlight you encapsulate both the X coordinates of the cursor, and characters of the text between the indices.  &lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;- Selecting with the mouse:  This I am yet to complete, but it isn't easy by the looks of it.  Since you no longer have any meaningful use of the cursor, you have to calculate which characters to select based solely on the X coors.  This gets even more challenging since you can also be clicking on letters of varying sizes rather than conveniently between them.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;There is a lot more to making text boxes than I had first imagined, and I haven't even dived fully into the issue, thus the scope of the problem is probably even lager than I imagine now.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;It is a good thing I have been Spiking, because had I tried to write this straight away, I would have made a huge mess, and spent even longer doing it.  Now at least when I write it for real, I will have some strategies to get it done right.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Other General coding goodies:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Nothing that comes to mind.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3714840552149734001-447265032582126975?l=8thlightapprenticeship.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://8thlightapprenticeship.blogspot.com/feeds/447265032582126975/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/01/day-2.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/447265032582126975'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/447265032582126975'/><link rel='alternate' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/01/day-2.html' title='Day 2'/><author><name>Justin</name><uri>http://www.blogger.com/profile/04054497811526894325</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://3.bp.blogspot.com/_snSMUhgzWLE/S0KeHj1cwNI/AAAAAAAAAAQ/f9gAgDyjN2A/S220/me.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3714840552149734001.post-5661635406183981921</id><published>2010-01-04T18:11:00.000-08:00</published><updated>2010-01-04T18:44:52.137-08:00</updated><title type='text'>Day 1</title><content type='html'>Today was my first day working as an Apprentice at 8thLight.  I will be working under Micah Martin for the next three months, soaking up all the knowledge I can.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I am not yet sure how I want to format my posts, so the next few shall be experimental.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;What I learned today:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Underlining Principles of being a Software Craftsman:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;* Communication - One of the fundamental and most crucial skills required by any software developer must be communication.  A software developer not only writes code that communicates to the computer his/her intentions, but also code that communicates to all other developers whom may read your code in hopes to build upon your work.  &lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;This essential duality will help to define how I will learn to become a Craftsman.  While I write any software, I must constantly keep three interpreters in mind.  The computer being first, because obviously if the computer can't use it, its not worth much.  Myself being second, since if I can't even understand my code, it really must be pretty crappy and I wont be able to work with it later.  Finally, and perhaps most importantly, I must write code that another developer can easily follow.  I think this last notion is what separates and developer from a Craftsman.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;General Knowledge of Language:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;* Though this is rather obvious to any experienced Java developer, and used to be quite obvious to me, I had a flutter in understanding today that I do not wish to have again.  In any class method there is always an implied    this.   before objects. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;* Java Threads - when creating a thread, the right way to make a quick and simple thread is to make it Runnable.  By doing so, and check me if I am wrong, you will have a default run() method that will be called when you call .start() on the thread object.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Specific Knowledge:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;* Java Swing uses a pyramid structure of panels to create any frame.  The main Frame is the base structure, and on it will be many panels.  Each panel can have several other panels inside of it, along with text boxes or buttons and things of the like.  &lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;When there is a mouse_click event, the event is first handed to the main Frame, which then checks the x,y coors of the click and scans all of the children panels to see which of them is at the clicked coor.  Then this panel scans all of its panels or other widget thingies until it finds the one at the clicked coor.  This goes on until there is either a panel with no children or the click is on a button widget or something of that nature.  The mouse_click event is then handled by that object in whatever manner it feels.&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt; &lt;/span&gt;Limelight props are also actually panels - called PropPanels, and have a similar structure.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Other General coding goodies:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;* I learned there is an enormous depth to making text box cursors.  Making it show up is easy enough, but it just goes down hill from there.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Extras:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;* Angelique taught me quite a bit about my taxes, Simple IRA, health care plans and so forth.  Fun fun.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;* Also a fair amount about domains and hosting.  Bought my first domain!  JustinMMartin.com  Still have to get something up there though.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;All in all, a successful day.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3714840552149734001-5661635406183981921?l=8thlightapprenticeship.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://8thlightapprenticeship.blogspot.com/feeds/5661635406183981921/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/01/day-1.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/5661635406183981921'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3714840552149734001/posts/default/5661635406183981921'/><link rel='alternate' type='text/html' href='http://8thlightapprenticeship.blogspot.com/2010/01/day-1.html' title='Day 1'/><author><name>Justin</name><uri>http://www.blogger.com/profile/04054497811526894325</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='28' src='http://3.bp.blogspot.com/_snSMUhgzWLE/S0KeHj1cwNI/AAAAAAAAAAQ/f9gAgDyjN2A/S220/me.jpg'/></author><thr:total>0</thr:total></entry></feed>
