Wednesday, November 19, 2014

Programmer, Thou Art a Fool

I just got burned.

My fault.  My responsibility.

The Lesson

I'm skipping right to the lesson that I learned from today:  Don't assume that you know what a control does.  Oh, and test thoroughly.

The Background

Let me give you some of the back story.  I was tasked with creating an internal website to help distribute some gift cards.  The site was meant to replace reams of paper that had been used in the past.  The requirements were simple: have an employee digitally "sign" something stating that they did indeed receive their gift card.

I had a nice, complicated solution that gave everyone the "personalized" feel that HR was desiring.  Due to other complications out of my control, I had to scale back to a much simpler site that simply asked for the person's employee number and last four digits of their SSN.  The work I did on the more complicated site was not a loss.  It did show us some issues with our Active Directory data and uncovered an error with a system that HR used.

I tested the site with four or five of my coworkers, and it worked as expected.  I presented it to HR, and they absolutely loved it.  The design was elegant and captured the holiday spirit.

The Launch

The day before the launch, HR gave me a new set of data.  I cleaned it up and got it into my database.  Everything was looking good.  We posted the link on HR's internal website, and they prepared packets for all the directors (60+ directors distributing to 2400+ employees.)

On the day of the launch, I had to attend a meeting.  When I got back to my desk, I had quite a few telephone calls, emails, and help tickets concerning the website. Oh, no, I thought.

The Problem

The error reports were from people whom had leading zeroes in either their employee numbers or the last-four digits of their SSN.  It didn't make any sense to me.  The range control was returning false when checking the value for validity.  It would not allow them to "sign" for their cards.

Why are the values being rejected?

What I Had Done

I had to make the site using ASP.NET Web Forms.  I would have preferred MVC, but I had a constraint that made me feel that web forms was the better way to go.  On the page, I used two validation controls per field.  I used the Required Field Validator and the Range Validator controls.  Both fields, employee number and last-four of SSN, were both numbers, so range validator made sense to me.  Both had the minimum value of 1 and the maximum value were 99999 and 9999 respectively.  Here's a sample tag:

<asp:RangeValidator ID="rvEmployeeNumber" runat="server" ControlToValidate="txtEmployeeNumber" Display="Dynamic" Text="*Must be Numeric" MinimumValue="1" MaximumValue="99999"></asp:RangeValidator>

Investigation

I pulled up the documentation (http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.rangevalidator(v=vs.100).aspx) and reviewed it.  I assumed* that the validation control would default to a number, since it is a range after all.  I located the type property, and saw that there were five types: String, Integer, Double, Date, and Currency.

*Never assume.

I used a test page to add five controls with a range validator of each type.  I didn't think that I needed to test a control with the type of Date, but it's best to check.  The three number types gave no issue.  The Date range validator broke as I expected, since the minimum and maximum values weren't even date values.  The String range validator recreated the error condition on the site.  We have a winner.

So, the default type for the Range Validator control is String.  To confirm, I removed the Type attribute, and output the default value to a label on the page.  The default type was, indeed, String.  D'oh!

What I Should Have Done

Since the employee number and the last four digits of the SSN aren't numbers meant to use with calculations, it does make sense to treat them as strings.  After all, I do store them as strings in the database for that very reason.

A more correct way to use the Range Validation control would have been this way:

 <asp:RangeValidator ID="rvEmployeeNumber" runat="server" ControlToValidate="txtEmployeeNumber" Display="Dynamic" Text="*Must be Numeric" Type="String" MinimumValue="00001" MaximumValue="99999"></asp:RangeValidator>

Do:

  • Set the Type attribute.  Even though the default is String, set it, so that others will know that you meant to use the type of String.
  • Add the leading zeroes.
    • Remember, it's a string, not a number.

I'm not certain what my biggest mistake was.  I thought of the input as a number, and gave no thought to the leading zeroes.  If I had written the client-side validation code, I would have used a regular expression that made certain that it was x characters in length and that each character was a digit (0 - 9).  To be truly thorough, I should have run all the employee numbers through the validation logic.

The Brightside

Even with that snafu, the feedback has been very positive, though I am still sore from my mistake.  It has made the card distribution go smoother, and it will help the Accounting department.  Hopefully, I have reduced paper waste, and cut down the time spent by HR and Accounting.

I don't consider myself arrogant, but I can be rather prideful of my code.  This was a good lesson in humility, and I did not enjoy it...

Friday, October 3, 2014

