<?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-8151007596010663103</id><updated>2011-08-14T19:49:00.451-07:00</updated><title type='text'>Ryan Brubaker</title><subtitle type='html'>My thoughts on developing software...</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://ryan-brubaker.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8151007596010663103/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://ryan-brubaker.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Ryan Brubaker</name><uri>http://www.blogger.com/profile/03141230570756777197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://farm1.static.flickr.com/68/219158810_71865d5a5e.jpg?v=0'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>34</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-8151007596010663103.post-6955306886362042679</id><published>2011-08-14T19:25:00.001-07:00</published><updated>2011-08-14T19:49:00.490-07:00</updated><title type='text'>Water Rocket</title><content type='html'>My son Max turned 4 yesterday. We had a rocket-themed birthday party for him so I found some instructions on the internet on how to make a &lt;a href="http://www.sciencetoymaker.org/waterRocket/buildWaterRocketLauncher.htm"&gt;water rocket&lt;/a&gt;. I'm not much of a handy man but this looked like an easy enough project. The results were somewhat disappointing for me, but luckily 4 year old boys are pretty easily impressed and it was a pretty big hit:&lt;br /&gt; &lt;a href="http://bit.ly/ncvQ5Y"&gt;Launch I&lt;/a&gt;&lt;br /&gt; &lt;a href="http://bit.ly/nF2S4x"&gt;Launch II&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;It looks like the seal at the mouth of the water bottle needed to be tighter and we were going a little overboard on the air pressure. The seal at the top was formed by heating up the PVC pipe with a candle until it became flexible, then pushing inward on both sides to create a bulge. The bulge I made was off to the side a little bit so I'm not surprised that caused a problem. I think if we could have figured out just the right amount of air pressure before it broke the seal we could have gotten a pretty decent launch. So I'm hoping to use it again in the near future to see if we can get better results. If we can't, it was easy enough to make that I'd like to try again, maybe when Max is a little older and can help build it.&lt;br /&gt;&lt;br /&gt;Overall it was a fun experience and educational. It definitely made me want to find other projects to work on.&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8151007596010663103-6955306886362042679?l=ryan-brubaker.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ryan-brubaker.blogspot.com/feeds/6955306886362042679/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8151007596010663103&amp;postID=6955306886362042679' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8151007596010663103/posts/default/6955306886362042679'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8151007596010663103/posts/default/6955306886362042679'/><link rel='alternate' type='text/html' href='http://ryan-brubaker.blogspot.com/2011/08/water-rocket.html' title='Water Rocket'/><author><name>Ryan Brubaker</name><uri>http://www.blogger.com/profile/03141230570756777197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://farm1.static.flickr.com/68/219158810_71865d5a5e.jpg?v=0'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8151007596010663103.post-8358695816056774791</id><published>2011-08-10T20:13:00.000-07:00</published><updated>2011-08-10T20:28:38.987-07:00</updated><title type='text'>30 Days to Success 1.1</title><content type='html'>On Monday, Apple approved the new version of my iPhone app, &lt;a href="http://itunes.apple.com/us/app/30-days-to-success/id441887436?mt=8"&gt;30 Days to Success&lt;/a&gt;. The new version doesn't contain anything too compelling:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Added functionality to restore application state at launch.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Updated application to only retrieve user Facebook info as necessary.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Added nicer view for Facebook Wall of Fame page.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Added functionality to share the application link with email contacts.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Added a friendly reminder to provide a review for the application.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Fixed some minor bugs.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;I added the reminder to review the application using &lt;a href=http://github.com/arashpayan/appirater/&gt;Appirater&lt;/a&gt; and integrated Facebook's &lt;a href=http://github.com/facebook/three20&gt;Three20&lt;/a&gt; library to make a much better view of the Wall of Fame. Adding state restoration was a bit of a pain but I figure if I'm going to charge for my app, I need to add little niceties like that.&lt;br /&gt;&lt;br /&gt;I also updated how I retrieved user Facebook information. To post to the app's Facebook page, the user must "like" my Facebook app. Because the user might like/unlike the app, I need to make sure I have the latest info and prompt them accordingly if they try to post one of their successful trials to my app's page. Because it was easier on me, I was retrieving that information when the app started up. But that was a sub-optimal user experience as that information only is needed when posting to the app page. So that was a needed change as I was putting myself ahead of the user.&lt;br /&gt;&lt;br /&gt;For my next update, I plan on adding functionality for users to suggest potential trials. I'm going to create a small set of web services on Google App engine that will allow users to submit a trial suggestion, email me a notification so I can review the suggestion and then return the list of suggestions to the app. &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8151007596010663103-8358695816056774791?l=ryan-brubaker.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ryan-brubaker.blogspot.com/feeds/8358695816056774791/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8151007596010663103&amp;postID=8358695816056774791' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8151007596010663103/posts/default/8358695816056774791'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8151007596010663103/posts/default/8358695816056774791'/><link rel='alternate' type='text/html' href='http://ryan-brubaker.blogspot.com/2011/08/30-days-to-success-11.html' title='30 Days to Success 1.1'/><author><name>Ryan Brubaker</name><uri>http://www.blogger.com/profile/03141230570756777197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://farm1.static.flickr.com/68/219158810_71865d5a5e.jpg?v=0'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8151007596010663103.post-7641438736264149333</id><published>2011-06-28T18:13:00.000-07:00</published><updated>2011-06-28T18:51:47.189-07:00</updated><title type='text'>Javascript closures</title><content type='html'>A couple of days ago, there was a &lt;a href="http://news.ycombinator.com/item?id=2688035"&gt;thread&lt;/a&gt; on &lt;a href="http://news.ycombinator.com/"&gt;Hacker News&lt;/a&gt; regarding Javascript closures. The thread referenced a &lt;a href="http://stackoverflow.com/questions/111102/how-do-javascript-closures-work"&gt;question&lt;/a&gt; on &lt;a href="http://stackoverflow.com/"&gt;Stack Overflow&lt;/a&gt; asking how best to explain closures. I'm not going to try and explain them here, but instead describe when the light bulb finally went off in my head regarding closures.&lt;br /&gt;&lt;br /&gt;For one of my web app projects, I needed a small component to display the number of characters being typed into a text field (a la Twitter). Unfortunately, I didn't think to check for any existing jQuery plugins for such functionality as there are quite a few. Fortunately, I just rolled my own and in the process finally realized the power of closures.&lt;br /&gt;&lt;br /&gt;My implementation turned out to be:&lt;br /&gt;&lt;pre style="overflow-x:scroll;"&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;this.AddCharacterCounter = function(textField, counterField, characterLimit)&lt;br /&gt;{&lt;br /&gt;   var updateCounter = function()&lt;br /&gt;   {&lt;br /&gt;      // All the code here to count characters and set css styles&lt;br /&gt;      // based on whether or not the limit had been reached.&lt;br /&gt;   };&lt;br /&gt;&lt;br /&gt;   var handleKeyEvent = function(event)&lt;br /&gt;   {&lt;br /&gt;      updateCounter(textField, counterField, characterLimit);&lt;br /&gt;   };&lt;br /&gt;&lt;br /&gt;   textField.keydown(handleKeyEvent);&lt;br /&gt;   textField.keyup(handleKeyEvent);&lt;br /&gt;   updateCounter();&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Then for any field that I wanted to attach such a counter, I just had to do the following:&lt;br /&gt;&lt;pre style="overflow-x:scroll;"&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;that.AddCharacterCounter($('#field1'), $('#field1Counter'), 300);&lt;br /&gt;that.AddCharacterCounter($('#field2'), $('#field2Counter'), 150);&lt;br /&gt;that.AddCharacterCounter($('#field3'), $('#field3Counter'), 30);&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8151007596010663103-7641438736264149333?l=ryan-brubaker.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ryan-brubaker.blogspot.com/feeds/7641438736264149333/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8151007596010663103&amp;postID=7641438736264149333' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8151007596010663103/posts/default/7641438736264149333'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8151007596010663103/posts/default/7641438736264149333'/><link rel='alternate' type='text/html' href='http://ryan-brubaker.blogspot.com/2011/06/javascript-closures.html' title='Javascript closures'/><author><name>Ryan Brubaker</name><uri>http://www.blogger.com/profile/03141230570756777197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://farm1.static.flickr.com/68/219158810_71865d5a5e.jpg?v=0'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8151007596010663103.post-9112304630610215955</id><published>2011-06-27T19:37:00.000-07:00</published><updated>2011-06-29T12:02:00.430-07:00</updated><title type='text'>Project Management: UI</title><content type='html'>One thing I struggle with both as a developer and PM is UI. There are two particular examples for my history as a PM.&lt;br /&gt;&lt;br /&gt;The first project was for an iPhone app where the client asked us to take their comps and make them more iPhone-friendly.  Our designer took their concepts and made what I thought was a much cleaner, usable interface. Unfortunately the client didn't like the design and we went through several more iterations of updates, each side getting more and more frustrated as our ideas weren't converging. In the end it became obvious that the client always wanted their original concept/layout but were just looking for us to create nicer UI assets for the implementation.&lt;br /&gt;&lt;br /&gt;The other project was a web application in which the client was extremely picky about the web site matching their comps pixel-for-pixel. The client did come up with a very nice design and provided us with very detailed comps so their pickiness wasn't completely unwarranted. As a PM and someone who doesn't easily pick up on UI design issues, I did not do a good job of vetting our implementation of the design before sending it on to the client. As a result a lot of time was wasted in back-and-forth communication to work out small UI mismatches.&lt;br /&gt;&lt;br /&gt;So how could I have avoided these situations? In the first case I think it was mainly a matter of communication. I interpreted the client's instructions as giving us free reign to generate a completely different implementation of the client's concepts. In the future I will make a point to thoroughly discuss with the client what they are looking for when asking us to do UI work.&lt;br /&gt;&lt;br /&gt;In the second case I think it's just becoming more aware of UI issues in general. It was obvious from the start that the client didn't want much/any deviation from their comps. But the web application was packed with functionality and as a developer, functionality is what I find interesting. In contrast, I can't just look at a label and tell what its font styles are and if they match the styles in a comp. In the future, I think I just need to consciously check for these type of issues, along with learning/practicing more design in my own side projects. I will also be more aware that a client that gives us detailed comps will probably be particular about how those comps are implemented.&lt;br /&gt;&lt;br /&gt;One other step that I think would help in such a case is getting the general HTML/CSS layout in place and signed off by the client before beginning to implement any major functionality. Such a workflow would really make HTML/CSS changes easier rather than trying to force-fit changes later on in the project.&lt;br /&gt;&lt;br /&gt;The folks at Herding Code recently had a very interesting &lt;a href="http://herdingcode.com/?p=309"&gt;podcast&lt;/a&gt; on situations like the second project I described here.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8151007596010663103-9112304630610215955?l=ryan-brubaker.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ryan-brubaker.blogspot.com/feeds/9112304630610215955/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8151007596010663103&amp;postID=9112304630610215955' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8151007596010663103/posts/default/9112304630610215955'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8151007596010663103/posts/default/9112304630610215955'/><link rel='alternate' type='text/html' href='http://ryan-brubaker.blogspot.com/2011/06/project-management-ui.html' title='Project Management: UI'/><author><name>Ryan Brubaker</name><uri>http://www.blogger.com/profile/03141230570756777197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://farm1.static.flickr.com/68/219158810_71865d5a5e.jpg?v=0'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8151007596010663103.post-7116397710277197021</id><published>2011-06-23T20:44:00.000-07:00</published><updated>2011-06-27T19:36:02.972-07:00</updated><title type='text'>Project Management: Project History</title><content type='html'>One thing I wish I had done better on my current project is to keep track of decisions that were made throughout the project. Multiple requirements have been changed multiple times and have just become more complicated throughout the process. It would be nice if there was a one-stop place where I could go to review past changes/decisions and why they were made to better make sense of new change requests. Yes, most decisions can be retrieved by searching through email but I'd like something that I can just pull up and quickly glance over, digging down deeper if necessary.&lt;br /&gt;&lt;br /&gt;So for future projects I'm planning on keeping a project journal to try and capture this information. I am going to focus on feature-level decisions as I can track task-level changes within our internal task system.&lt;br /&gt;&lt;br /&gt;At first I was thinking that a wiki would be a good place to track this information, but I'm going to create a journal document within our internal collaboration system, FirstClass. Using a document will be pretty convenient since I can drag/drop emails into the document to create links back to the conversation threads where changes were discussed and approved. These links will then serve as a way for me to dig down deeper to revisit past changes and as a gentle reminder to clients of the change requests that were made during the project.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8151007596010663103-7116397710277197021?l=ryan-brubaker.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ryan-brubaker.blogspot.com/feeds/7116397710277197021/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8151007596010663103&amp;postID=7116397710277197021' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8151007596010663103/posts/default/7116397710277197021'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8151007596010663103/posts/default/7116397710277197021'/><link rel='alternate' type='text/html' href='http://ryan-brubaker.blogspot.com/2011/06/project-managment-project-history.html' title='Project Management: Project History'/><author><name>Ryan Brubaker</name><uri>http://www.blogger.com/profile/03141230570756777197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://farm1.static.flickr.com/68/219158810_71865d5a5e.jpg?v=0'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8151007596010663103.post-6315206770644554483</id><published>2011-06-22T21:20:00.000-07:00</published><updated>2011-06-22T21:25:28.000-07:00</updated><title type='text'></title><content type='html'>TO B.R. HAYDON, ESQ.&lt;br /&gt;&lt;br /&gt;High is our calling, Friend!--Creative Art&lt;br /&gt;(Whether the instrument of words she use,&lt;br /&gt;Or pencil pregnant with ethereal hues),&lt;br /&gt;Demands the service of a mind and heart,&lt;br /&gt;Heroically fashioned--to infuse&lt;br /&gt;Faith in the whispers of the lonely Muse,&lt;br /&gt;While the whole world seems adverse to desert:&lt;br /&gt;And, oh! when Nature sinks, as oft she may,&lt;br /&gt;Through long-lived pressure of obscure distress,&lt;br /&gt;Still to be strenuous for the bright reward,&lt;br /&gt;And in the soul admit of no decay--&lt;br /&gt;Brook no continuance of weak-mindedness:&lt;br /&gt;Great is the glory, for the strife is hard!&lt;br /&gt;&lt;br /&gt;William Wordsworth&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8151007596010663103-6315206770644554483?l=ryan-brubaker.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ryan-brubaker.blogspot.com/feeds/6315206770644554483/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8151007596010663103&amp;postID=6315206770644554483' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8151007596010663103/posts/default/6315206770644554483'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8151007596010663103/posts/default/6315206770644554483'/><link rel='alternate' type='text/html' href='http://ryan-brubaker.blogspot.com/2011/06/to-b.html' title=''/><author><name>Ryan Brubaker</name><uri>http://www.blogger.com/profile/03141230570756777197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://farm1.static.flickr.com/68/219158810_71865d5a5e.jpg?v=0'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8151007596010663103.post-5055427650402490170</id><published>2011-06-21T20:15:00.000-07:00</published><updated>2011-06-29T12:03:16.504-07:00</updated><title type='text'>Project Management: People</title><content type='html'>One of my favorite blogs is &lt;a href="http://www.randsinrepose.com/"&gt;Rands In Repose&lt;/a&gt;. Rands is the only person I've ever read that makes project management sound both fun and challenging. He really seems to be able to get into the heads of people and understand what makes them tick. While reading his book &lt;a href="http://www.amazon.com/Being-Geek-Software-Developers-Handbook/dp/0596155409/ref=sr_1_1?ie=UTF8&amp;amp;qid=1308712912&amp;amp;sr=8-1"&gt;Being Geek&lt;/a&gt;, I thought to myself that I would really enjoy the challenge of being a full-time project manager in the future (there's always time to write code in my off hours...just ask my wife &lt;g&gt;). But I don't think I'm at that point yet as I'm not ready to give up writing code during my day job.&lt;br /&gt;&lt;br /&gt;One area of project management that Rands focuses on is managing people. At Art &amp;amp; Logic, I have the luxury of focusing most of my energies on the project. I'm not responsible for managing anyone's career path or filling out yearly evaluations. It's basically a matter of defining and doling out tasks. I do my best to try and match developers with tasks in which they have genuine interest, but that isn't too difficult given the unique types of projects we get.&lt;br /&gt;&lt;br /&gt;One interesting aspect of project management at Art &amp;amp; Logic is that I'm always managing new people. Part of me enjoys the opportunity to work with new people. At the same time, it would be nice to gel with a consistent team of people and developer deeper relationships. But it really seems to be the nature of consulting where projects come and go much quicker and it's necessary to match the project with people having the appropriate skills.&lt;br /&gt;&lt;br /&gt;But again, I'm thinking that it might be fun in the future to work for a product company and manage a team of developers on a commercial product. It would definitely be a new challenge to be responsible for a single product and a single team. I also think it would be fun to be more of a mentor and help people along their paths to become better developers.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/g&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8151007596010663103-5055427650402490170?l=ryan-brubaker.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ryan-brubaker.blogspot.com/feeds/5055427650402490170/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8151007596010663103&amp;postID=5055427650402490170' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8151007596010663103/posts/default/5055427650402490170'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8151007596010663103/posts/default/5055427650402490170'/><link rel='alternate' type='text/html' href='http://ryan-brubaker.blogspot.com/2011/06/project-managment-people.html' title='Project Management: People'/><author><name>Ryan Brubaker</name><uri>http://www.blogger.com/profile/03141230570756777197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://farm1.static.flickr.com/68/219158810_71865d5a5e.jpg?v=0'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8151007596010663103.post-2624292660209824851</id><published>2011-06-20T19:28:00.000-07:00</published><updated>2011-08-05T06:53:00.174-07:00</updated><title type='text'>Project Management: Time</title><content type='html'>Art &amp;amp; Logic bills on a &lt;a href="http://drdobbs.com/architecture-and-design/199001126"&gt;time and materials basis&lt;/a&gt;. This is a good thing, but as a project manager I often struggle with the thought that every hour I spend on PM tasks is an hour I take away from developers to get the real work done. At the same time, an hour spent on PM tasks could prevent countless hours of wasted time later on in the project due to a miscommunication/misunderstand of requirements.&lt;br /&gt;&lt;br /&gt;It's quite a balancing act to find that right level of involvement where you have all of the details that you need, while still squeezing out as many hours as possible for the developers. I like to think I've found that balance, though I tend to be a little more hands-off due to being a developer myself. I understand the negative impacts of interruptions and what it does to flow-state. So far this method has served me well and I think that's due to the following reasons:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;I work with a &lt;a href="http://www.artlogic.com/about-us"&gt;great group of developers&lt;/a&gt; that can take a task and complete it with minimal direction.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;I'm very detail-oriented, so even though I try to limit the hours I use as a PM, I have the complete picture of the project in front of me in my &lt;a href="http://www.davidco.com/about-gtd"&gt;GTD system&lt;/a&gt;.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;A more "hands-off" approach fits with the JUST-SUFFICIENCY model stated in Art &amp;amp; Logic's &lt;a href="http://www.artlogic.com/manifesto"&gt;development manifesto&lt;/a&gt;. An example of this in my PM style is to limit the project's tasklist to the features/tasks that are in the immediate future instead of populating the tasklist with the entire set of requirements at the beginning of the project. It's a given that many of those requirements will be changed/removed before the project comes to a close.&lt;/li&gt;&lt;/ul&gt;Another factor that comes into play is the type and size of the project. A small iPhone application does not demand the type of attention that a large web application does.&lt;br /&gt;&lt;br /&gt;I'm constantly tweaking how I do things and am hopefully improving with each project. My ultimate goal is to continue improving the efficiency of my workflow as a PM, enabling me to get more information about projects in less time.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8151007596010663103-2624292660209824851?l=ryan-brubaker.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ryan-brubaker.blogspot.com/feeds/2624292660209824851/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8151007596010663103&amp;postID=2624292660209824851' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8151007596010663103/posts/default/2624292660209824851'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8151007596010663103/posts/default/2624292660209824851'/><link rel='alternate' type='text/html' href='http://ryan-brubaker.blogspot.com/2011/06/project-managment-time.html' title='Project Management: Time'/><author><name>Ryan Brubaker</name><uri>http://www.blogger.com/profile/03141230570756777197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://farm1.static.flickr.com/68/219158810_71865d5a5e.jpg?v=0'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8151007596010663103.post-7957696840109085194</id><published>2011-06-18T20:53:00.001-07:00</published><updated>2011-08-05T07:56:50.921-07:00</updated><title type='text'>Next Few Posts</title><content type='html'>It's late so I'm going to cheat a little bit tonight and make a meta-post about my upcoming posts. When I started my job as a consultant at Art &amp; Logic, I came in expecting to write code a majority of my working hours. After a couple of projects, it became clear that client/project management was also a pretty big part of the job, especially when working as a solo developer on a project.&lt;br /&gt;&lt;br /&gt;Over the past year and a half, I've had the opportunity to manage teams of people on some pretty large projects. Before I started at Art and Logic, had you told me I'd be a project manager, I would have asked you to put me out of my misery now. My thoughts on project management/managers were too similar to Dilbert cartoons.&lt;br /&gt;&lt;br /&gt;However, I've really enjoyed learning project management and I feel that I'm getting better at it each project. My next couple of posts will talk about some of the experiences I've had and lessons learned while starting out in this new role.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8151007596010663103-7957696840109085194?l=ryan-brubaker.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ryan-brubaker.blogspot.com/feeds/7957696840109085194/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8151007596010663103&amp;postID=7957696840109085194' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8151007596010663103/posts/default/7957696840109085194'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8151007596010663103/posts/default/7957696840109085194'/><link rel='alternate' type='text/html' href='http://ryan-brubaker.blogspot.com/2011/06/next-few-posts.html' title='Next Few Posts'/><author><name>Ryan Brubaker</name><uri>http://www.blogger.com/profile/03141230570756777197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://farm1.static.flickr.com/68/219158810_71865d5a5e.jpg?v=0'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8151007596010663103.post-4504939853061274068</id><published>2011-06-17T20:40:00.000-07:00</published><updated>2011-06-17T20:58:23.944-07:00</updated><title type='text'>Beginner JavaScript Trick</title><content type='html'>So this trick is probably old-hat for any experienced JavaScript programmer, but the problem it solves tripped me up when I first started using JavaScript in depth.  I was maintaining code written by another developer and at the beginning of every JavaScript module he wrote he would always have the following line:&lt;br /&gt;&lt;code&gt;&lt;br /&gt;var that = this;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;I didn't really understand the point of it at the time until I later ran into a frustrating bug where &lt;code&gt;this&lt;/code&gt; wasn't pointing to the (top-level) object I thought it should. Sure enough, it was because I was referring to &lt;code&gt;this&lt;/code&gt; within an event handler and &lt;code&gt;this&lt;/code&gt; was pointing to the target of the event rather than the top-level object. The light bulb went off in my head. So whenever you want to refer to your top-level object, you can just reference &lt;code&gt;that&lt;/code&gt; and use &lt;code&gt;this&lt;/code&gt; everywhere else. This &lt;a href="http://www.quirksmode.org/js/this.html"&gt;article&lt;/a&gt; provides a good explanation of the issue.&lt;br /&gt;&lt;br /&gt;Sometime later, I was watching Douglas Crockford's JavaScript lectures on Yahoo and saw that he uses the same technique. Unfortunately, those videos are no longer available on Yahoo.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8151007596010663103-4504939853061274068?l=ryan-brubaker.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ryan-brubaker.blogspot.com/feeds/4504939853061274068/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8151007596010663103&amp;postID=4504939853061274068' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8151007596010663103/posts/default/4504939853061274068'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8151007596010663103/posts/default/4504939853061274068'/><link rel='alternate' type='text/html' href='http://ryan-brubaker.blogspot.com/2011/06/beginner-javascript-trick.html' title='Beginner JavaScript Trick'/><author><name>Ryan Brubaker</name><uri>http://www.blogger.com/profile/03141230570756777197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://farm1.static.flickr.com/68/219158810_71865d5a5e.jpg?v=0'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8151007596010663103.post-384221068693234011</id><published>2011-06-16T20:21:00.000-07:00</published><updated>2011-06-16T20:43:25.121-07:00</updated><title type='text'>Software project ideas</title><content type='html'>While testing my new &lt;a href="http://itunes.apple.com/us/app/30-days-to-success/id441887436?mt=8"&gt;iPhone app&lt;/a&gt;, I completed a 7-day trial to brainstorm three new mobile app ideas per day. When Apple says "there's an app for that" they're not kidding. Coming up with an original idea is pretty close to impossible. I wasn't limiting myself to original ideas and even searched the the app store to see if there were any ideas I could improve on. But any simple ideas have likely been done.&lt;br /&gt;&lt;br /&gt;For example, on the weekend of my trial, Max and I camped out at my in-laws and we toasted marshmallows. "Aha!" I thought. That would be a good gimmicky app (I was going for quantity here, not quality). Searching for marshmallow on the app store didn't turn up anything. But the next day it hit me I didn't search for s'mores and sure enough...&lt;a href="http://itunes.apple.com/us/app/smores/id339011099?mt=8%22"&gt;there's an app for that&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I did think of a couple of apps that don't seem to be in the store but they would require nice graphics and I'm not looking to do anything where I'd have to hire someone to do that work.&lt;br /&gt;&lt;br /&gt;By far the ideas I thought were best were apps for existing companies/entities to supplement their current offerings. I have several ideas now for apps for local businesses/friends . When I get some free time I'm definitely planning on approaching some people to see if they're interested.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8151007596010663103-384221068693234011?l=ryan-brubaker.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ryan-brubaker.blogspot.com/feeds/384221068693234011/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8151007596010663103&amp;postID=384221068693234011' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8151007596010663103/posts/default/384221068693234011'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8151007596010663103/posts/default/384221068693234011'/><link rel='alternate' type='text/html' href='http://ryan-brubaker.blogspot.com/2011/06/software-project-ideas.html' title='Software project ideas'/><author><name>Ryan Brubaker</name><uri>http://www.blogger.com/profile/03141230570756777197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://farm1.static.flickr.com/68/219158810_71865d5a5e.jpg?v=0'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8151007596010663103.post-4435597765119375076</id><published>2011-06-15T20:26:00.000-07:00</published><updated>2011-06-15T20:50:47.938-07:00</updated><title type='text'>30 Days to Success</title><content type='html'>This week Apple approved my iPhone app &lt;a href="http://itunes.apple.com/us/app/30-days-to-success/id441887436?mt=8%22"&gt;30 Days to Success&lt;/a&gt;, which is an application based on Steve Pavlina's &lt;a href="http://www.stevepavlina.com/blog/2005/04/30-days-to-success/"&gt;article&lt;/a&gt; of the same name.&lt;br /&gt;&lt;br /&gt;I've had the idea for this app for several years now and actually developed a prototype 2 years ago. I emailed Steve to see if he would be interested in the app but he declined. So I dropped the idea not wanting to infringe on his copyrights.&lt;br /&gt;&lt;br /&gt;But late last year Steve &lt;a href="http://www.stevepavlina.com/blog/2010/12/releasing-my-copyrights/"&gt;released all copyrights&lt;/a&gt; to his online content so I decided to start the project back up.&lt;br /&gt;&lt;br /&gt;Back in the prototype phase, I had created my own hideous calendar UI. After stopping work on the project, I ran across the &lt;a href="https://github.com/klazuka/Kal/"&gt;Kal&lt;/a&gt; library when doing some estimates at my day job and and knew that was something I would have to integrate. So with a better looking UI and some updates to integrate Facebook and Twitter, I thought I had something that was worthy of release. There are a couple of things I'm still not happy with but I will fix them over time.&lt;br /&gt;&lt;br /&gt;I'm not expecting too much income from the app although I'm hoping to make a little bit of passive income off of it in the long run. I think I have a couple of things going for me:&lt;br /&gt;- I can take advantage of Steve Pavlina's already large audience.&lt;br /&gt;- Integration of Facebook and Twitter will put the app in front of a lot more eyes.&lt;br /&gt;- I'm planning some other social features that should encourage current users to get others involved with the app.&lt;br /&gt;&lt;br /&gt;I had one sale the first day and two sales the second day. Assuming this exponential growth rate continues, I'll be at a million sales in no time :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8151007596010663103-4435597765119375076?l=ryan-brubaker.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ryan-brubaker.blogspot.com/feeds/4435597765119375076/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8151007596010663103&amp;postID=4435597765119375076' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8151007596010663103/posts/default/4435597765119375076'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8151007596010663103/posts/default/4435597765119375076'/><link rel='alternate' type='text/html' href='http://ryan-brubaker.blogspot.com/2011/06/30-days-to-success.html' title='30 Days to Success'/><author><name>Ryan Brubaker</name><uri>http://www.blogger.com/profile/03141230570756777197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://farm1.static.flickr.com/68/219158810_71865d5a5e.jpg?v=0'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8151007596010663103.post-5220307228916931058</id><published>2011-06-14T19:34:00.000-07:00</published><updated>2011-06-14T19:42:15.950-07:00</updated><title type='text'>Day 1 of 30</title><content type='html'>In honor of the release of my new &lt;a href="http://itunes.apple.com/us/app/30-days-to-success/id441887436?mt=8"&gt;iPhone app&lt;/a&gt; to the iTunes store, I am going to try and complete a 30 day trial to write something here every day.&lt;br /&gt;&lt;br /&gt;I've queued up about 10 topics I'd like to write about so I should be good to go for at least the first week and a half. &lt;br /&gt;&lt;br /&gt;And with that, Day 1 is a success ;)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8151007596010663103-5220307228916931058?l=ryan-brubaker.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ryan-brubaker.blogspot.com/feeds/5220307228916931058/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8151007596010663103&amp;postID=5220307228916931058' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8151007596010663103/posts/default/5220307228916931058'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8151007596010663103/posts/default/5220307228916931058'/><link rel='alternate' type='text/html' href='http://ryan-brubaker.blogspot.com/2011/06/day-1-of-30.html' title='Day 1 of 30'/><author><name>Ryan Brubaker</name><uri>http://www.blogger.com/profile/03141230570756777197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://farm1.static.flickr.com/68/219158810_71865d5a5e.jpg?v=0'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8151007596010663103.post-2605133083131857336</id><published>2010-09-21T19:24:00.000-07:00</published><updated>2010-10-01T06:14:04.065-07:00</updated><title type='text'>New Hobby</title><content type='html'>One of my favorite classes in college was the Digital Logic class where we had to design basic computer circuitry. Then this year I read &lt;a href="http://www.amazon.com/Code-Language-Computer-Hardware-Software/dp/0735611319/ref=sr_1_1?ie=UTF8&amp;s=books&amp;qid=1285122387&amp;sr=8-1"&gt;Code: The Hidden Language of Computer Hardware and Software&lt;/a&gt; and again, was just engrossed in all of the gates, adders and multiplexers. I really am clueless when it comes to a lot of this stuff but always wanted to get some hands-on experience.&lt;br /&gt;&lt;br /&gt;I first found about the &lt;a href=http://www.arduino.cc/"&gt;Arduino&lt;/a&gt; project from the &lt;a href="http://www.pragprog.com/magazines/2010-07/meet-the-arduino"&gt;July 2010 issue of PragPub&lt;/a&gt;. Then a couple of weeks ago, a friend of mine mentioned that he bought an Arduino and was fooling around with it so I decided to take the plunge too.&lt;br /&gt;&lt;br /&gt;Like my friend, I ended up purchasing the &lt;a href=http://www.sparkfun.com/commerce/product_info.php?products_id=10057&gt;SparkFun Inventor's Kit for Arduino&lt;/a&gt;, which comes with some basic parts and project schema to get you started.&lt;br /&gt;&lt;br /&gt;Here is a video of my son and I with our first project to light up some LEDs:&lt;br /&gt;&lt;br /&gt;&lt;object width="400" height="400"&gt;&lt;param name="movie" value="http://www.youtube.com/v/LCjO4d8fOis?fs=1&amp;amp;hl=en_US"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/LCjO4d8fOis?fs=1&amp;amp;hl=en_US" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="400" height="400"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8151007596010663103-2605133083131857336?l=ryan-brubaker.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ryan-brubaker.blogspot.com/feeds/2605133083131857336/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8151007596010663103&amp;postID=2605133083131857336' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8151007596010663103/posts/default/2605133083131857336'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8151007596010663103/posts/default/2605133083131857336'/><link rel='alternate' type='text/html' href='http://ryan-brubaker.blogspot.com/2010/09/new-hobby.html' title='New Hobby'/><author><name>Ryan Brubaker</name><uri>http://www.blogger.com/profile/03141230570756777197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://farm1.static.flickr.com/68/219158810_71865d5a5e.jpg?v=0'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8151007596010663103.post-3942906371016581344</id><published>2010-09-19T20:52:00.001-07:00</published><updated>2010-09-19T21:04:44.823-07:00</updated><title type='text'>New Home Page</title><content type='html'>I've been doing a lot of work on Google App Engine lately and finally registered a domain name for myself at &lt;a href="http://www.ryan-brubaker.com/"&gt;ryan-brubaker.com&lt;/a&gt;. It's probably a little bit of overkill to use GAE for a personal site but I just find it easier. I'm going to use that page to start putting up code samples, keep track of books I've read and anything else that strikes my fancy. &lt;br /&gt;&lt;br /&gt;I'll still be using blogger to host my blog, which after a year of silence, I hope to get back on track again. This past year has been a busy year for me and I have a lot of things I'd like to write about.&lt;br /&gt;&lt;br /&gt;And for a little vanity note, I'm now listed on the Developer Testimonials page on the Art &amp; Logic website: &lt;a href="http://www.artlogic.com/careers"&gt;Art &amp; Logic Careers&lt;/a&gt; (click the Developer Testimonials tab).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8151007596010663103-3942906371016581344?l=ryan-brubaker.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ryan-brubaker.blogspot.com/feeds/3942906371016581344/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8151007596010663103&amp;postID=3942906371016581344' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8151007596010663103/posts/default/3942906371016581344'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8151007596010663103/posts/default/3942906371016581344'/><link rel='alternate' type='text/html' href='http://ryan-brubaker.blogspot.com/2010/09/new-home-page.html' title='New Home Page'/><author><name>Ryan Brubaker</name><uri>http://www.blogger.com/profile/03141230570756777197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://farm1.static.flickr.com/68/219158810_71865d5a5e.jpg?v=0'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8151007596010663103.post-2216370184624815404</id><published>2009-08-22T20:27:00.000-07:00</published><updated>2009-08-22T20:58:09.280-07:00</updated><title type='text'>Coming Up for Air</title><content type='html'>So much for posting once a month...&lt;br /&gt;&lt;br /&gt;I've been extremely busy in my life lately, mostly due to work, which is a good thing given the state of the economy. But I'm finally seeing the light at the end of the tunnel and I think my schedule will be a little more normal in the coming weeks.&lt;br /&gt;&lt;br /&gt;July was my one year anniversary at &lt;a href="http://www.artlogic.com"&gt;Art &amp;amp; Logic&lt;/a&gt;. And what a year! I've worked on 13 different projects throughout the past year, all of which I've really enjoyed. I've programmed in C++, Java, Objective C, ActionScript3/Flex, Javascript and C# (including ASP.net). I've written desktop programs, BlackBerry apps, iPhone apps (2 in the store, 1 pending approval, and some others still in progress) and a web application targeting the iPhone (and BlackBerry in the near future).&lt;br /&gt;Needless to say, I'm having a blast and working as a consultant is providing me the variety I crave in a job.&lt;br /&gt;&lt;br /&gt;One of my most recent projects, hinted at above, is an ASP.net application targeting the iPhone and BlackBerry platforms. This was my first production-level web application, although I've spent a little time on my own learning Ruby on Rails and a little bit of time at work learning TurboGears. It's been a lot of fun, and I was surprised at how much I enjoyed using ASP.net.&lt;br /&gt;&lt;br /&gt;What I've realized during this project though, is that I really need to come up to speed on Javascript/CSS. This project was small enough that I didn't run into too many issues, but if I want to continue doing web applications (and I do), I really need a more thorough knowledge of those two technologies. I'm planning on buying some books in the near future that should hopefully give me the basics I need to build a stronger knowledge base.&lt;br /&gt;&lt;br /&gt;I'm also hoping to provide some updates to the &lt;a href="http://ryan-brubaker.blogspot.com/2008/03/grader-whathow.html"&gt;Grader&lt;/a&gt; program I developed for my brother. The deadline on that is pretty tight as his football season is rapidly approaching. So there may be a couple of late nights for me coming up in the near future.&lt;br /&gt;&lt;br /&gt;One other project I have in mind is a simple application written on top of the Google app engine. I am a secretary for a local organization, and I'd like to create a web application that allows people to submit information to me, aggregate it, and resend it out to concerned parties. Sifting through separate emails to gather the information and compose a new email is taking up too much of my time. And it's another chance to get some web development experience.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://ryan-brubaker.blogspot.com/2009/01/code-kata.html"&gt;Code Kata&lt;/a&gt; and &lt;a href="http://ryan-brubaker.blogspot.com/2008/04/learning-math.html"&gt;Learning Math&lt;/a&gt; have been on hold for quite a while, but I'm hoping to get those back on track also.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8151007596010663103-2216370184624815404?l=ryan-brubaker.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ryan-brubaker.blogspot.com/feeds/2216370184624815404/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8151007596010663103&amp;postID=2216370184624815404' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8151007596010663103/posts/default/2216370184624815404'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8151007596010663103/posts/default/2216370184624815404'/><link rel='alternate' type='text/html' href='http://ryan-brubaker.blogspot.com/2009/08/coming-up-for-air.html' title='Coming Up for Air'/><author><name>Ryan Brubaker</name><uri>http://www.blogger.com/profile/03141230570756777197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://farm1.static.flickr.com/68/219158810_71865d5a5e.jpg?v=0'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8151007596010663103.post-1080968169197332161</id><published>2009-01-28T19:26:00.000-08:00</published><updated>2009-01-28T20:32:33.725-08:00</updated><title type='text'>Code Kata</title><content type='html'>One of my goals for quite a while has been starting a &lt;a href="http://codekata.pragprog.com/"&gt;Code Kata&lt;/a&gt; practice. Dave Thomas nicely sums up the benefits of such a habit at the above link. However, there are several  other reasons I want to start this practice, all of which fall under the category of becoming a better programmer, but which have materialized after starting my job as a consultant. The main factor in recognizing these areas in which I'd like to improve, has been working within very aggressive budgets (time-wise) that don't allow much time to stray from the well-beaten path.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.codinghorror.com/blog/archives/000152.html"&gt;&lt;span style="font-weight: bold;"&gt;Good Programmers Write Good Code; Great Programmers Steal Great Code&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;One consequence of aggressive budgets is that it usually makes sense to find existing code that does what you need it to do, rather than writing it from scratch. Between sample code in documentation, generic code from previous projects and personal blog posts, it's almost impossible &lt;span style="font-style: italic;"&gt;&lt;span style="font-weight: bold;"&gt;not&lt;/span&gt;&lt;/span&gt; to be able to find existing code that at least points you in the direction you need to go.&lt;br /&gt;&lt;br /&gt;Unfortunately, I think this has somewhat diminished my ability to quickly solve problems on my own. I want to use the Code Kata practice to plop myself in front of a blank editor and pull the code out of my head.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Unit Testing&lt;/span&gt;&lt;br /&gt;Ever since taking a TDD course taught by &lt;a href="http://www.objectmentor.com/omTeam/martin_r.html"&gt;Robert Martin&lt;/a&gt;, I've wanted the same experience I had in his class in my daily programming activities. Having a suite of tests to run after each code change and seeing those tests pass was very gratifying. Even more gratifying was changing the code, seeing an error, and knowing exactly where and why that error occurred because of the tests we had in place.&lt;br /&gt;&lt;br /&gt;Most of my projects so far as a consultant haven't been very business-rule intensive. So the model objects in the code were pretty simple and the projects wouldn't have benefited that much from a unit-test suite.&lt;br /&gt;&lt;br /&gt;The problem is, even if unit tests would have been useful, I don't have enough experience with the standard testing tools to quickly integrate them into a project without wasting valuable budget time.&lt;br /&gt;&lt;br /&gt;I want to use the Code Kata practice to learn the different testing tools that exist, including tools that test at a higher level than a unit.  I'm also hoping to get better at understanding what to test and how to write better tests.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Learning new tools/libraries/languages/specialty areas&lt;/span&gt;&lt;br /&gt;This last point is similar to the previous one, but I also want to expand my tool set in other areas. One example is becoming an expert in a standard editor that I would use across languages in order to increase my efficiency in editor use. Another example, is focusing the Code Kata practice on an area such as Artificial Intelligence or Image Processing for a set amount of time.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Next Steps&lt;/span&gt;&lt;br /&gt;The biggest problem in getting into this habit, like any habit really, is finding the time to do it. I know I will not be able to follow a set schedule so I will just have to be disciplined enough to dedicate some time to it every few weeks. Hopefully, posting on this blog will give me a way to stay accountable.&lt;br /&gt;&lt;br /&gt;My first practice will be to review &lt;a href="http://www.amazon.com/Programming-Language-Prentice-Hall-Software/dp/0131103628"&gt;&lt;span style="font-style: italic;"&gt;The C Programming Language&lt;/span&gt;.&lt;/a&gt; I already know C, but I think it will be a good way to review and give myself the pleasure of making some fast progress when I start. It certainly won't hurt to reinforce some of the basics again. And it will also give me some easy programs for unit testing, allowing some quick progress on that front.&lt;br /&gt;&lt;br /&gt;The other thing I'd like to do during this first practice, is to learn Emacs and eventually use it as my standard editor. This will likely take quite a bit of time, but I need to start sometime. But again, it will help to start out small, reviewing a language I already know instead of taking on too many new areas at once.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8151007596010663103-1080968169197332161?l=ryan-brubaker.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ryan-brubaker.blogspot.com/feeds/1080968169197332161/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8151007596010663103&amp;postID=1080968169197332161' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8151007596010663103/posts/default/1080968169197332161'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8151007596010663103/posts/default/1080968169197332161'/><link rel='alternate' type='text/html' href='http://ryan-brubaker.blogspot.com/2009/01/code-kata.html' title='Code Kata'/><author><name>Ryan Brubaker</name><uri>http://www.blogger.com/profile/03141230570756777197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://farm1.static.flickr.com/68/219158810_71865d5a5e.jpg?v=0'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8151007596010663103.post-2473089021012445704</id><published>2009-01-05T17:58:00.000-08:00</published><updated>2009-01-05T19:03:39.269-08:00</updated><title type='text'>iPhone SDK : UIWebView</title><content type='html'>I've been tangling with &lt;code&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;UIWebView&lt;/span&gt;&lt;/code&gt; the past couple of days and am documenting my struggles in hopes that this post may save others some time in the future. I've found a solution to my problem, intercepting single-tap events that occur on a &lt;code&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;UIWebView&lt;/span&gt;&lt;/code&gt;, although the solution doesn't seem to be optimal. But first, a little background to the other approaches I've tried...&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;Subclassing&lt;/span&gt; &lt;code&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;UIWebView&lt;/span&gt;&lt;/code&gt;/Overlaying a Transparent &lt;code&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;UIView&lt;/span&gt;&lt;/code&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;These approaches are basically the same. In a &lt;code&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;UIWebView&lt;/span&gt;&lt;/code&gt; subclass or in a transparent &lt;code&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;UIView&lt;/span&gt;&lt;/code&gt; subclass (on top of a &lt;code&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;UIWebView&lt;/span&gt;&lt;/code&gt;), override the &lt;code&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_8"&gt;UIResponder&lt;/span&gt;&lt;/code&gt; methods (&lt;code&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_9"&gt;touchesBegan&lt;/span&gt;:&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_10"&gt;withEvent&lt;/span&gt;&lt;/code&gt;, &lt;code&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_11"&gt;touchesMoved&lt;/span&gt;:&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_12"&gt;withEvent&lt;/span&gt;&lt;/code&gt;, etc...) and handle the touches accordingly.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The catch here for me was that I really wanted the &lt;code&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_13"&gt;UIWebView&lt;/span&gt;&lt;/code&gt; to behave as it always did for any other events. This would suggest that I just needed to intercept any single-tap events, and afterwards, forward all events to the &lt;code&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_14"&gt;UIWebView&lt;/span&gt;&lt;/code&gt;. However, what you really need to do is forward the events to the &lt;code&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_15"&gt;UiWebView's&lt;/span&gt;&lt;/code&gt; immediate &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_16"&gt;subview&lt;/span&gt;, which is an instance of &lt;code&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_17"&gt;UIScroller&lt;/span&gt;&lt;/code&gt;. This solution seemed like it would work until I realized that pinch zoom events no longer worked and they are essential to the application I'm building.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Even more frustrating is the fact that all of &lt;code&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_18"&gt;UIWebView's&lt;/span&gt;&lt;/code&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_19"&gt;subviews&lt;/span&gt; are not part of the public &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_20"&gt;SDK&lt;/span&gt;. This fact makes it pretty much impossible to &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_21"&gt;programmatically&lt;/span&gt; change how &lt;code&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_22"&gt;UIWebView&lt;/span&gt;&lt;/code&gt; works under the covers.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;For more information on this approach, see the following &lt;a href="http://discussions.apple.com/thread.jspa?messageID=8486052"&gt;thread&lt;/a&gt; in the Apple &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_23"&gt;developer &lt;/span&gt;forums.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;Overriding &lt;code&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_24"&gt;UIView&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_25"&gt;hitTest&lt;/span&gt;:&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_26"&gt;withEvent&lt;/span&gt;&lt;/code&gt;method&lt;/span&gt;&lt;/div&gt;&lt;div&gt;According to &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_27"&gt;Kerem&lt;/span&gt; at &lt;a href="http://www.codingventures.com/?p=31"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_28"&gt;CodingVentures&lt;/span&gt;&lt;/a&gt;, he was able to intercept double-tap events on a &lt;code&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_29"&gt;UIWebView&lt;/span&gt;&lt;/code&gt; by &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_30"&gt;subclassing&lt;/span&gt; and overriding the &lt;code&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_31"&gt;hitTest&lt;/span&gt;:&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_32"&gt;withEvent&lt;/span&gt;&lt;/code&gt; method. However, when I implemented this technique, the &lt;code&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_33"&gt;UIEvent&lt;/span&gt;&lt;/code&gt; passed into the method always had an empty set of touches making it impossible to get the &lt;code&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_34"&gt;tapCount&lt;/span&gt;&lt;/code&gt; property on any &lt;code&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_35"&gt;UITouch&lt;/span&gt;&lt;/code&gt; objects. I tried overriding &lt;code&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_36"&gt;hitTest&lt;/span&gt;:&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_37"&gt;withEvent&lt;/span&gt;&lt;/code&gt; for other &lt;code&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_38"&gt;UIView&lt;/span&gt;&lt;/code&gt; controls (e.g &lt;code&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_39"&gt;UIWindow&lt;/span&gt;&lt;/code&gt;, &lt;code&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_40"&gt;UIScrollView&lt;/span&gt;&lt;/code&gt;, etc...) all with the same result.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;My Solution&lt;/span&gt;&lt;/div&gt;&lt;div&gt;The solution I came up with was to subclass &lt;code&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_41"&gt;UIWindow&lt;/span&gt;&lt;/code&gt; and override the &lt;code&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_42"&gt;sendEvent&lt;/span&gt;:&lt;/code&gt; method. This method gets called after &lt;code&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_43"&gt;hitTest&lt;/span&gt;:&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_44"&gt;sendEvent&lt;/span&gt;&lt;/code&gt; returns but before any of the &lt;code&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_45"&gt;UIResponder&lt;/span&gt;&lt;/code&gt; methods get called. At this point, the &lt;code&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_46"&gt;UIEvent&lt;/span&gt;&lt;/code&gt; contains all of the associated touches, allowing me to access the &lt;code&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_47"&gt;tapCount&lt;/span&gt;&lt;/code&gt; property of the associated &lt;code&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_48"&gt;UITouch&lt;/span&gt;&lt;/code&gt; objects.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This solution isn't perfect as I am now handling single-taps at the window level instead of just those that occur on the &lt;code&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_49"&gt;UIWebView&lt;/span&gt;&lt;/code&gt;. Luckily, this doesn't really interfere with what I'm trying to do in my application.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I'd still really like to know why it seems that &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_50"&gt;someimes&lt;/span&gt; the &lt;code&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_51"&gt;UIEvent&lt;/span&gt;&lt;/code&gt; passed into &lt;code&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_52"&gt;hitTest&lt;/span&gt;:&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_53"&gt;sendEvent&lt;/span&gt;&lt;/code&gt; has touches associated with it and sometimes doesn't. I'd also be interested if anyone can successfully forward on pinch events to &lt;code&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_54"&gt;UIWebView&lt;/span&gt;&lt;/code&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/8151007596010663103-2473089021012445704?l=ryan-brubaker.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ryan-brubaker.blogspot.com/feeds/2473089021012445704/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8151007596010663103&amp;postID=2473089021012445704' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8151007596010663103/posts/default/2473089021012445704'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8151007596010663103/posts/default/2473089021012445704'/><link rel='alternate' type='text/html' href='http://ryan-brubaker.blogspot.com/2009/01/iphone-sdk-uiwebview.html' title='iPhone SDK : UIWebView'/><author><name>Ryan Brubaker</name><uri>http://www.blogger.com/profile/03141230570756777197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://farm1.static.flickr.com/68/219158810_71865d5a5e.jpg?v=0'/></author><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8151007596010663103.post-5724090825519419107</id><published>2009-01-02T19:20:00.000-08:00</published><updated>2009-01-02T19:50:08.788-08:00</updated><title type='text'>This and That</title><content type='html'>I was able to clear my plate of several things at year's end and am looking to a fresh start to the new year. &lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;Job&lt;/span&gt;&lt;/div&gt;&lt;div&gt;My job is still going really well and I'm very happy with the decision I made to join Art &amp;amp; Logic. I've learned so much over the past half year and see that continuing into the new year. A project I completed for M Financial Group is now featured on our &lt;a href="http://www.artlogic.com/work/projects.php"&gt;website&lt;/a&gt; as it was the first native Blackberry application completed by our company. My current project is for the iPhone and should be completed early this year.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;Math&lt;/span&gt;&lt;/div&gt;&lt;div&gt;I finally completed the &lt;a href="http://www.amazon.com/Practical-Algebra-Self-Teaching-Guide-2nd/dp/0471530123/ref=pd_bbs_sr_1?ie=UTF8&amp;amp;s=books&amp;amp;qid=1230953687&amp;amp;sr=8-1"&gt;algebra book&lt;/a&gt; I started earlier this year. I have a bad habit of not quitting books I've started, even if I've decided they aren't that interesting or helpful. I probably didn't need to go through this whole book as it was pretty basic stuff. But it was a good refresher and a confidence booster that I haven't forgotten all of the math I've ever learned. The next math book I'm planning to tackle is &lt;a href="http://www.matrixanalysis.com/DownloadChapters.html"&gt;Matrix Analysis and Applied Linear Algebra&lt;/a&gt;, which I know will be more challenging and should provide more value.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;Grader&lt;/span&gt;&lt;/div&gt;&lt;div&gt;My brother asked for some updates to this program, namely the ability to save application session state. So I am going to add an sqlite backend to add the ability to save/reload the program data and hopefully refactor the code a little bit. I've switched over to a Macbook as my primary development machine and finally got all of the software downloaded/installed to my VirtualBox Windows image for this project. I had been using Eclipse's CDT plugin to develop this app but I'm going to switch over to Visual Studio Express since it's free.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;Code Kata&lt;/span&gt;&lt;/div&gt;&lt;div&gt;I am going to write a post in the near future about how I'm planning on starting this development practice.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;Blogging&lt;/span&gt;&lt;/div&gt;&lt;div&gt;I set a goal to write a post on this blog at least once a month this year. But I'm going to try and do more than that if I can.&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/8151007596010663103-5724090825519419107?l=ryan-brubaker.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ryan-brubaker.blogspot.com/feeds/5724090825519419107/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8151007596010663103&amp;postID=5724090825519419107' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8151007596010663103/posts/default/5724090825519419107'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8151007596010663103/posts/default/5724090825519419107'/><link rel='alternate' type='text/html' href='http://ryan-brubaker.blogspot.com/2009/01/this-and-that.html' title='This and That'/><author><name>Ryan Brubaker</name><uri>http://www.blogger.com/profile/03141230570756777197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://farm1.static.flickr.com/68/219158810_71865d5a5e.jpg?v=0'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8151007596010663103.post-2588239605561533248</id><published>2008-08-31T20:11:00.000-07:00</published><updated>2008-09-02T19:48:08.258-07:00</updated><title type='text'>It's Been a While...</title><content type='html'>since I wrote anything here, but that's mainly because I've been focused on finishing up the work for my Master's degree. And I'm happy to say that everything has been completed except for a few touch-up edits to my final paper. I'm very relieved that this process is over and I'm looking forward to evenings where I can choose to do whatever I want, or at least choose to do whatever I want without feeling guilty about procrastinating on my project :)&lt;br /&gt;&lt;br /&gt;So what am I going to do? As far as software development is concerned my goals are the following:&lt;div&gt;&lt;ol&gt;&lt;li&gt;Establish a regular &lt;a href="http://codekata.pragprog.com/2007/01/code_kata_backg.html"&gt;Code Kata&lt;/a&gt; practice.&lt;/li&gt;&lt;li&gt;Continue &lt;a href="http://ryan-brubaker.blogspot.com/2008/04/learning-math.html"&gt;learning math&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;Add some more features to &lt;a href="http://ryan-brubaker.blogspot.com/2008/03/new-product-grader.html"&gt;Grader&lt;/a&gt; that my brother requested and convert it into a web application using Ruby on Rails.&lt;/li&gt;&lt;li&gt;Establish a consistent GTD system.&lt;/li&gt;&lt;/ol&gt;Following through on these goals should also give me plenty of material to regularly post to this blog.&lt;/div&gt;&lt;div&gt; &lt;/div&gt;&lt;div&gt;Of course, all of these goals are secondary to performing at my &lt;a href="http://ryan-brubaker.blogspot.com/2008/07/new-job.html"&gt;current job&lt;/a&gt;, which has been absolutely great so far. I finished up my first project about a month ago, released a cut of my second project today, and should be starting my third project in a couple of days. Each project has required me to work with a new programming language and/or work with a very interesting 3rd party API. Working from home has take some getting used to, but I'm definitely able to concentrate better and feel that my productivity has significantly increased.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I'm really looking forward to this time in my life and feel that completing my degree now affords me time to really concentrate on becoming a better developer. &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8151007596010663103-2588239605561533248?l=ryan-brubaker.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ryan-brubaker.blogspot.com/feeds/2588239605561533248/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8151007596010663103&amp;postID=2588239605561533248' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8151007596010663103/posts/default/2588239605561533248'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8151007596010663103/posts/default/2588239605561533248'/><link rel='alternate' type='text/html' href='http://ryan-brubaker.blogspot.com/2008/08/its-been-while.html' title='It&apos;s Been a While...'/><author><name>Ryan Brubaker</name><uri>http://www.blogger.com/profile/03141230570756777197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://farm1.static.flickr.com/68/219158810_71865d5a5e.jpg?v=0'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8151007596010663103.post-3649814280251489336</id><published>2008-07-01T20:49:00.001-07:00</published><updated>2008-07-01T21:21:27.227-07:00</updated><title type='text'>New Job</title><content type='html'>On Thursday, July 10&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;th&lt;/span&gt;, I will be starting a new job with &lt;a href="http://www.artlogic.com"&gt;Art &amp;amp; Logic&lt;/a&gt;. I'm very excited about this career change and can't wait to start.&lt;br /&gt;&lt;br /&gt;Leaving my current job was both an easy decision a and hard decision to make. I really like the people I work with and will miss the camaraderie our team shared. I'm also leaving right in the middle of a large project so the timing isn't the best. But finding the perfect time to leave is probably impossible.&lt;br /&gt;&lt;br /&gt;With that said, I feel very confident I'm making the correct long-term decision. I've worked for my current employer for over seven years, the last four years working on the same project. One of my favorite things about programming is that it requires a constant effort to learn new languages, skills and techniques and I feel that my current position was lacking in this area. I work in a very mature industry with little opportunity for innovation. Programming has become somewhat stale for me over the past few months, and to me, that signals a need for change. Spending nine hours a day at a job that just isn't fun anymore does a disservice to myself, my family and the rest of my team.&lt;br /&gt;&lt;br /&gt;My new job should remedy the problems I stated above. It's a contracting position so I'm looking forward to the variety of projects and challenges I will face. I already feel rejuvenated when it comes to writing code and am ready to jump headfirst into my first project. I will also be working out of my home, which I'm sure will pose a new set of challenges for me and my family. But the thought of escaping the cube farm and working in an environment where it will be much easier to reach a flow-state, is very satisfying. There are some potential downsides to working as a contractor, but I'm not too concerned about them at this point. I'm really just excited about the chance at a fresh start and the opportunities that lie ahead.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8151007596010663103-3649814280251489336?l=ryan-brubaker.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ryan-brubaker.blogspot.com/feeds/3649814280251489336/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8151007596010663103&amp;postID=3649814280251489336' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8151007596010663103/posts/default/3649814280251489336'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8151007596010663103/posts/default/3649814280251489336'/><link rel='alternate' type='text/html' href='http://ryan-brubaker.blogspot.com/2008/07/new-job.html' title='New Job'/><author><name>Ryan Brubaker</name><uri>http://www.blogger.com/profile/03141230570756777197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://farm1.static.flickr.com/68/219158810_71865d5a5e.jpg?v=0'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8151007596010663103.post-2083132909682287697</id><published>2008-04-19T19:41:00.000-07:00</published><updated>2008-04-19T20:39:32.610-07:00</updated><title type='text'>Book Review: Out of their Minds: The Lives and Discoveries of 15 Great Computer Scientists</title><content type='html'>I'm on a roll in the book department.&lt;br /&gt;&lt;br /&gt;As its title implies, this book presents 15 major figures (e.g. Dijkstra, Knuth, McCarthy) in computer science history and some of their most important discoveries. It was a very interesting, humbling, and motivating read. It's amazing to think of what these men discovered without the high level languages and modern hardware that is available today. Had I grown up in their generation, I doubt I would have pursued a career in software.  Although I enjoyed my assembly language class in college, one semester was enough. Although I am obviously not on the same intellectual plane as the subjects of the book, reading about their accomplishments was inspiration enough to continue becoming a better developer and expanding my knowledge about computer science.&lt;br /&gt;&lt;br /&gt;Two other things that jumped out at me when reading this book:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;It was interesting to see that many of these men started their careers (or academic careers) in something other than computer science. From biology, to music, to chemistry, most of them were proficient in some other field before ending up in their final career path. What they all had in common though, was a passion for creating things, which easily transferred into the computer science field.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Reading this book made me wonder why college computer science programs (at least mine) do not have a &lt;span style="font-style: italic;"&gt;History of Computer Science&lt;/span&gt; class where these men and their discoveries are the focus of the course. I think many students would gain an appreciation for the history behind the major discoveries in the field, along with the same motivation I received from reading the book. It would also make students appreciate the work and dedication required to become an expert in the field.&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8151007596010663103-2083132909682287697?l=ryan-brubaker.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ryan-brubaker.blogspot.com/feeds/2083132909682287697/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8151007596010663103&amp;postID=2083132909682287697' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8151007596010663103/posts/default/2083132909682287697'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8151007596010663103/posts/default/2083132909682287697'/><link rel='alternate' type='text/html' href='http://ryan-brubaker.blogspot.com/2008/04/book-review-out-of-their-minds-lives.html' title='Book Review: Out of their Minds: The Lives and Discoveries of 15 Great Computer Scientists'/><author><name>Ryan Brubaker</name><uri>http://www.blogger.com/profile/03141230570756777197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://farm1.static.flickr.com/68/219158810_71865d5a5e.jpg?v=0'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8151007596010663103.post-8480632292994666071</id><published>2008-04-13T19:02:00.001-07:00</published><updated>2008-04-13T19:02:50.660-07:00</updated><title type='text'>Book Review:  Tog on Software Design</title><content type='html'>I just finished reading &lt;a href="http://www.amazon.com/Tog-Software-Design-Bruce-Tognazzini/dp/0201489171/ref=sr_1_1?ie=UTF8&amp;amp;s=books&amp;amp;qid=1208136660&amp;amp;sr=8-1"&gt;&lt;span style="font-style: italic;"&gt;Tog on Software Design&lt;/span&gt;&lt;/a&gt;, a very interesting book overall, although I found some parts a little more interesting than others.&lt;br /&gt;&lt;br /&gt;Much of the focus of the book is on Bruce Tognazzi's &lt;a href="http://www.asktog.com/starfire/"&gt;&lt;span style="font-style: italic;"&gt;Starfire&lt;/span&gt;&lt;/a&gt; project, a project started in 1992 to provide a vision of the future for software in the year 2004. The transcripts of the resulting video from the project were a little tedious to get through...I should have just watched the &lt;a href="http://www.asktog.com/starfire/starfire.mp4"&gt;video&lt;/a&gt;. It was interesting to see how much of the technology featured in the video still isn't available four years after the story takes place.&lt;br /&gt;&lt;br /&gt;The rest of the book focused on design principles intended to provide a better user experience when creating software. Many of the principles he presented were simple matter of fact statements that seemed obvious. But turning his principles into implementations are probably easier said than done.&lt;br /&gt;&lt;blockquote&gt;&lt;/blockquote&gt;The part of the book I found most interesting was his side-by-side comparison of software and magic. It is an interesting metaphor that doesn't seem very obvious, but makes a lot of sense after his explanation. To summarize:&lt;br /&gt;&lt;blockquote&gt;Both software designers and magicians create virtual realities. We bring ours alive on computer displays; magicians bring theirs alive on the stage. We capture our "performances" in code so they can continue to occur long after their writing; magicians traditionally appear live. We depend on our knowledge of the mechanics of computer technology, the aesthetics of graphic design, and the science of psychology. Magicians depend on their knowledge of the mechanics of their tricks, the aesthetics of showmanship, and the science of psychology.&lt;/blockquote&gt;&lt;blockquote&gt;&lt;/blockquote&gt;It's interesting to envision the goal of software design as providing a user with an illusion that makes the physical computer disappear and replaces it with a real world metaphor that allows them to get work done.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8151007596010663103-8480632292994666071?l=ryan-brubaker.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ryan-brubaker.blogspot.com/feeds/8480632292994666071/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8151007596010663103&amp;postID=8480632292994666071' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8151007596010663103/posts/default/8480632292994666071'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8151007596010663103/posts/default/8480632292994666071'/><link rel='alternate' type='text/html' href='http://ryan-brubaker.blogspot.com/2008/04/book-review-tog-on-software-design_13.html' title='Book Review:  Tog on Software Design'/><author><name>Ryan Brubaker</name><uri>http://www.blogger.com/profile/03141230570756777197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://farm1.static.flickr.com/68/219158810_71865d5a5e.jpg?v=0'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8151007596010663103.post-2563620459045592245</id><published>2008-04-12T18:26:00.001-07:00</published><updated>2008-04-12T19:36:53.393-07:00</updated><title type='text'>Learning Math</title><content type='html'>Inspired by this &lt;a href="http://steve.yegge.googlepages.com/math-every-day"&gt;post&lt;/a&gt; from Steve Yegge, I have decided to re-learn/learn as much math as possible.  I've always wanted to be better at math. One thing I've always regretted is how much time I wasted in my high school AP Calculus class, only to have to take the same exact course my first semester in college. Combine that will all of the other math knowledge I've lost over the years and I feel like I should knkow much more than I do.&lt;br /&gt;&lt;br /&gt;I'm starting from the very beginning, algebra, which should hopefully be more of a review than anything else. I ordered this &lt;a href="http://www.amazon.com/gp/product/0471530123"&gt;book&lt;/a&gt; from Amazon the other day and plan to read a little bit each day while I eat breakfast. I haven't really determined what the end-state of this goal is. Maybe it will be a life-long thing and I will end up a math genius :)&lt;br /&gt;&lt;br /&gt;It hasn't been necessary for me to know much high-level math in my development career. But I'm hoping that this project will enhance my problem solving skills and expand possible job opportunities. If nothing else, it will make me feel like I've made up for all of the knowledge I have lost over the years&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8151007596010663103-2563620459045592245?l=ryan-brubaker.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ryan-brubaker.blogspot.com/feeds/2563620459045592245/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8151007596010663103&amp;postID=2563620459045592245' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8151007596010663103/posts/default/2563620459045592245'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8151007596010663103/posts/default/2563620459045592245'/><link rel='alternate' type='text/html' href='http://ryan-brubaker.blogspot.com/2008/04/learning-math.html' title='Learning Math'/><author><name>Ryan Brubaker</name><uri>http://www.blogger.com/profile/03141230570756777197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://farm1.static.flickr.com/68/219158810_71865d5a5e.jpg?v=0'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8151007596010663103.post-3094007305167159271</id><published>2008-03-13T19:14:00.000-07:00</published><updated>2008-03-13T19:57:57.520-07:00</updated><title type='text'>Grader: Other GUI Thoughts</title><content type='html'>I listened to a very interesting &lt;a href="http://itc.conversationsnetwork.org/shows/detail3519.html"&gt;inteview&lt;/a&gt; on ITConversations.com the other week.  The interviewee was Bill Buxton, a principal researcher with Microsoft Research and author of &lt;a href="http://www.amazon.com/Sketching-User-Experiences-Interactive-Technologies/dp/0123740371/ref=pd_bbs_sr_1?ie=UTF8&amp;amp;s=books&amp;amp;qid=1205461156&amp;amp;sr=8-1"&gt;Sketching User Experiences&lt;/a&gt; (now on my Amazon wish-list).&lt;br /&gt;&lt;br /&gt;In the interview, Bill talks about using sketching, at the simplest level possible, to allow creative though and to get away from preconceived notions about what software has to look like.  A very interesting non-software example he provided was that George Lucas intertwined scenes of the chariot race from Ben-Hur with NASCAR wreck footage, to sketch out the pod-racing scene in the &lt;span style="font-style: italic;"&gt;The Phantom Menace.&lt;/span&gt;  This technique allowed him to sense how the scene would play out with little expense or time commitment.&lt;br /&gt;&lt;br /&gt;This interview struck a chord with me because I didn't really brainstorm too much on what the Grader GUI would look like.  The grading data is tabular so I immediately envisioned an entry table and implemented it that way, not really considering any other options.  Maybe a wizard-like entry system would have made for a better user experience (not likely :) ).  But I didn't even give myself the option of brainstorming and allowing some bad ideas help spurn some ideas that might have worked better.&lt;br /&gt;&lt;br /&gt;I'm also currently reading &lt;a href="http://www.amazon.com/Tog-Software-Design-Bruce-Tognazzini/dp/0201489171/ref=sr_1_1?ie=UTF8&amp;amp;s=books&amp;amp;qid=1205462015&amp;amp;sr=1-1"&gt;Tog On Software&lt;/a&gt;.  This book was written in 1996 and predicts a user-interface revolution happening ten years out.  Since the book is twelve years old, it's interesting to see how much of the book's predictions have yet to become reality.  One of Tog's predictions was that computer systems would have seamless voice recognition systems by now, which got me thinking about how well Grader could work with such a user interface.  A user speaking the words "2", "1", "2" "0", "Next Player", "0", "Next Play", etc... would likely be much easier than typing the scores and using the tab/arrow keys to move between cells.  I think I might look for some open source voice recognition software and see what I can do with it.  That sounds like a fun project and would probably be a good thing to learn for the future.&lt;br /&gt;&lt;br /&gt;Anyway, I think these two sources have made me think harder about user interface design and the process involved.  I especially took to heart Bill Buxton's interview as "sketching" is a general purpose technique that can be applied to all areas of creative thinking, not just UI design.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8151007596010663103-3094007305167159271?l=ryan-brubaker.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ryan-brubaker.blogspot.com/feeds/3094007305167159271/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8151007596010663103&amp;postID=3094007305167159271' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8151007596010663103/posts/default/3094007305167159271'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8151007596010663103/posts/default/3094007305167159271'/><link rel='alternate' type='text/html' href='http://ryan-brubaker.blogspot.com/2008/03/grader-other-gui-thoughts.html' title='Grader: Other GUI Thoughts'/><author><name>Ryan Brubaker</name><uri>http://www.blogger.com/profile/03141230570756777197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://farm1.static.flickr.com/68/219158810_71865d5a5e.jpg?v=0'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8151007596010663103.post-3721767856297039910</id><published>2008-03-13T18:58:00.000-07:00</published><updated>2008-03-13T19:14:11.652-07:00</updated><title type='text'>Grader: GUI</title><content type='html'>I find GUI programming to be enjoyable most of the time, with dashes of frustration thrown in for good measure. The fun part is the rapid feedback loop that exists as changes appear immediately on screen. It's also easy to bang out the code and get a lot accomplished in a short amount of time. The frustration comes in when my perfectionist tendencies inspire me to spend an inordinate amount of time trying to get every last detail exactly right, something that is quite difficult to do.&lt;br /&gt;&lt;br /&gt;I've worked with QT for quite a while now (5+ years give or take) and really enjoy working with it. Having started out my professional career writing in Java, I like the similarities between the QT framework and the Java Standard library. But like the Java Standard library, QT is quite large and can require a lot of digging to uncover functionality you know is likely to exist, but doesn't seem to exist where you expect it.&lt;br /&gt;&lt;br /&gt;Case in point...the Grader application uses a QTableWidget to allow users to enter player grades. After quickly getting the initial GUI up and running, I was surprised to see the cells of the table were not expanding to fit the entire widget, leaving empty white space along the bottom and right borders. I knew there had to be a way to correct this issue, but searched high and low through the QT documentation, unable to find it.&lt;br /&gt;&lt;br /&gt;I reached the point where I was ready to give up, subclass QTableWidget, and write some overly complex code that filled the widget, making sure each column and row was the same size, handling resizing issues, etc... But one last search resulted in me finally finding what I needed in the QHeaderViewClass, the class that provides the table's row/column headers. I probably skipped over the function at least once when skimming the documentation, making things even more frustrating. But at least I didn't spend any time rewriting functionality that already existed.&lt;br /&gt;&lt;br /&gt;I tackled two other issues in the first iteration of this project: fast data entry and displaying the grading data.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Fast Data Entry&lt;/span&gt;&lt;br /&gt;I wanted to make sure the user could complete data entry without having his hands leave the keyboard. I used QActions to provide shortcut keys to save a play (Ctrl-S) and output a report (Ctrl-W). These actions exist in a menu, which I didn't really want to add as I didn't even want to give the user the option of using the mouse. But the QActions didn't seem to be active unless the menu was available.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Displaying Grade Data&lt;/span&gt;&lt;br /&gt;My first attempt at this functionality was to display the entire grading table at the top of the window, using a QLabel with the text set to an html table. However, this resulted in a lot of screen clutter and looked really ugly. My next attempt was to just set the QLabel text to an html table that contained two columns, one for the grading scores and one for the grading descriptions based on the current selected column in the grade entry table. This worked well except that the table was always changing sizes and required the user to refocus when looking at the grade data. My brother actually complained about this problem when I gave him the first iteration to test out. I settled on using another QTableWidget which has the benefit of staying a fixed size, but has the disadvantage of looking as if it's editable even though I disabled any selection of the table cells (disabling the entire widget didn't look correct).&lt;br /&gt;&lt;br /&gt;Overall, I think the GUI is decent enough for something that I wanted to keep as simple as possible. There probably are still some sizing issues that could be handled better but at this point, I think that's running into the Law of Diminishing Returns.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8151007596010663103-3721767856297039910?l=ryan-brubaker.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ryan-brubaker.blogspot.com/feeds/3721767856297039910/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8151007596010663103&amp;postID=3721767856297039910' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8151007596010663103/posts/default/3721767856297039910'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8151007596010663103/posts/default/3721767856297039910'/><link rel='alternate' type='text/html' href='http://ryan-brubaker.blogspot.com/2008/03/grader-gui_13.html' title='Grader: GUI'/><author><name>Ryan Brubaker</name><uri>http://www.blogger.com/profile/03141230570756777197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://farm1.static.flickr.com/68/219158810_71865d5a5e.jpg?v=0'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8151007596010663103.post-8553985434892415147</id><published>2008-03-05T20:46:00.002-08:00</published><updated>2008-03-13T19:11:19.208-07:00</updated><title type='text'>Grader: KISS (Keep It Simple Stupid)</title><content type='html'>When my brother first asked me to write this program, he mentioned that someone had suggested to him he could solve his problem using Microsoft Access. I haven't used Access much before, but looked into it as a starting point. Creating the data tables was not a problem, but when I started looking at creating entry forms that spanned multiple tables, I decided it would probably just be easier for me to write an application from scratch.&lt;br /&gt;&lt;br /&gt;At this point, I figured my next decision should be to decide which database to code against.  I was picturing the ability to query on players, plays, years...quite a grand scheme. Taking a step back, I realized that my brother had asked for none of this functionality. All he wanted was a way to input grades for a single game and a summary report so he could evaluate each player's performance over the entire game. From this point on, I decided I was going to create the simplest program possible, focusing more on providing a solid user experience, and adding functionality only when it was requested. This decision resulted in the following decisions:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;No Database&lt;/span&gt;&lt;br /&gt;All of the data entered by the user is stored in memory and is lost once a game is completed (unless you count the report summary html file). This decision saved me quite a bit of time, and the more I thought about it, saving the data to such a history wouldn't provide much value at the high school level. Why would a coach care to save data for a player that is going to graduate in a year or two anyway?&lt;br /&gt;&lt;br /&gt;At startup, the user must select two files that they previously created (or use the default files created by my brother), which contain the data needed for grading.  The first file is just a text file that contains the list of players begin graded.  The other file is a comma-delimited file that contains the grading scores, grading categories and descriptions of each score for each category.  For example, a simple file might contain the following:&lt;br /&gt;&lt;blockquote&gt;Score,Catch,Yards After Catch&lt;br /&gt;1,Circus Catch,Ran for Touchdown&lt;br /&gt;0,Catch,No Yards&lt;br /&gt;-1,Drop,Lost Yardage&lt;br /&gt;&lt;/blockquote&gt;&lt;span style="font-weight: bold;"&gt;HTML Summary Reports&lt;/span&gt;&lt;br /&gt;I was originally going to provide the summary reports in a dialog window once a game was completed. I was also intending to provide the capability to print that report. Having written some printing code before, I knew this would turn out to be complicated. I was pretty happy with myself when I thought of the idea just to generate an html report file. Not only could the user just print the file from his web-browser, but the html format allows the user to put reports out on a web server where other coaches can view the data.&lt;br /&gt;&lt;br /&gt;The next two missing features are things I think I will eventually implement, even if my brother does not request them, as they would be generally useful.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;No Backspace&lt;/span&gt;&lt;br /&gt;At this point, the user cannot go back to a previous play after it has been submitted. This probably isn't a big deal as it shouldn't be too hard to enter the data error-free. But it might be nice to have that capability if a play is accidentally submitted before all the data has been entered.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;All or Nothing&lt;/span&gt;&lt;br /&gt;Grader currently doesn't support any concept of saving off partial results. So the user must enter a complete game at one sitting. I think it would be pretty useful to allow the user to enter complete game data over a series of application sessions. Of course, the usefulness would depend on how long it takes to enter an average game, information I will have to get from my brother. If it only takes 5-10 minutes, then maybe this isn't a worthwhile function to implement.&lt;br /&gt;&lt;br /&gt;I saved myself a lot of time and was able to deliver the product much faster than if I had decided to move forward on implementing any of the above features.  Instead, I was able to spend more time on solving the little problems faced when trying to make a GUI look just the way you want, which is the topic I will discuss in my next post.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8151007596010663103-8553985434892415147?l=ryan-brubaker.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ryan-brubaker.blogspot.com/feeds/8553985434892415147/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8151007596010663103&amp;postID=8553985434892415147' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8151007596010663103/posts/default/8553985434892415147'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8151007596010663103/posts/default/8553985434892415147'/><link rel='alternate' type='text/html' href='http://ryan-brubaker.blogspot.com/2008/03/grader-kiss-keep-it-simple-stupid_6826.html' title='Grader: KISS (Keep It Simple Stupid)'/><author><name>Ryan Brubaker</name><uri>http://www.blogger.com/profile/03141230570756777197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://farm1.static.flickr.com/68/219158810_71865d5a5e.jpg?v=0'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8151007596010663103.post-2439817017327581266</id><published>2008-03-05T19:30:00.000-08:00</published><updated>2008-03-05T20:09:30.560-08:00</updated><title type='text'>Grader:  What?/How?</title><content type='html'>&lt;span style="font-weight: bold;"&gt;What?&lt;/span&gt;&lt;br /&gt;Below is a screen-shot of the main window for the Grader application:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_4Wbzvp_sjnY/R89nDbtShsI/AAAAAAAAAAU/t534uTWWdec/s1600-h/Grader.png"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://1.bp.blogspot.com/_4Wbzvp_sjnY/R89nDbtShsI/AAAAAAAAAAU/t534uTWWdec/s400/Grader.png" alt="" id="BLOGGER_PHOTO_ID_5174467805546972866" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;The Grading Key displays the grade data for the current grading category, which is determined by the current selected cell in the lower grade-entry table.  The Grading Key provides a reference to the grading criteria as the user traverses through the grading table.&lt;br /&gt;&lt;br /&gt;Although it does not require an entry, the play field allows the user to enter a name for the current play.&lt;br /&gt;&lt;br /&gt;Other than that, the user simply enters grades for each player based on the grading criteria.  As I said in my previous post, the application is pretty simple.  The user submits the grades for a play by pressing Ctrl-S (or Grade-&gt;Save Play), at which point the grade-entry table is cleared and is ready for the next play.&lt;br /&gt;&lt;br /&gt;At any point, the user can press Ctrl-W (or Grade-&gt;Write Game Report) to signal the completion of a game.  At this point, the application outputs an html page that provides a grade summary for each player.  Ctrl-N (or File-&gt;New Game) allows the user to start a new game.&lt;br /&gt;&lt;br /&gt;The only other feature I provide at this point is the ability to pre-submit a list of plays when starting a new game.  My brother's team already has a software package that tracks game information.  This software allows them to export a list of plays which they can then just copy/paste into a dialog I provide.  This results in a different "mode" in which the play field is disabled and is populated with the current play name as the user iterates through the plays.  The Grader software then automatically generates the summary report after the last play has been submitted.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;How?&lt;/span&gt;&lt;br /&gt;I developed the program in C++, using the open-source version of QT (4.1) for the GUI.  At some point, I want to put the application up on SourceForge so it is generally available.  &lt;br /&gt;&lt;br /&gt;The player data is stored in a designated text file and just contains the names of the players that will be graded.  The grading data is stored in a designated csv file.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8151007596010663103-2439817017327581266?l=ryan-brubaker.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ryan-brubaker.blogspot.com/feeds/2439817017327581266/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8151007596010663103&amp;postID=2439817017327581266' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8151007596010663103/posts/default/2439817017327581266'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8151007596010663103/posts/default/2439817017327581266'/><link rel='alternate' type='text/html' href='http://ryan-brubaker.blogspot.com/2008/03/grader-whathow.html' title='Grader:  What?/How?'/><author><name>Ryan Brubaker</name><uri>http://www.blogger.com/profile/03141230570756777197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://farm1.static.flickr.com/68/219158810_71865d5a5e.jpg?v=0'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_4Wbzvp_sjnY/R89nDbtShsI/AAAAAAAAAAU/t534uTWWdec/s72-c/Grader.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8151007596010663103.post-1644937892160625060</id><published>2008-03-02T19:23:00.000-08:00</published><updated>2008-03-02T20:53:47.567-08:00</updated><title type='text'>New Product:  Grader</title><content type='html'>I've recently released my first independent product.  Calling it a product is a bit of a stretch as it is quite simple and isn't going to make me any money.  However, it was a fun little project and I'd like to write a series of posts on some of the ideas/decisions I made while implementing it.&lt;br /&gt;&lt;br /&gt;I created the application for my brother, who is an assistant football coach at the high school where he teaches.  One of his responsibilities during the season is to review the film for each game, grading his players in several categories for each play.  In the past, he completed this task manually, which obviously took quite a bit of time.  Thus, he asked if I could develop an application that would help speed up this process and generate summary information to help him better evaluate his players' performance.&lt;br /&gt;&lt;br /&gt;And so Grader was born (my creative juices were not flowing when I came up with the name).  I think it turned out pretty well and will hopefully make his job easier.  It also provides me with sample code to show any potential employers, although at this point it is probably too simple to make any kind of impression.  However, I'm sure my brother will require more functionality in the future.  I would also like to convert Grader to a web application using Ruby on Rails, as it would be an ideal project to dip my toes into learning that platform.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8151007596010663103-1644937892160625060?l=ryan-brubaker.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ryan-brubaker.blogspot.com/feeds/1644937892160625060/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8151007596010663103&amp;postID=1644937892160625060' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8151007596010663103/posts/default/1644937892160625060'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8151007596010663103/posts/default/1644937892160625060'/><link rel='alternate' type='text/html' href='http://ryan-brubaker.blogspot.com/2008/03/new-product-grader.html' title='New Product:  Grader'/><author><name>Ryan Brubaker</name><uri>http://www.blogger.com/profile/03141230570756777197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://farm1.static.flickr.com/68/219158810_71865d5a5e.jpg?v=0'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8151007596010663103.post-1189560991692586602</id><published>2007-12-29T19:58:00.000-08:00</published><updated>2007-12-30T19:02:00.375-08:00</updated><title type='text'>Is the Waterfall Method Just a Way to Procrastinate?</title><content type='html'>This weekend, I finished reading the very good book &lt;a href="http://www.amazon.com/Now-Habit-Overcoming-Procrastination-Guilt-Free/dp/1585425524/ref=pd_bbs_sr_1?ie=UTF8&amp;amp;s=books&amp;amp;qid=1198987247&amp;amp;sr=8-1"&gt;&lt;span style="font-style: italic;"&gt;The Now Habit: A Strategic Program for Overcoming Procrastination and Enjoying Guilt-Free Play&lt;/span&gt;&lt;/a&gt;, written by Neil Fiore.  I really wish I had read this book before reading &lt;a href="http://www.amazon.com/Getting-Things-Done-Stress-Free-Productivity/dp/0142000280/ref=pd_bbs_sr_1?ie=UTF8&amp;amp;s=books&amp;amp;qid=1198987288&amp;amp;sr=1-1"&gt;&lt;span style="font-style: italic;"&gt;Getting Things Done: The Art of Stress-Free Productivity&lt;/span&gt;&lt;/a&gt;.  The information in each book reinforces the other, but I think the information in  &lt;span style="font-style: italic;"&gt;The Now Habit &lt;/span&gt;would have provided a solid foundation to better understand the reasoning behind the strategies presented in &lt;span style="font-style: italic;"&gt;GTD&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;While reading &lt;span style="font-style: italic;"&gt;The Now Habit&lt;/span&gt;, it was interesting to reflect on the information in the book as it related to the philosophies behind different software development methodologies, specifically Waterfall-like methods versus Agile-like methods.  There were two main points of the book that stood out to me as related to software development.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Perfectionism&lt;/span&gt;&lt;br /&gt;Fiore suggests that creative work requires workers to eliminate desires for perfection and allow themselves the opportunity to make mistakes.  Perfectionism blocks workers from starting, making them afraid the initial steps they may be prepared to take aren't part of the "perfect" solution.  Now compare the two different methodologies:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Waterfall Method:  Requirements and design must be "perfect" before starting any development work.  Mistakes in earlier phases must be avoided, otherwise their cost explodes in later cycles.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Agile Method:  Development is undertaken with the understanding that initial ideas and design will need correction.  Test-driven development provides a safety-net so mistakes cost less and can be corrected without fear of breaking other parts of the system.  Working code is given preference to perfect code.&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-weight: bold;"&gt;Frequent Rewards&lt;/span&gt;&lt;br /&gt;Another suggestion Fiore makes is to plan work in short time intervals, giving yourself frequent rewards after completing discrete tasks needed to complete the project.  Rewards that exist too far out into the future will only encourage a person to engage in activities that provide a more immediate reward (e.g. watching television).  Comparing the methodologies once again:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Waterfall Method: At best, the development cycle is broken up into short iterations allowing for frequent feedback during that cycle.  However, such feedback rewards will only occur after the Requirements/Design phases.  Any rewarding feedback from customers on the working product can only occur when requirements changes are much more costly.&lt;/li&gt;&lt;li&gt;Agile Method: Short, frequent iterations reward the team with visible signs of progression.  A short development iteration will have a proposed completion date near enough in the future to provide motivation to make the shorter deadline.   The completion of each iteration builds momentum to move on and complete the next.&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8151007596010663103-1189560991692586602?l=ryan-brubaker.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ryan-brubaker.blogspot.com/feeds/1189560991692586602/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8151007596010663103&amp;postID=1189560991692586602' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8151007596010663103/posts/default/1189560991692586602'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8151007596010663103/posts/default/1189560991692586602'/><link rel='alternate' type='text/html' href='http://ryan-brubaker.blogspot.com/2007/12/is-waterfall-method-just-way-to.html' title='Is the Waterfall Method Just a Way to Procrastinate?'/><author><name>Ryan Brubaker</name><uri>http://www.blogger.com/profile/03141230570756777197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://farm1.static.flickr.com/68/219158810_71865d5a5e.jpg?v=0'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8151007596010663103.post-4145426639993721718</id><published>2007-12-10T20:21:00.000-08:00</published><updated>2007-12-10T21:23:32.326-08:00</updated><title type='text'>Should You Get A Master's Degree?</title><content type='html'>I'm currently a couple of semesters away from (hopefully) earning a Master's degree in Software Engineering.  It has been a long process, one that I'm anxious to see come to an end.  Working full time, while taking one class per semester, drags the process out much too long.&lt;br /&gt;&lt;br /&gt;If I could travel back in time, I'd tell my younger self two things:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Google's stock won't be overpriced at $100 when they have their IPO.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Don't waste your time getting a Master's degree.&lt;/li&gt;&lt;/ol&gt;Waste is probably too strong of a word as I don't feel the entire process has had no benefit.  I was able to take two programming classes I didn't take as an undergraduate (databases, compilers), and I've learned quite a bit working on my thesis project (more on that later).  Having a Master's degree may provide me the opportunity to teach later in my career, something I always thought I might enjoy.&lt;br /&gt;&lt;br /&gt;But overall, I feel that my time spent on course/project work could have been spent on things that would have improved my personal brand much better.  Looking back, I could have built a website using Ruby on Rails, contributed to an open-source project or spent more time improving my writing skills by blogging regularly (at this current moment, writing a blog post is a way to procrastinate on my project).  All of these activities would make me much more attractive to a potential employer than would having a Master's degree listed on a resume.&lt;br /&gt;&lt;br /&gt;My thesis project is an attempt to build an automated refactoring tool for C++ programs.  I knew going into the project that writing such a program was a fool's errand.  But it seemed interesting at the time and I knew the project would be approved.  Although I have quite a bit of work left, assuming I get as much functionality completed as I think I can, I'll be pretty pleased with the end result.  It will be more of a prototype than a complete program.  But one only has to do a Google search on parsing C++ to see why I think a prototype would be a pretty nice accomplishment.&lt;br /&gt;&lt;br /&gt;So to answer my question, no, you probably shouldn't get a Master's degree.  Instead spend your time learning/building something you find interesting, something that could impress a future employer or turn into your own business.&lt;br /&gt;&lt;br /&gt;If you ignore my advice and still want to get a Master's degree, I would then offer you this advice.  Get your degree immediately after you finish your undergraduate degree.  Don't start after you are in the work force and have to take more than two years to finish.  Also, wait until after you earn your degree to get married and have kids.  :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8151007596010663103-4145426639993721718?l=ryan-brubaker.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ryan-brubaker.blogspot.com/feeds/4145426639993721718/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8151007596010663103&amp;postID=4145426639993721718' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8151007596010663103/posts/default/4145426639993721718'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8151007596010663103/posts/default/4145426639993721718'/><link rel='alternate' type='text/html' href='http://ryan-brubaker.blogspot.com/2007/12/should-you-get-masters-degree.html' title='Should You Get A Master&apos;s Degree?'/><author><name>Ryan Brubaker</name><uri>http://www.blogger.com/profile/03141230570756777197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://farm1.static.flickr.com/68/219158810_71865d5a5e.jpg?v=0'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8151007596010663103.post-7202843101659736615</id><published>2007-10-08T19:43:00.000-07:00</published><updated>2007-10-08T20:24:32.049-07:00</updated><title type='text'>Problem Solved</title><content type='html'>In my last post, I talked about how include dependencies in our code base were causing lengthy build times.  Well thanks to this &lt;a href="http://www.codinghorror.com/blog/archives/000101.html"&gt;entry&lt;/a&gt; on &lt;span class="description"&gt;Jeff Atwood's blog, &lt;a href="http://www.codinghorror.com/blog/"&gt;Coding Horror&lt;/a&gt;, &lt;/span&gt;our problem was solved overnight.  Okay, our problem really isn't solved.  We still have include dependency issues, but they no longer affect our build times, thanks to &lt;a href="http://www.xoreax.com/main.htm"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;Incredibuild&lt;/span&gt;&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Jeff's mention of &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;Incredibuild&lt;/span&gt; has completely transformed my day at work.  A build that used to take over twenty-five minutes now takes about five minutes.  I no longer have to worry about switching tasks/contexts to fill twenty-five minute voids throughout my day.  I no longer have second thoughts about working in certain areas of the code, knowing that any small change would require a full rebuild.  &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;Refactoring&lt;/span&gt; can occur much faster and adds to the wave of motivation that has swept through our team since we began using this product.&lt;br /&gt;&lt;br /&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;Incredibuild&lt;/span&gt; is by far one of the best products I've ever worked with.  Not only does it work as intended, but it was incredibly easy to setup.  After reading Jeff's post, I downloaded the trial version and had the software working on two of my machines in less than fifteen minutes.  A quick "You have to check this out..." email to my fellow team-members resulted in us having a seven machine build network by the end of the day.  At that point, we started bugging management to approve purchasing the software and we are now on our way to becoming a much more productive team.&lt;br /&gt;&lt;br /&gt;I am still trying to eliminate some of the worst include-dependencies/coupling in our code.  But I no longer have to wait twenty-five minutes to get any feedback for my effort.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8151007596010663103-7202843101659736615?l=ryan-brubaker.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ryan-brubaker.blogspot.com/feeds/7202843101659736615/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8151007596010663103&amp;postID=7202843101659736615' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8151007596010663103/posts/default/7202843101659736615'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8151007596010663103/posts/default/7202843101659736615'/><link rel='alternate' type='text/html' href='http://ryan-brubaker.blogspot.com/2007/10/problem-solved.html' title='Problem Solved'/><author><name>Ryan Brubaker</name><uri>http://www.blogger.com/profile/03141230570756777197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://farm1.static.flickr.com/68/219158810_71865d5a5e.jpg?v=0'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8151007596010663103.post-7091662499514778154</id><published>2007-05-24T18:24:00.000-07:00</published><updated>2007-06-01T11:00:51.931-07:00</updated><title type='text'>The Case of the Horrible Include Dependencies</title><content type='html'>One of my favorite programming books is &lt;a href="http://www.amazon.com/Working-Effectively-Legacy-Robert-Martin/dp/0131177052/ref=pd_bbs_sr_1/002-9532766-8425652?ie=UTF8&amp;s=books&amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;qid=1180056350&amp;amp;sr=8-1"&gt;Working Effectively with Legacy Code&lt;/a&gt; written by Michael Feathers.  The book provides an arsenal of techniques to refactor legacy code and get it into a test harness.&lt;br /&gt;&lt;br /&gt;One specific situation the author addresses is testing a C++ class that has a large number of include dependencies.  Our product has many classes that suffer from this problem.  Our main library consists of over 600 source (.cpp) files and changes to a single header file often result in a large number of files having to be recompiled.  A full rebuild takes over thirty minutes and  is a productivity and motivation killer.  I've decided to attack this problem at its root and try to eliminate as many of the dependencies as possible.  At the very least, I will reduce the number of times a full-rebuild is necessary and will hopefully see a noticeable reduction in compilation time in the future.&lt;br /&gt;&lt;br /&gt;I started off by writing three Ruby scripts to collect data about the include dependencies for our product.  The first script traverses our source tree, inserting the following line into each header file after the header guard:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;#pragma message("including __FILE__")&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;The second script parses the compilation output, tabulating the number of times each header file is included and how many header files each .cpp file includes.&lt;br /&gt;&lt;br /&gt;The final script is the inverse of the first and removes all of the #pragma directives.&lt;br /&gt;&lt;br /&gt;The scripts were easy to write and they output the exact information I want, so I don't think a code analyzer tool would have saved me much time.  The main downside to my approach is that I have to do a full rebuild anytime I want to get all of the current data.  But since this project is something I'm doing on the side, rapid feedback isn't that important.  I can just kick off the build and come back to it when I have some down time.&lt;br /&gt;&lt;br /&gt;Since beginning this project two weeks ago, I have been able to significantly reduce the include dependencies on about half a dozen header files.  For example, one header file that was being included 455 times is now included only eighteen times.  That is quite a time saver the next time someone changes that header file.&lt;br /&gt;&lt;br /&gt;It's very motivating to see the include dependencies shrink after each small improvement I make.  In his book, Michael Feathers talks about situations where programmers feel the code the work on is beyond repair.  He points out that little changes here and there begin to add up, and you slowly realize the situation isn't as bad as it seems.  I think the small victories I've had so far point to continued success and will result in a much better code base and a much more productive team.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8151007596010663103-7091662499514778154?l=ryan-brubaker.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ryan-brubaker.blogspot.com/feeds/7091662499514778154/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8151007596010663103&amp;postID=7091662499514778154' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8151007596010663103/posts/default/7091662499514778154'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8151007596010663103/posts/default/7091662499514778154'/><link rel='alternate' type='text/html' href='http://ryan-brubaker.blogspot.com/2007/05/case-of-horrible-include-dependencies.html' title='The Case of the Horrible Include Dependencies'/><author><name>Ryan Brubaker</name><uri>http://www.blogger.com/profile/03141230570756777197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://farm1.static.flickr.com/68/219158810_71865d5a5e.jpg?v=0'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8151007596010663103.post-5038677321296839174</id><published>2007-04-22T08:52:00.000-07:00</published><updated>2007-04-22T09:59:15.888-07:00</updated><title type='text'>Great Experience with Unit Testing</title><content type='html'>This weekend I planned on stopping in at work for an hour or two to clean out some simple things on my &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;TODO&lt;/span&gt; list.  Unfortunately, upon opening my email, I was greeted with a message that our overnight build/run system had failed.  In particular, a unit test suite for a library that I had created had failed to pass.  The email also indicated that our application had significant changes in output from its previous run, something that wasn't expected for any changes that had been checked in the past day.&lt;br /&gt;&lt;br /&gt;The unit test failure struck me as quite odd since the code in that library hadn't changed in over a year.  I reran the test suite in my development environment, found the test that was failing and noticed that an output string I was expecting had changed.  This failure gave me an immediate clue to where the problem was introduced, and with great satisfaction, I was able to track down the problem in no time.&lt;br /&gt;&lt;br /&gt;As it turns out, my unit tests were not the only code expecting to see that same string value.  Another major library in our system, which controls output functionality, had failed due to the changes that had been made.  This library is much more complicated and does not yet have test coverage.&lt;br /&gt;&lt;br /&gt;What I found significant about this experience, was that my unit tests had caught an error in functionality outside of the library they were testing.  The library I wrote is pretty trivial, and I actually wrote the tests after writing the code (tut, tut) to try and introduce unit testing to my team.  So an exercise that I felt was pretty academic at the time, had a significant practical payoff.  Had I never written those tests, I would have spent much more time tracking down the change that had caused the problem.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold; font-style: italic;"&gt;Lesson learned&lt;/span&gt;:  Unit tests not only test the primary functionality being tested.  They can also test secondary functionality that the primary functionality depends on.  Even if a test seems pointlessly trivial, its worth writing as it may uncover problems in other areas of the system.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8151007596010663103-5038677321296839174?l=ryan-brubaker.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ryan-brubaker.blogspot.com/feeds/5038677321296839174/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=8151007596010663103&amp;postID=5038677321296839174' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8151007596010663103/posts/default/5038677321296839174'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8151007596010663103/posts/default/5038677321296839174'/><link rel='alternate' type='text/html' href='http://ryan-brubaker.blogspot.com/2007/04/great-experience-with-unit-testing.html' title='Great Experience with Unit Testing'/><author><name>Ryan Brubaker</name><uri>http://www.blogger.com/profile/03141230570756777197</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='21' src='http://farm1.static.flickr.com/68/219158810_71865d5a5e.jpg?v=0'/></author><thr:total>0</thr:total></entry></feed>
