# Monday, 24 October 2011

There isn’t enough hours in the day to not to.

After 13+ years of employment with Coconino County I’ve decided to move on.  It’s been a really tough decision yet at the same time an easy one. 

Comfort

Leaving behind 13 years of effort is hard. 

Leaving behind team members, colleagues and friends I’ve made is hard

Leaving behind something that has become very comfortable and familiar is hard.

Passion

Following my desire to be more involved in the technical day to day leadership and doing is easy.  My heart lies with the coding craft.  I love to code and I love the process of becoming better at it every day. 

When I graduated from College I didn’t think much about code as a craft

From WikiPedia:

In English, to describe something as a craft is to describe it as lying somewhere between an art (which relies on talent) and a science (which relies on knowledge).

I think most colleges miss the first part of that.  It’s a shame as I believe this is a huge key to great programmers.  Perhaps it’s too much to ask of them?  After all many in the class are still just trying to understand a For loop or Big O notation.

What I do know is you can’t teach passion and this is key to the artistic side.  It’s all about internal motivation.  I’ve always enjoyed coding and always saw it as a way of expressing myself.  But I was lacking something and I didn’t know it.

Body Of All Possible Knowledge - courtesy of http://maxme.org/old_site/bodyknow.htm

My Awakening

About three years back I bought a license to Safari Books Online.  It cost more than what we were budgeting yearly for literature but I was staring at a bookshelf full of out of date books.  There had to be a better way.  With so many books at my fingertips I went from reading one or two books a year to seven or eight with a few more that I perused through and a slew of development blogs.

Clean Code

Clean Code, by Uncle Bob was perhaps the most influential in changing the way I thought about code.  Along with many more books and blogs I found that code could be so much more than just code.  It is my creative outlet to solving other people’s problems and it can be elegant and poetic.  Yes, I’m getting all gushy. The simple answer is that I care deeply about honing my code craft and we need more who think and feel this way in our trade. 

My Code Passion

  • I love making life easier for people. Building software for this purpose is a passion; it's not just a job. I am constantly looking for ways to better myself, my code, my team and my product.
  • I believe that deleting code is a beautiful thing.
  • I want to leave code in better shape every time I touch it.
  • I believe that well written code can be read like a story line.
  • I believe in constantly looking to improve one-self and those around them.
  • I believe that craftsmanship isn't just for wood working.

A New Journey

Passion - Courtesy of http://maxme.org/old_site/Passion.htmFollowing my passion, this week, I began a new journey with NAU (my alma mater) as a Senior Developer.  I will be responsible for setting the architectural direction and development of several applications around the advising process for Freshman and Sophomore students before they declare their major.  The group I support also helps them land jobs!  I’m very excited about it and look forward to bringing my skills to the table as well as continuing to hone my coding craft.

Need a little more help stoking your fire?  Read The Passionate Programmer

We need a few more passionate programmers.  Won’t you join us?

Happy Coding! :-)

Posted 10.24.2011  #    Comments [0]  | 
# Monday, 17 January 2011

One can never know as much as a team knows. Learning from others is a wonderful team and individual trait.

Background

About a year ago our team was working on an intranet project. As the lead developer and I discussed the features needed, we decided to handle some tasks on the front end with jQuery. Neither one of us had much experience with jQuery and we had a tight deadline to meet. 

The Bad & The Ugly

Since we were really under the gun we split up the work and I tackled the client side jQuery. Warning – Avert eyes now if you wish not to see be subjected to ugly code!

var Editor1 = '#Editor1';
var Editor1CountLimit = 5000
var Editor1InfoArea = '#Info';

var WhyThisStratArea = '#txtVchWhyThisStrategicArea';
var WhyThisStratAreaCountLimit = 500;
var WhyThisStratAreaInfoArea = '#txtVchWhyThisStrategicAreaInfo';

var ProgramDescriptionArea = '#txtVchProgramDescription';
var ProgramDescriptionAreaCountLimit = 1000;
var ProgramDescriptionAreaInfoArea = '#txtVchProgramDescriptionInfo';

var Activity = '#txtVchActivity';
var ActivityCountLimit = 3000;
var ActivityInfoArea = '#txtVchActivityInfo';

var OtherInfo = '#txtVchOtherInfo';
var OtherInfoCountLimit = 1000;
var OtherInfoArea = '#txtVchOtherInfoInfo';

var OutcomeMandated = '#txtvchOutcomeMandated';
var OutcomeMandatedCountLimit = 1000;
var OutcomeMandatedArea = '#txtvchOutcomeMandatedInfo';