ASP.NET MVC: How to add a model with a dynamic list of child models?

Background

Okay, I admit that the title needs some work.  Let me slide on that.

I like visiting stackoverflow, and I have found it to be a great resource to help me solve the problems that I have encountered.  I believe strongly in doing research first for all my questions, and I usually find answers to them.  However, I have only posted two questions on the site.  Those earned me a tumbleweeds badge.  I ended up removing them, because I felt that they were too specific to a contract job that has come and gone.

But I digress.  I came across a question that interested me.  I like ASP.NET MVC a lot, but I've still got a lot to learn about it, so I didn't feel that I could answer the question outright.  However, I wanted to figure out how to answer it, and I've got multiple ideas.

Posting: Create record using Model List

In a nutshell, the poster wanted to have a view to create a new invoice and add a dynamic number of line items to the invoice all on one page.  I'm not going to address anything else.

Set Up

I pulled up my Sandbox project, added the two models (with some simplification), and added a controller with views.  I let Visual Studio do most of the work, since I wanted to spend time on the problem.

I'm using Visual Studio Premium 2013, and my web project is targeting .NET Framework 4.5.  I'm using Entity Framework and Code-First.

My Attempt

My very first reaction was to open up the Create,cshtml view and modify it, so that it would have a place to add the line items for the invoice, and add the functionality to dynamically add new line items in the client-side.  I thought that a table would be appropriate for the line items:

HTML:
    <table id="invoiceDetails" data-count="1">
        <thead>
            <tr>
                <th>Item Name</th><th>Quantity</th><th>Rate/Hour</th>
            </tr>
        </thead>
        <tbody id="invoiceDetails-Rows">
            <tr>
                <td><input type="text" name="Name" id="Name" /></td>
                <td><input type="number" name="Quantity" id="Quantity" /></td>
                <td><input type="number" name="Price" id="Price" /></td>
            </tr>
        </tbody>
        <tfoot>
            <tr>
                <td colspan="3">
                    <input type="button" id="add-row" value="Add Another Item Row" />
                </td>
            </tr>
        </tfoot>
    </table>

I contemplated automatically adding a new table row when the user clicks on any of the line item text boxes, but decided that I didn't want empty fields to be posted.

JavaScript:
$(document).ready(function () {
    $("#add-row").click(function () {
        var count = $("#invoiceDetails").attr("data-count");
        $("#invoiceDetails-Rows").append(createTableRow(count));
        $("#invoiceDetails").attr("data-count", count++); // increment the count
    });
});

function createTableRow(num) {
    var oTR = document.createElement("tr");
    var oTD = document.createElement("td");
    //<td><input type="text" name="Name" id="Name" /></td>
    var oTB = document.createElement("input");
    oTB.name = "Name"; oTB.id = "Name" + num;
    oTB.type = "text";
    oTD.appendChild(oTB);
    oTR.appendChild(oTD);
    //<td><input type="number" name="Quantity" id="Quantity" /></td>
    oTD = document.createElement("td");
    oTB = document.createElement("input");
    oTB.name = "Quantity"; oTB.id = "Quantity" + num;
    oTB.type = "number";
    oTD.appendChild(oTB);
    oTR.appendChild(oTD);
    //<td><input type="number" name="Price" id="Price" /></td>
    oTD = document.createElement("td");
    oTB = document.createElement("input");
    oTB.name = "Price"; oTB.id = "Price" + num;
    oTB.type = "number";
    oTD.appendChild(oTB);
    oTR.appendChild(oTD);

    return oTR;
}

The JavaScript could be improved, but it will work for now.  I kept the Name attribute of the new input fields the same as the original row, and only changed the Id attribute to append a number, hence keeping the Id attribute unique.  By keeping the Name attribute the same, the page will post back a comma-delimited string.  Example: Name="Labor,Parts,etc."

I tested the Create page, and the client-side worked as I wanted - after a minor correction.

Next, I moved on to the controller.

Initial Controller:
    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Create([Bind(Include = "InvoiceId,ClientId,Amount,CreationDate,DueDate,InvoiceNotes")] Invoice invoice)
    {
        if (ModelState.IsValid)
        {
            db.Invoices.Add(invoice);
            db.SaveChanges();
            return RedirectToAction("Index");
        }
        return View(invoice);
    }

It's your standard fare, nothing fancy.  I would like for it to use the power of model binding, since that means less code on my part and I'm leveraging the framework.

First attempt: Would a list of InvoiceDetails work?  I changed the method's signature to:
public ActionResult Create(
    [Bind(Include = "InvoiceId,ClientId,Amount,CreationDate,DueDate,InvoiceNotes")] Invoice invoice,
    [Bind(Include = "Name,Quantity,Price")] List<InvoiceDetail> invoiceDetails)
Result: invoiceDetails is null.  Dang it.

Second attempt: Can I get it to work for one line item?
public ActionResult Create(
    [Bind(Include = "InvoiceId,ClientId,Amount,CreationDate,DueDate,InvoiceNotes")] Invoice invoice,
    [Bind(Include = "Name,Quantity,Price")] invoiceDetail)
Result: This works.

Third attempt:  Hey!  What about params?  I can use that to pass in an unknown array of parameters to a method.  Would it work in this case?  Go for it!
public ActionResult Create(
    [Bind(Include = "InvoiceId,ClientId,Amount,CreationDate,DueDate,InvoiceNotes")] Invoice invoice,
    [Bind(Include = "Name,Quantity,Price")] params InvoiceDetail[] invoiceDetails)
Result: No compile errors which is always good.  Same result as the list. The variable is null.

What to do now?  As I mentioned before, if form fields share the same name, the values will be passed to the server as a comma-delimited string.  Let's see what I can do with that.  I commented out my previous changes to the method signature, so that we're back to the initial controller signature.  I've added the code to add the line items and a method to process the line items passed from the web page.

Controller:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(
    [Bind(Include = "InvoiceId,ClientId,Amount,CreationDate,DueDate,InvoiceNotes")] Invoice invoice
)
{
    if (ModelState.IsValid)
    {
        db.Invoices.Add(invoice);
        List<InvoiceDetail> invoiceDetails = new List<InvoiceDetail>(); 
        if (Request["Name"] != null && Request["Quantity"] != null && Request["Price"] != null)
        {
            invoiceDetails = GetInvoiceDetails(Request["Name"], 
                Request["Quantity"], Request["Price"]);
        }
        if (invoiceDetails.Count > 0)
        {
            foreach (var invoiceDetail in invoiceDetails)
            {
                invoiceDetail.InvoiceId = invoice.InvoiceId;
                db.InvoiceDetails.Add(invoiceDetail);
            }
        }
        db.SaveChanges();
        return RedirectToAction("Index");
    }
    return View(invoice);
}

Helper Method:
private List<InvoiceDetail> GetInvoiceDetails(string names, string quantities, string prices)
        {
            List<InvoiceDetail> details = new List<InvoiceDetail>();
            string[] Names = names.Split(',');
            string[] Quantities = quantities.Split(',');
            string[] Prices = prices.Split(',');
            // Not the best, but let's just go with the length on Names (for simplicity)
            // And we need to add validation - but not for the purpose of this post.
            for (int i = 0; i < Names.Length; i++)
            {
                InvoiceDetail detail = new InvoiceDetail() { Name = Names[i] };
                if (i < Quantities.Length) {
                    decimal qty = 0m;
                    decimal.TryParse(Quantities[i], out qty);
                    detail.Quantity = qty; 
                }
                if (i < Prices.Length) {
                    decimal price = 0m;
                    decimal.TryParse(Prices[i], out price);
                    detail.Price = price; 
                }
                details.Add(detail);
            }
            return details;
        }

Result:  This works.  With one page, I can create a new invoice with an unlimited number of line items (relatively unlimited... reasonably unlimited... subject to memory and other limitations...)

But is this the best method?  As it is written, it is not a good solution.  If there is an error with the invoice, all the line items will be lost.  Let's try to fix that.  We need to pass the line items back to the view, if the Invoice model is not valid, then we need to rebuild the line items in the view.

Changes to the Controller:
public ActionResult Create(
            [Bind(Include = "InvoiceId,ClientId,Amount,CreationDate,DueDate,InvoiceNotes")] Invoice invoice 
        )
        {
            List<InvoiceDetail> invoiceDetails = new List<InvoiceDetail>(); 
            if (Request["Name"] != null 
                && Request["Quantity"] != null && Request["Price"] != null)
            {
                invoiceDetails = GetInvoiceDetails(Request["Name"], 
                    Request["Quantity"], Request["Price"]);
            }
            if (ModelState.IsValid)
            {
                db.Invoices.Add(invoice);
                if (invoiceDetails.Count > 0)
                {
                    foreach (var invoiceDetail in invoiceDetails)
                    {
                        invoiceDetail.InvoiceId = invoice.InvoiceId;
                        db.InvoiceDetails.Add(invoiceDetail);
                    }
                }
                db.SaveChanges();
                return RedirectToAction("Index");
            }
            ViewBag.invoiceDetails = invoiceDetails; // pass this back to the view
            return View(invoice);
        }