var ServiceLevelMandated = '#txtVchServiceLevelMandated';
var ServiceLevelMandatedCountLimit = 1000;
var ServiceLevelMandatedArea = '#txtVchServiceLevelMandatedInfo';

var ChangeInLevelofService = '#txtvchChangeInLevelofService';
var ChangeInLevelofServiceCountLimit = 1000;
var ChangeInLevelofServiceArea = '#txtvchChangeInLevelofServiceInfo';


$(document).ready(function() {

    ChangeTextOnKeyUp(Editor1, Editor1CountLimit, Editor1InfoArea);

    //change the length when typed in.
    TrackKeyStrokesForTextArea(WhyThisStratArea, WhyThisStratAreaCountLimit, WhyThisStratAreaInfoArea);
    TrackKeyStrokesForTextArea(ProgramDescriptionArea, ProgramDescriptionAreaCountLimit, ProgramDescriptionAreaInfoArea);
    TrackKeyStrokesForTextArea(Activity, ActivityCountLimit, ActivityInfoArea);
    TrackKeyStrokesForTextArea(OtherInfo, OtherInfoCountLimit, OtherInfoArea);
    TrackKeyStrokesForTextArea(OutcomeMandated, OutcomeMandatedCountLimit, OutcomeMandatedArea);
    TrackKeyStrokesForTextArea(ServiceLevelMandated, ServiceLevelMandatedCountLimit, ServiceLevelMandatedArea);
    TrackKeyStrokesForTextArea(ChangeInLevelofService, ChangeInLevelofServiceCountLimit, ChangeInLevelofServiceArea);

    //setup the initial value for a text area...
    $(WhyThisStratAreaInfoArea).html($(WhyThisStratArea).val().length + ' Characters Used');
    $(ProgramDescriptionAreaInfoArea).html($(ProgramDescriptionArea).val().length + ' Characters Used');
    $(ActivityInfoArea).html($(Activity).val().length + ' Characters Used');
    $(OtherInfoArea).html($(OtherInfo).val().length + ' Characters Used');
    $(OutcomeMandatedArea).html($(OutcomeMandated).val().length + ' Characters Used');
    $(ServiceLevelMandatedArea).html($(ServiceLevelMandated).val().length + ' Characters Used');
    $(ChangeInLevelofServiceArea).html($(ChangeInLevelofService).val().length + ' Characters Used');
});

function ChangeTextOnKeyUp(ctl, limit, info) {

    var editor = $(ctl).contents().find('iframe').eq(1);

    $(editor).load(function() {

        //initial load, set value....
        var txt = $(this).contents().find('body').text();
        $(info).html(txt.length + ' Characters Used');

        //watch cut and paste
        $(this).contents().find('body').bind('cut paste', function(e) {
            var el = $(this);
            setTimeout(function() {
                //use a delay to wait for the text to update....
                var txt = $(el).text();
                if (txt.length > limit) {
                    $(info).html(txt.length + ' Characters Used').css("color", "red");
                }
                else {
                    $(info).html(txt.length + ' Characters Used').css("color", "");
                }
            }, 150);
        });

        //watch key up
        $(this).contents().keyup(function() {

            var txt = $(this).contents().find('body').text();

            if (txt.length > limit) {
                $(info).html(txt.length + ' Characters Used').css("color", "red");
            }
            else {
                $(info).html(txt.length + ' Characters Used').css("color", "");
            }
        });

    });

}

function TrackKeyStrokesForTextArea(ctl, limit, info) {
    $(ctl).keyup(function() {
        var txt = $(ctl).val();
        if (txt.length > limit)
            $(info).html(txt.length + ' Characters Used').css("color", "red");
        else
            $(info).html(txt.length + ' Characters Used').css("color", "");
    });

    $(ctl).bind('cut paste', function(e) {
        var el = $(this);
        setTimeout(function() {

            var txt = $(el).val();
            if (txt.length > limit) {
                $(info).html(txt.length + ' Characters Used').css("color", "red");
            }
            else {
                $(info).html(txt.length + ' Characters Used').css("color", "");
            }
        }, 150);
    });
}

function ValidateEditor1Length(source, args) {
    var editor = $(Editor1).contents().find('iframe').eq(1);
    var txt = editor.contents().find('body').text();
    var isValid = txt.length > 0 && txt.length <= Editor1CountLimit;
    args.IsValid = isValid;
}

function ValidateWhyThisStratAreaLength(source, args) {
    var txt = $(WhyThisStratArea).val();
    var isValid = txt.length > 0 && txt.length <= WhyThisStratAreaCountLimit;
    args.IsValid = isValid;
    /*if (!isValid)
        Spellcheck();*/
        
}

function ValidateProgramDescriptionLength(source, args) {
    var txt = $(ProgramDescriptionArea).val();
    var isValid = txt.length > 0 && txt.length <= ProgramDescriptionAreaCountLimit;
    args.IsValid = isValid;
}

function ValidateActivityLength(source, args) {
    var txt = $(Activity).val();
    var isValid = txt.length > 0 && txt.length <= ActivityCountLimit;
    args.IsValid = isValid;
}
function ValidateOtherInfoLength(source, args) {
    var txt = $(OtherInfo).val();
    var isValid = txt.length > 0 && txt.length <= OtherInfoCountLimit;
    args.IsValid = isValid;
}
function ValidateOutcomeMandatedLength(source, args) {
    var txt = $(OutcomeMandated).val();
    var isValid = txt.length > 0 && txt.length <= OutcomeMandatedCountLimit;
    args.IsValid = isValid;
}
function ValidateServiceLevelMandatedLength(source, args) {
    var txt = $(ServiceLevelMandated).val();
    var isValid = txt.length > 0 && txt.length <= ServiceLevelMandatedCountLimit;
    args.IsValid = isValid;
}
function ValidateChangeInLevelofServiceLength(source, args) {
    var txt = $(ChangeInLevelofService).val();
    var isValid = txt.length > 0 && txt.length <= ChangeInLevelofServiceCountLimit;
    args.IsValid = isValid;
}

Ugly!  Oh ya, we’ve all seen it and we’ve all most assuredly done it at least once. :-)

TheBadAndUgly

So what is all this code doing? Basically only three things. It’s setting and tracking the max length allowed in a text area, updating the number of characters typed and showing a message/validating when an entry goes over it’s maximum length.

Why do all this when we can do this with validator controls? We wanted the UI to be more responsive and interactive for the users. We wanted the number of characters along with a warning to the user when they go over the limit before they try to save their work.

Now, I could give every excuse for this horrible looking code. We’ve all been here before.  Not enough time to do it right but we have to get it out the door none-the-less.  I knew the code was bad and could be improved upon.  Still, the code is ugly.

The Good

We had a new team member join our team about four months ago and we happened to be working on this project again.  His jQuery skills brought to bear on this project was just what we needed.

To fix MY monstrosity he created hidden fields tied to the text areas and got rid of the setup variables.  It may sound like we’re swapping one mess for another but it helped greatly in reducing the code needed as well as improved the readability and flow.

<asp:TextBox ID="txtWhyThisStrategicArea" cssClass="spellcheck" runat="server" TextMode="MultiLine"></asp:TextBox>
<input runat="server" type="hidden"  id="txtWhyThisStrategicAreaMaxLength" value="500" />
<input runat="server" type="hidden"  id="txtWhyThisStrategicAreaRequired" value="true" />
// Text field character counter
$('#txtProgramName, #txtWhyThisStrategicArea, #txtContactPerson).each(function () {

    var length = $(this).val().length;
    var limit = $('#' + $(this).attr('id') + 'MaxLength').val();
    var maxInfoArea = $('#' + $(this).attr('id') + 'MaxArea');
    var displayText = ' of ' + limit + '  Characters Used.';

    //set up the initial display
    if (length > limit)
        $(maxInfoArea).html(length + displayText).addClass("warning");
    else
        $(maxInfoArea).html(length + displayText).removeClass("warning");

    //hook the keyup
    $(this).keyup(function () {
        var length = $(this).val().length
        if (length > limit)
            $(maxInfoArea).html(length + displayText).addClass("warning");
        else
            $(maxInfoArea).html(length + displayText).removeClass("warning");
    });

});

169 lines of code down to 24.  Deleting code, it’s a beautiful thing!

Knowledge, Learning and Sharing – Our Biggest Asset. 

Knowledge and learning are perhaps our biggest asset but are we open to receiving it and sharing it?

I am convinced our attitude in this arena is a huge factor of our success. We never think it’s a bad thing to go get lessons from someone better than us for other activities like learning an instrument.  Why wouldn’t we think the same way in our profession. Do we believe it will make us look weak or expose us in such a way that would jeopardize our job? It’s more dangerous to think this way than it is to actively engage with those better than ourselves to improve.

Stock Photo

Learning from others should be embraced by all.  When we close off our mind to being teachable we will suffer and so will the team.  Contributions from all team members is valuable.  Everyone from the Janitor to the CEO can provide valuable insight.  The more an individual and team thinks and acts like this the more likely they are to grow stronger mentally, improve their technical and social skills, and ultimately help produce better solutions for everyone. 