I moved the declaration and initialization of the invoiceDetails list outside of the if block, and I added the list to the ViewBag.  If the Invoice model is not valid, then I'll send the list of line items back to the view.

Changes to the View:
@{
    List<Sandbox.Models.InvoiceDetail> invoiceDetails = ViewBag.invoiceDetails;
    var count = invoiceDetails != null ? invoiceDetails.Count : 1;
    //if (count <= 0) { count = 1; } // default value
    var name = "";
    var quantity = 0m;
    var price = 0m;
    if (invoiceDetails != null && invoiceDetails.Count > 0)
    {
        name = invoiceDetails[0].Name;
        quantity = invoiceDetails[0].Quantity;
        price = invoiceDetails[0].Price;
    }
}
<table id="invoiceDetails" data-count="@count">
    <thead>
        <tr>
            <th>Item Name</th><th>Quantity</th><th>Rate/Hour</th>
        </tr>
    </thead>
    <tbody id="invoiceDetails-Rows">
        <tr>
            <td><input type="text" name="Name" id="Name" value="@name" /></td>
            <td><input type="number" name="Quantity" id="Quantity" value="@quantity" /></td>
            <td><input type="number" name="Price" id="Price" value="@price" /></td>
        </tr>
        @if (invoiceDetails != null) { 
            for (int i = 1; i < invoiceDetails.Count; i++)
            {
                var num = i + 1;
                var nameid = "Name" + num.ToString();
                var qtyid = "Quantity" + num.ToString();
                var priceid = "Price" + num.ToString();
                name = invoiceDetails[i].Name;
                quantity = invoiceDetails[i].Quantity;
                price = invoiceDetails[i].Price;
        <tr>
            <td><input type="text" name="Name" id="@nameid" value="@name" /></td>
            <td><input type="number" name="Quantity" id="@qtyid" value="@quantity" /></td>
            <td><input type="number" name="Price" id="@priceid" value="@price" /></td>
        </tr>
            }
        }
    </tbody>
    <tfoot>
        <tr>
            <td colspan="3"><input type="button" id="add-row" value="Add Another Item Row" /></td>
        </tr>
    </tfoot>
</table>
It's ugly, but it works.  There's always room for improvement in this code.  I should probably move it into a partial view.  In the controller, perhaps I should have initialized the list to contain one instance of an InvoiceDetail, so I could avoid having to do null checks.  And the list goes on.

Is There a Better Way?

Oh, I am positive that there is.  Here's a few possibilities:

  • Use AJAX or SPA or flavor of the day.
    • Have the initial form show the Invoice model only with a "save" button.  Make a post request to a web service to save the invoice and return the invoice id.  Dynamically, add the fields for the line items with an "update" button that makes a call to a web service to add the line, and then add another set of fields.
  • Separate into two views.
    • Have one view for creating the Invoice.  Upon creating, the user is sent to a second view that displays the invoice and has a form for adding a line item.  After saving the line item, it is added to the invoice display, and the form is cleared for a new line item.  This continues until the user clicks a "Close" button or something similar that makes sense.


Monday, September 22, 2014

SignalR

SignalR

Okay, so I skipped ahead.  I looked at SignalR.  I felt compelled to do a search on Pluralsight for courses on SignalR and picked this one to watch:  Building a Game of Memory with SignalR.  But on the bright side, the project required the use of a singleton which is one of the design patterns that I need to know.  How's that for rationalization?

Overall, it was enjoyable.  I did my best to follow along with the code.  I've got a lower subscription, so no source code for me, but that's okay.  It's good to type it out and work out the missing parts on my own.  The instructor was creating an MVC 4 website.  I tried that at first, but I couldn't get SignalR to install.  NuGet needed to uninstall a JSON module, but the Web API depended on it.

I didn't want to get bogged down with troubleshooting the environment.  I started up a new project using .NET Framework 4.5.1.  I got SignalR 2.2 installed with no problems.  Once I started using it, there were issues.  This article helped me correct the differences between the older and newer versions of SignalR:  Upgrading SignalR 1.x Projects to version 2.