Happy Coding!

Posted 01.17.2011  #    Comments [2]  | 
# Saturday, 06 March 2010

It’s been almost two years since StackOverflow went live.  The brain child of Jeff Atwood and Joel Spolsky, StackOverflow has fast become the top programming Q & A site and it’s free!

The site is incredibly easy to use, their reputation engine is perfect for ensuring you know you are getting a good or bad answer since the entire community rates both the question and answers.  Answers come fast and the best one is identified very fast as well.  It’s like having a top gun coder in your back pocket for any topic you can think of!  We can’t know everything (unless your Jon Skeet). 

I have found SO to be a great resource for finding answers.  I also frequent it to help answer questions for others.

Happy Coding!

Posted 03.06.2010  #    Comments [0]  | 
# Friday, 05 March 2010

Want to learn ASP.Net MVC?  Perhaps you already started learning it.  I decided to take a side project of mine that I started in Web Forms and completely start over with .Net MVC.  I wanted to document what I did and the resources I found in the hopes that it may help you.  I still have much to learn and master with .Net MVC but so far I am impressed and am happy I decided to branch out and learn something new.  It has made me a better developer and a more well informed developer.  Both good things!

Not sure what ASP.Net MVC is?  Check out this intro video and this overview and then hurry on back.

How I started:

ASP.Net MVC Tutorials and many, many blog posts from Scott Guthrie, Phil Haack, Rob Conery, Jimmy Bogard, Jeffrey Palermo, Eric Hexter, Steven Sanderson, Stephen Walther and these are just the ones I remember.

Books:

I started with ASP.Net MVC In Action and quickly realized that many of it’s topic were over my head.  So I put it down and read ASP.Net MVC Framework Unleashed and Pro ASP.Net MVC Framework and then went back to MVC In Action. 

TIP #1 - When I am learning a new technology I tend to do the examples in the book from scratch.  It takes longer than just downloading their sample code but it helps me absorb it more. 

TIP #2 – Almost all the material I read on ASP.Net MVC touch on or go into detail on Unit Testing, Test Driven Development, Dependency Injection, Inversion Of Control and many other design principles.  If you are not sure what these are you might want to research them a little bit.  The books I recommend do give overviews of these.  One of MVC’s main design goals is for giving control of the application back to the developer and ease of testing.  If you find this even the least bit interesting then keep going!

Samples/Tutorials:

ASP.Net MVC Tutorials – I watched these to get a feel for MVC.  They have a lot of video’s and sample code you can run through.  They did a great job of covering the basics.  Stay here a while, fire up your IDE and peck away on the keyboard with these tutorials.

Nerd Dinner – Perhaps a cult classic or a right of passage?  I for the most part skipped it…. Oooppsss.  No wonder I struggled so hard with MVC in the beginning.  Just kidding.    It was one of the first books and sample apps out.  I skipped it only because I didn’t have it in my Safari Books Online.  I did however take advantage of their free chapter and source code.

Rob Conery – Rob Conery published a set of video’s documenting the development of an eCommerce storefront called MVC StoreFront.  I watched these video’s carefully and read his code carefully.  He then renamed the project to Kona and added a few more screencasts.  Check these out.  I poured through his code to see some of the possibilities that MVC has.  I still don’t understand some of it but Rob’s a much smarter guy than I am. :-)

Starter kits – Check out their Northwind MVC project, period.

Tip #3 – Check out the ASP.Net MVC Tutorials and the MVC storefront screencasts at least! 

Cheat sheets – Elijah Manor published several cheat sheets on MVC that are great to put on your wall or at least keep close at hand while you are learning MVC.

50 ASP.Net MVC Tips – Stephen Walther, author of ASP.Net MVC Framework Unleashed published these nice tips on his blog.

MVC Contrib Project – A bit more advanced but the wizards over at Headspring created this little open source gem.  The ASP.Net MVC In Action’s sample project uses MVC Contrib.  The project is great and I am still digesting a lot of what is in the project.  I especially dig the TestHelper library.  It just makes my job of testing routes a breeze.

I mentioned I used a side project to learn ASP.Net MVC.  I know now that had I not done that I would still be sitting here thinking about learning it.  Why?  I found many things I took for granted with Web Forms were gone in ASP.Net MVC.  Viewstate for example.  I had certainly grown accustom to it.  Another gotcha for me was filling a dropdown list the right way (not directly in the controller).  I truly did have some frustrating points with ASP.Net MVC but only because I had to retrain myself to how the internet really works (Web Forms took care of this for me).  I really am better for it now.  

Tip #4 – Take a tangible project and do it in ASP.Net MVC.  Stick with it.  It is very different from Web Forms if this is where you are coming from.  Please read my post on Confessions of a Web Form Guy Learning ASP.Net MVC if you want a little insight into some of the "aha" moments I had. 

MVC is moving fast, as of this writing they are already on of MVC2 RC2.  A lot of new features are coming our way that make MVC that much sweeter. 

I hope this helps you in your journey!  If you know of some other good resources for ASP.Net MVC please comment on it.

Happy Coding!

Posted 03.05.2010  #    Comments [0]  | 
# Friday, 26 February 2010

I was not asked nor am I being paid for this post.  I just want to let other’s know about a service that I have found to be incredibly valuable to improving my code craft.

I knew about Safari Books Online for a couple of years before I decided to give it a shot.  I had trepidation at first due to the price point and wasn’t sure if I would really use it.  I averaged a few books a year so it didn’t seem worth it.  Nine months have passed since I took it for a spin and I am smitten with Safari and here’s why.

  1. Thousands of Books at your fingertips

Nearly 11,000 as of this writing.  The publisher list is large and I have only a couple of a cases where a book I wanted was not in the library.  They are adding titles every week it seems like.  For the most part, I feel like a kid in a candy store seeing all the books that are available.  I have 47 books in my bookshelf at this time and have accessed many more.

  1. Features, features, features

I have a habit of marking up, highlighting and dog earring the books I read.  While this is great it’s still not the easiest to find that note or dog ear I made that had that particular topic I wanted to re-read or apply.  Enter the world of Safari Books Online.  I can add bookmarks and notes to my books and easily access them.  I can email and even download books/chapters if I want/need to.  The books have hyperlinked references & related content.  The searching ability offers a great way to find topics of particular interest in different books if you are wanting to learn/read on a particular topic rather than read an entire book.

  1. Accessibility

At first I had a hard time reading a book electronically.  It felt awkward and I wanted the physical book.  That didn’t take long to get over.  The ability to pick up where I left off on a book anywhere I have access to the internet is unbeatable.  I have used Safari at home, at the office and recently Safari added mobile devices to the list.  I experimented with the mobile device for my BlackBerry and found it to be pleasing.  Naturally, a larger media device would be preferable but if you don’t have one the small BlackBerry screen and Safari’s layout make it very readable.

  1. No Worries = More Reading = More Learning

Should I buy this?  I fought this question over and over again before Safari.  Now my battle is which book will I read next.  In the nine months or so of owning Safari I have read through six books and will finish my seventh soon.  I figure I will get another three in before the year is over.  That’s 10 books from cover to cover in a year. That doesn’t include the others I have browsed through, read a chapter here, looked at a code sample there.  I would easily say this is the most I have read in a year.  All thanks to the simple fact that I don’t have to shell out money every time I think I want to read a book.  There’s even been a couple of books on Safari that I started to read and then dropped after realizing I didn’t care for them.  Had I purchased the book outright I would have been disappointed.  Instead I feel liberated and empowered.

  1. Cost

Safari Offers two versions of it’s service for individuals.  The 10-slot bookshelf costs just over $250 a year and the unlimited access version weighs in at just under $475 as of this writing.  If you are like me the unlimited access version starts to feel a little costly but that’s the version I bought and have found it to be well worth to cost.

I have 47 books in my bookshelf currently.  If I bought each one at an average of $25 I would have shelled out nearly $1,200.  Let’s be honest though, I would not have bought all those books.  Instead let’s just say that I would have bought 10 of them since that’s what I believe I will have read completely through using Safari in a year.  I still would spend $250.  At the least, I have equaled the value of the 10-slot bookshelf.  It may be hard to find technology books for $25 average unless you buy used as much as possible.  If the average book cost $40 we are fast approaching the value of the unlimited bookshelf and don’t forget the shipping costs.

Now throw in the added features you get with Safari and I thinks it’s clear that Safari is a great tool well worth the price for any developer.

I have one nagging thought about Safari but it has nothing to do with it’s service.  I have no idea how author’s are compensated for book usage.  I hope it’s a good deal for them but I imagine it’s still not as good as buying a book outright.  Still, there’s a good chance I wouldn’t have bought the book in the first place so perhaps Safari is helping to increase their revenue. :-)

Happy coding, err… reading!

Posted 02.26.2010  #    Comments [0]  |