The Memory game matches people up to play a simple memory match game against each other using a Hub to communicate with one another.  When a player joins, they have to wait until another player joins, then a game can begin.  SignalR handles the communication between the client and the server.  It's pretty thrilling to see a card flip simultaneously on different browsers (I used Chrome and IE to test).

I'm not going to post large sections of the code here, but I will talk about some of the gotchas that I had to deal with.  In my opinion, the code belongs to the course, and subscribers have permission to re-type the code and learn how to use it.  Of course, higher subscriptions give access to the full source code which is useful.  The source code should have all the bugs worked out.  If you're not good at debugging, then you may want to pay for that higher subscription...

Upgrading to SignalR 2.2
This did cause a minor issue that was relatively easy to correct.  The correction was to use OWIN.  This is another thing to go on my learning list.  See the link above about upgrading SignalR.

Make Your Own Cards
I needed to make my own cards.  No big deal.  I whipped up some cards quickly in PhotoShop and added them to the project.

Handlebars
This issue was partly my fault, and partly an error in the code shown in the video.  I started a new page to do the final code.  The template failed.  I debugged it in Visual Studio, and it did seem to be giving me the information that I needed.  I switched to the client, and started outputting data to the console.  My game board was undefined!  What?  After a little bit of work, I found the issue.

Original call:
     $("#board").html(template(game));

This seemed correct, until I started looking at the model.  The template was expecting an array containing the cards.  The Game model did not contain a list of cards.  It did contain a property for the game board, Board.  Ah, we're closer.  The Board model is the one with the list of pieces.

Corrected call:
    $("#board").html(template(game.Board.Pieces));

Now, I was getting the correct data out to the console, however, the template was still not working.  This was probably due to not having a dependency added, or having something else out of order.  Again, I didn't want to spend time debugging this part, since I wanted to understand the whole point of the instruction which was SignalR.  This was easy enough to solve.  The template was small, and it was easy to write a simple function in JavaScript to do the exact same work that the handlebars templating engine was doing.  I'll go back later, and set things straight with handlesbars.  It will be good to know what I did wrong, but not right now.

Game Play
Okay, everything seemed to be working.  Only one player goes at a time, and... the player just keeps turning over cards.  Methods to handle the turns and matches don't seem to be firing.  Crikey.  Back to debugging.  A method on the back end was missing a bit of logic.  I kept the code intact, but added another "return true" where I thought appropriate.  Looking at the code, it had some redundancy.  Once I am certain that I understand the code, I intend to go back and clean it up.

It Works!

Huzzah!  It works during my simple testing using two different browsers on my desktop PC.  I still have a few issues to work out concerning the CSS, but it's doing what it needs to do.  I've got two different instances of the webpage in sync.  It's exciting.

Where to Next?
I'll break down the code, and seek to understand it.  I believe that I do, but I'll really know when I go to create a different web application using SignalR.  It'd be fun to make a version of Silent Death to play with a friend.  Silent Death is a turn-based strategy game using miniatures.  If it turned out well, I'd be more than happy to see if the game company that owns the game might be willing to let me release it to the public.  Based on the free time I have right now, all my time should be used on improving my programming skills first.

Tuesday, September 16, 2014

Software Development Game Plan

Software Development Game Plan

I am working in the Microsoft stack right now.  I've worked mostly with Microsoft technology, but I don't consider it to be the one and only option.  That would be limiting.

Before I started my first professional gig as a web designer, I learned the ins and outs of web pages by viewing their source and using Notepad to create my own web pages.  I still enjoy hammering out my own HTML, CSS, and JavaScript by hand.

In the past, I have developed web applications using PHP.  I've coded some basic console applications using C/C++ and have done a little bit of Java programming.  I've even written some ASM for a microcontroller.

C# is my Preferred Language, But That Could Change

I do like C#, but who knows what I'll be writing in the future.  My current plan does revolve around C# as my primary server-side language.  That seems like the wise decision, since I am most familiar with it in comparison to other languages that I've used.  HTML, CSS, and JavaScript are my go-to's for the client-side.

The plan:

  • Gain a deeper understanding of C# and the .NET Framework.
  • Grok design patterns in C#.
  • Have a solid understanding of SOLID.
  • Know ASP.NET MVC.
  • Get my pet project going, and implement it in multiple forms.
  • Work on learning other cool things:
    • AngularJS
    • SignalR
    • KendoUI
    • Onion Architecture
    • And the list goes on...

Gain a deeper understanding of C# and the .NET Framework.
I feel that I have been able to solve all the problems handed to me in the companies where I've worked.  But I'm starting to realize how much that I don't know.  I can blame working for small companies all I want, but that only goes so far.  The development was limited by me and I was alone.  I should have reached out to the community and saw that I need to learn more.

Grok design patterns in C#
I read/heard somewhere that the design patterns are often good habits that we, programmers, should adopt.  I get that.  Also, I see where it creates a common language to talk about potential solutions.  I've worked through some examples with mixed success.  I'll keep at it, until I grok them.

Have a solid understanding of SOLID
I need to understand SOLID and know how it can positively and negatively affect my code base.  I see the value in a lot of it, and I believe that it will help me improve my OOD skills.

Know ASP.NET MVC.
I am familiar enough with it, but need to complete a few more projects using that framework, so that I can be supremely comfortable with it.  I do like it a lot.  I've struggled with ASP.NET Web Forms over control issues.  With classic ASP, I had complete control over my web pages.  With Web Forms, the web controllers caused me no end of grief.  We've reached détente.  I am drawn to MVC, because it gives me back the control, and it seems to encourage OOD more than does Web Forms.

Get my pet project going, and implement it in multiple forms.
I've started working on a pet project.  I'd like to use the Onion Architecture to structure it.  I thought that it would help me design the project, so that I could spin off different versions of my project.  I intend to produce the following, but not limited to: ASP.NET MVC app, AngularJS app with a Web API back-end, WPF, and possibly a Windows Universal App.

Work on learning other cool thing...
Keep on learning.  Too many cool things to know, and not enough time.  Argh... Raspberry Pi, various microcontroller projects, NUI apps, IoT, robotics...  stop. Let me get a handle on the above stuff, before I keep going off on tangents.

Take care,
C.

Monday, September 15, 2014

Trials of Fixing a Software Developer

Hello, me.  I'm writing to you.  Yes, you.

I am going to fix myself.  What's wrong?  Oh, name it.

I'll probably post brain dumps concerning programming (web to be more specific), since I am working as a web developer, and want to remember a few things.  But, I should post other articles concerning what I am doing to fix other parts of myself.  Fix my body, fix my mind, fix my relationships, and all those fixes will bleed over into the facet that composes the programmer.

You'll find no earth-shattering writing or topics here.  Just ramblings whose only connecting thread is me.  Who's me?  I'm a self-taught programmer that got complacent.  I stayed at one company way too long.  I should have left, but it was so close to home, and the pay was good.  I paid the price.  Like I said, I got complacent.  I did my work, but I didn't stretch myself.  I did slowly improve my code, but still so many things to learn and do, and I wasn't doing that.  I was a lone coder just cruising along.

Egad!  Snap out of it, man!

What am I doing to fix myself?  Well, here's a list in random order.  Okay, not random, but not in any kind of real order...

- Fix my body
Yes, I am fat.  According to the BMI charts (that do not take into account body type!), I am obese.  Dang.  Okay, I am not as big as some, but still hefty.  At my heaviest, I was at 242 LB.  In October, 2013, I started changing my habits, since I finally realized that I needed to change.  I wasn't active, so I started simply by cutting my calories.  I lost about ten pounds, but my weight still fluctuated a lot.

In July of this year, by happenstance, I was listening to an old podcast of The Art of Manliness, and the host was interviewing Mark Sisson, the author of The Primal Blueprint, and owner of the site, MarksDailyApple.com.  What he talked about resonated with me.  I bought the book.

I'm down to 210 LB right now, and I haven't even incorporating all of the philosophy of TBP.  I decided to take measured steps and work on my eating habits first.  Then I started the sprint workouts, and will add in the rest as time goes by.  I feel good.  I still get frustrated, since I'm not losing the weight like I'd like, but change does take time.

- Fix my programming
I did go back to school in 2007 and get a Master's in Applied Computer Science.  It was interesting, but I still lack a grounding in a lot of basics that an undergraduate gets while working on a CS degree.

I'm working on fixing that.  I need to know design patterns well, and know SOLID.  There's still a ton of other things on my software developer to-do list, but this is a good start.

That's it for now.
I'll end this post right now.  It's a good start.  I should go back, reread, and edit, but no.  I'm done.  This is for me.  It'd be cool if other's found it useful.  But I need it to be useful to me.

Take care,
C.