What are your Daily Hits?

In the book My Job Went to India (And All I Got was this Lousy Book), Chad Fowler writes about what developers can do to improve their craft.  There are 52 tips, and they range from positive gems like Be the Worst (#8) to other positive gems, like: You’ve already Lost Your Job (#43). 

All kidding aside; this book is chock full of tips meant to help us improve our craft, and it’s even gotten a facelift as The Passionate Programmer.

One such tip is The Daily Hit (#20):

As with most tasks that are worth doing, becoming a standout performer is more likely with some specific and intentional work.  When was the last time you went above and beyond the call of duty? Did your manager know about it?  How can you increase the visible instances of this behavior?

James McMurry, a co-worker who’s also a good friend, told me very early in both our careers about a system he had worked up to make sure he was doing a good job. It struck me as being remarkably insightful given his level of experience (maybe it’s a hint he got from his parents), and I use it to this day.  Without warning his manager, he started tracking daily hitsHis goal was to, each day, have some kind of outstanding accomplishment to report to his manager — some idea he had thought of or implemented that would make his department better.

Simply setting a goal (daily, weekly, or whatever you’re capable of) and tracking this type of accomplishment can radically change your behavior.  When you start to search for outstanding accomplishments, you naturally go through the process of evaluating and prioritizing your activities based on the business value of what you might work on.

Why daily?

Tracking hits at a reasonably high frequency will ensure that you don’t get stuck: If you’re supposed to produce a high per day, you can’t spend two weeks crafting the perfect task.

I’m guilty of trying to be perfect. When I sit down to implement code; I (very often) try to get the code working perfectly. I spend a lot of time fully implementing when I should be prototyping.  the daily hit is a way of prototyping instead of fully implementing a feature, and sometimes I wish this book came with a rubber mallet to beat me with when I forget its lessons. Do you keep track of your daily hits?

If you don’t know what your daily hits are, neither do your manager.

 

Bad Actors in your Code

During my time in the Army, I used to get rankled when I’d see Television or Movies portray soldiers.  Generally, they’d get something wrong; and usually, it wasn’t just something minor.  It didn’t usually bug me when it was clear they weren’t trying to get it right. It bothered the hell out of me when it looked like they tried to get it right, but failed in some way that could have been prevented if they would have spent $1000 and hired a military consultant for a day.

The same thing bothers me about naming in source code.  Well, not the military part, but the ‘bad acting’ part. Names that don’t do what they say they do, or names that don’t even mean what you think they mean.  These ‘gems’ can slow down development time and reduce the level of understanding from all team members. For every new person you bring on to the team, that’s another person that has to make the mental leap from what a word means to what it is used for in your application.

 

Here are a few bad names I’ve seen in source code recently, and they are all from commercial applications.

timeout  – Describes how old a file should be before it’s deleted

narrative – Refers to the ‘help’ field for a form or page.

nounset – where noun can be anything, like ‘bird’ or ‘category’ or ’email’ or ‘password’. The suffix ‘set’ is added to it to denote a ‘set’ of that noun. In some cases, it refers to a ‘template’.

That’s just a few; and there are more out there, probably in the application you work on.

What’s so wrong with bad naming?

Let’s say you have a new developer come onto your team. it doesn’t matter if this developer is just out of college or if he’s a 10 year veteran. He now has to learn what those words mean.  He then has to apply those names to the intent behind them, and daily has to remind himself of what they mean, since they aren’t used in their normal context.

Here are some possible solutions for the ‘naming problem’.

timeout  – fileAgeInMinutes

narrative – instructions

nounset – nouns, or nounTemplate (This can also rely on the fact that in databases, a table is considered a collection of things; adding ‘set’ is redundant).

It’s easy to change the name of something before it’s in use; but what happens when it’s in use?

Great question — one I don’t have a definitive answer to.

If you’re king of your particular hill, then you decree that the name is changed.

If you aren’t, then all you can do is raise awareness and push to having it changed in all parts of the application in the main branch, and make it an architecutural change for the next relief. It’s important to keep documentation up to date (preferably in source code) so that new developers know that in the ‘old’ version, it was called something different.

What are your thoughts? How do you deal with ‘bad names’ in Source Code?

 

Refactor Your Wetware: Review

Pragmatic thinking and learning coverI’m addicted to books. I like to read them, I like to collect them, I like to immerse myself and bathe in them.

Ok, strike that last part.

Generally I buy programming books, and since this book was sitting in the programming section, I figured I was safe.

 

Refactor Your Wetware: Pragmatic Thinking and Learning is a book that teaches you something within the first few pages and doesn’t stop until the book is closed.  It goes in depth into our methods and modes of learning and expounds upon them not only with well written ancedotes, but with research and practical examples.  From topics such as the Dreyfus Model to how our Right brain can solve problems when we’re not thinking about them, Refactor Your Wetware covers it.

Perhaps the biggest thing I learned from this book was the effect that our Right brain has on our problem solving ability.  When he couldn’t solve a particular problem, Benjamin Franklin would take a nap with ball bearings in his hand; and once he fell into a deep sleep the ball bearings would  fall and wake him up.  It was this moment when his Right brain was at its most active, and it would help visualize the answer.  This ancedote and more attest to the virtues of the right brain.

But Refactor Your Wetware doesn’t stop there. In true programming fashion, it deals with how to debug your brain and methods to remove bias from your every day thought.  It effectively covers methods of learning and retaining information with proven processes.  If you’re a knowledge worker of any sort, this book belongs on your bookshelf.

Embrace Fear

I used to be scared of databases.

They’re the closest thing to a black box that I deal with on a daily basis.

Cryptic messags point to mal-formed queries; Debugging consists of <pre>PRINT</pre> statements; and learning the inner workings is akin to learning another computer architecture.

Databases were foreign animals to me. I open up a box to another world; another construct; and quite like the Matrix: I have no idea how it works.

There was my problem. Right there. In bold, even.

I wasn’t particularly proud of this fact.

If you’re a professional software developr, you’re probably on the wrong end of the database-skill curve; I know I [still] am.

For developers, SQL and Databases are a tool. We’d use XML and XSLT if it were more performant.  There’s an entire industry that uses Object Relational Mapping to get around SQL and Databases. But the problem isn’t with ORMs, it’s when we use them because we fear the unknown.

Verily I say unto you:

Embrace this fear. Let it work for you.

Without it, we’d blindly write queries; we may not parameterize variable input; and we might do something stupid, like mis-sizing a database field.

When you aren’t afraid of the unknown anymore, it’s time to question why. That fear is healthy; ignoring it isn’t.

Configuration Pain – Creating your own Custom Configuration Section

 

Recently I was asked to implement a ‘smarter’ application for managing temporary files on our company’s webfarm. We use a number of third-party tools that don’t clean up after themselves  really well (or, we may just be using them incorrectly); and as such we frequently run into low diskspace issues due to viewstate and other third party utilies not being cleaned up.

Goal: Build an application that can be configured by the end user to delete directories and files as needed (like viewstate, activePDF temp files) and run as a scheduled task. Any logging should be done to the Windows event log.

There are a number of methods that could be used to enable the user to set up their configuration options, but in keeping with the .NET model for configuration, I picked using XML and the app.config to store the settings using a custom configuration section.

I ran into an issue  during the course of development because I had the wrong XML layout. I used the following method:

<folder>
     <path>D:MyPathmyFolder</path>
     <description>MyDescriptionhere</description>
     <fileType>*.txt</fileType>
</folder>

instead of:

<folders>
     <folder id=”1″ path=”D:MyPathmyFolder” description=”MyDescriptionhere” fileType=”*.txt” />
</folders>

This creates a problem because of how .NET handles custom sections. It apparently doesn’t like the syntax of the former, and instead of implementing code to serialize it and de-serialize it myself, I chose to stick with implementing the configuration API as written.  I had that choice, since I was implementing a new ‘feature’; and if you’re maintaining a legacy project, you may not have that luxury. 

Once you know the format your XML will take, it’s a simple matter of creating the custom configuration section C# classes. The first class that is going to be created is a class that is the actual Custom Configuration section.  Classes also need to be created for each collection of XML items (the list of folders in the <folders>, and a class needs to be made for each element and its properties (the folder element and the path, description, and fileType properties.

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration;

namespace DelViewState_CS
{
    public class DelViewStateConfigSettings : ConfigurationSection
    {
        public DelViewStateConfigSettings()
        {
            
        }
                       
        [ConfigurationProperty(“folders”, IsDefaultCollection = true)]
        public FoldersCollection Folders
        {
            get { return (FoldersCollection)base[“folders”]; }
        }
        
        [ConfigurationProperty(“timeout”, IsRequired = true)]
        public int Timeout
        {
            get { return (int)base[“timeout”]; }
            set { base[“timeout”] = value; }
        }
       
    }

}

 

The configuration section has two properties, the timeout property (a poorly named legacy property that indicates how long it’s been since the file was accessed), and a folderscollection property that will contain the individual folders and their properties.

Here is the C# code for the folderscollection class:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration;
namespace DelViewState_CS
{
    public sealed class FoldersCollection : ConfigurationElementCollection
    {
        protected override ConfigurationElement CreateNewElement()
        {
            return new FoldersElement();
        }
        protected override object GetElementKey(ConfigurationElement element) 
        {
            return ((FoldersElement)element).Id;
        }
        public override ConfigurationElementCollectionType CollectionType
        {
            get
            { return ConfigurationElementCollectionType.BasicMap;  }
        }
        protected override string ElementName
        {
            get
            { return “folder”;  }
        }

        public FoldersElement this[int index]
        {
            get { return (FoldersElement)BaseGet(index); }
            set
            {
                if (BaseGet(index) != null)
                {
                    BaseRemoveAt(index);
                }
                BaseAdd(index, value);
            }

        }

        new public FoldersElement this[string Path]
        {
            get { return (FoldersElement)BaseGet(Path); }
        }

        public bool ContainsKey(string key)
        {
            bool result = false;
            object[] keys = BaseGetAllKeys();
            foreach (object obj in keys)
            {
                if ((string)obj == key)
                {
                    result = true;
                    break;
                }
            }
            return result;
        }
    }
}

The final class we have to write is the folder element itself.  This contains the necessary properties of the folder element:

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration;
namespace DelViewState_CS
{
    public sealed class FoldersElement : ConfigurationElement
    {
        [ConfigurationProperty(“id”, IsRequired=true, IsKey=true)]
        public int Id
        {
            get {return (int)base[“id”]; }
            set { base[“id”] = value; }
        }
        [ConfigurationProperty(“path”, IsRequired = true)]
        public string Path
        {
            get { return (string)base[“path”]; }
            set { base[“path”] = value; }
        }

        [ConfigurationProperty(“description”, IsRequired = false)]
        public string Description
        {
            get { return (string)base[“description”]; }
            set { base[“description”] = value; }
        }

        [ConfigurationProperty(“fileType”, IsRequired = false)]
        public string FileType
        {
            get { return (string)base[“fileType”]; }
            set { base[“fileType”] = value; }
        }
        
    }
}

Once all of that is written, it’s a simple matter of accessing the custom section and reading these properties (and in my case, deleting the files associated with them. Accessing the custom configuration section is as simple as creating a static factory method in the customconfigurationsection.cs file:

public static DelViewStateConfigSettings GetDelViewStateConfigSettingsSection()
        {
            DelViewStateConfigSettings cs;
            System.Configuration.Configuration config = System.Configuration.ConfigurationManager.OpenExeConfiguration(System.Configuration.ConfigurationUserLevel.None) as System.Configuration.Configuration;
            cs = config.GetSection(“delViewStateConfigSettingsGroup/delViewStateConfigSettings”as DelViewStateConfigSettings;
            return cs;
        }

 

There are plenty of methods for writing to the event log, but I followed the guidelines laid out here.

In the end, it took a little over a week from the time that I first learned about the task to the time it was completed (testing, checkin, cleanup).  There are a number of ways it could be made better:

  • Using delegates and anonymous methods to shorten the written code that deletes the files and writes to the event log
  • Pull the custom section into its own XML file that is referenced int he app.config; to allow for drag and drop placement.
  • Checking the files for being ‘locked’ (which happens sometimes) and working around that.  For the time being, I’m logging those happenings to the event log so I can find out why they’re happening and fix the actual problem

There are more improvements to come, in the next blog post on this topic, I’ll talk about enhancing this utility by getting it to scope out IIS Virtual directories and auto-filling that information in.

Who let the Comments out?

There are a multitude of blog posts out there that detail when you should and should not comment, but Jeff Atwood of Coding Horror puts it best:

Code can only tell you how the program works; comments can tell you why it works. Try not to shortchange your fellow developers in either area.

We’ve all heard of tales of college students whose professors required that they extensively document their code; sometimes at risk of a letter grade.

Once upon a time, in a land not so far away, a diligent young computer science student sat eagerly attentive in her C++ programming class. Her formidable instructor was droning on and on about how Programming Comments were the basis of all that is good in the world of software design. Then at last, those famous words, “If you do not comment your code, you will automatically drop one (1) letter grade.”

Academia is one thing, but what about programming texts? Shouldn’t they advocate the sane way of commenting code?

I wish.

I pulled open my old C++ book today, just to get a refresher on function pointers and things I’d forgotten (since C# makes use of function pointers in anonymous methods and lambda expressions), and happened to open up to the page on comments.

There were no less than eight bullet points on commenting code.  From Structured & Object-Oriented Problem Solving using C++, Third Edition by Andrew C. Staugaard:

 

Debugging Tip

Programming Comments are an important part of the program documentation and should be used liberally (emphasis mine).  […] At a minimum, the program should include the following comments:

  • The beginning of the program should be commented with the programmer’s name, date the program was written, date the program was last revised, and the name of the person doing the revision.
  • The beginning of the program should be commented to explain the purpose of the program, which includes the problem definition and program algorithms.  This provides an overall perspective by which anyone, including you, can begin debugging or maintaining the program.
  • Preprocessor directives should be commented as to their purpose.
  • Constant and variable definitions should be commented as to their purpose.
  • Major sections of the program should be commented to explin the overall purpose of the respective section.
  • Individual program lines should be commented when the purpose of the code is not obvious relative to the application.
  • All major subprograms (functions in C++) should be commented just like the main program function.
  • The end of each program block (right curly brace) should be commented to indicate what the brace is ending.

Well, at least he’s thorough.  Some of the advice is sage; and other parts of the advice are just downright redundant in the real world, if you’re using source control and an anything but notepad.

So here’s my revised list — directed at that very same college student who is stuck reading that text.

 

Debugging Tip

Program Comments are an important part of the program documentation and should be used to help any programmer understand what is happening.   […] Use the following guidelines for guidance:

  • The beginning of the program should be commented with the programmer’s name, date the program was written, date the program was last revised, and the name of the person doing the revision.
  • The beginning of the program should be commented to explain the purpose of the program, which includes the problem definition and program algorithms.  This provides an overall perspective by which anyone, including you, can begin debugging or maintaining the program.
  • Preprocessor directives should be commented as to their purpose, and directives should not change the meaning of reserved words.
  • Constant and Variable definitions should have a clear name that explains their purpose, so comments aren’t necessary.
  • Major sections of the program should be commented to explain the overall purpose of the respective section when its purpose isn’t reasonbly clear.
  • All major subprograms (functions in C++) should be commented just like the main program function.
  • The end of each program block (right curly brace) should be commented to indicate what the brace is ending.
  • Write code that explains itself. Comments should only be used to tell someone WHY you did something, not what you did. That’s what code is for.

Instead of using the beginning of the textbook to discuss basics that any CS101 book should cover, I’d use it to cover source control, and the integral part it plays in keeping track of code changes — something that the author wanted the bullet points to do, but which don’t make sense in modern source control systems.

If you have new developers on your team, do them (and yourself) a favor and point them to one of the references I mentioned. Friends don’t let friends comment liberally!

NB: These ideas aren’t original to me; I got them from reading Coding Horror and reading Code Complete.

 

The Cost of OpenID

I was chatting with a friend today about implementing OpenID for a possible startup idea, and we talked about the cost of OpenID vs its benefits.

The conclusion of the chat was that if you’re a bootstrapped startup, it almost never makes sense to spend the time and money implementing an authentication system.

Don’t take my word for it, look at the numbers.

Let’s say the average Software developer in your area makes just $65,000 a year (or $34 per hour)*. If they build their own authenication system from the ground up, you could look at between 80 and 120 hours worth of time spent on it (given a 60% productivity rate, that comes out to 72 hours spent on the project, or $4080 spent on programming this one part of the system.  That’s a conservative estimate.  There are many ways to do authentication; and everyone gets it wrong sometimes.

What’s the cost of implementing OpenID? 5 hours worth of initial work and $500 at most? If you went with the ‘Plus’ option, it’s only $100 per year — that’s a savings of almost $3800!

That’s $3800 that could be used for far more important things than building an authentication system, and it’s one less part of the system you have to maintain in the future — which represents an immeasurable cost savings towards other projects.

In most cases, the cost doesn’t justify the benefit of rolling your own system. Let someone else take care of it.

No Aliases in Where Clauses

I was bit by the ‘No Aliases allowed in Where Clauses’.  It also explained Linq-to-SQL’s seemingly strange syntax at the same time.

The SQL Order of Operations isn’t as its written by developers, but the other way around.

  1. FROM clause
  2. WHERE clause
  3. GROUP BY clause
  4. HAVING clause
  5. SELECT clause
  6. ORDER BY clause

 

So, when you have an aliased column, it can’t use that in the WHERE Clause because it hasn’t been told what that means yet.  So what happens when you want to use the Aliased column in the Where Clause?

There’s a Hack you can use:

Wrap the entire statement (or that line, as applicable) with a SELECT statement that contains the WHERE Clause you want to alias.

For instance:

select * from ( select a + b as aliased_column from table ) dt where dt.aliased_column = whateveryouputhere.

It does it rather nicely. You can find the question and answer (not mine) on Stack Overflow.

 

Take the Long View

I was at the bank this afternoon depositing much needed money into my very dry bank account.  At about 3:50pm, all of the computers in the bank suddenly slowed to a crawl. We stood there at our respective tellers, glancing around for 5 minutes while all of the tellers asked each otehr if they were able to ‘get in’.  They apologized, customers sighed and generally no one got anything done until the ‘computers’ came back up.

Being a software guy, my first instinct is to blame the programmers.  The tired, overworked developers who were tasked with developing and deploying Version 2 Of The Bank Software; these developers (if they’re anything like any other programmer out there) probably had a budget that was overrun, a deadline that was missed, and a manager breathing down their neck.  They probably developed the application in some easy to use language for rapid development, and if they’re anything like me (and every other programmer out there) they aren’t great programmers. In fact, if you want to get statistical, there might be 1/3 of them that are ‘above average’, 1/3 ‘average’, and 1/3 that downright suck.

They probably work in a cubicle farm as part of a consulting firm, and they’re probably the lowest bidder for the project.

Now, barely any of the decisions made are the developer’s fault. And the business people at the bank probably thought they were getting the best bang for their buck — and they did.  The consulting firm probably guarantees top-notch quality and superior customer service; and the developers probably read The Pragmatic Programmer religiously.

With all of the business decisions that were made, the bank probably didn’t put an emphasis on ‘fast’. They probably didn’t say, “We need it in one year, for this cost, and we need it to be ‘fast’.” They probably assumed (much like you and I would if we weren’t programmers) that it would be lightning fast. Or maybe they’re so used to substandard application speed (I’m looking at you, Outlook) that they don’t even bat an eyelash when the system goes ‘down’ for five minutes on a busy Friday afternoon. 

The question is, Why.  Why does the system slow to a crawl on Friday afternoons?

Because business people made decisions based on the near-term; based on contractual obligations, based on cost; and based on maximizing profit.

No one probably even thought about the customer that has to wait in line.

But what’s the effect? So a customer has to wait for five minutes — no big deal, right?

Well, if that customer is his own business person, then that’s five minutes less they have to do any work. That’s five minutes of their life that isn’t spent doing whatever their business is.

Then there’s the multiplier effect of that. Someone who was waiting for that person now waits 5 extra minutes, and someone else waits five extra minutes because that person was waiting on person #1, and so on.

How do you quantify that?

Quantify it as lost business.  That three weeks you could spend delaying deployment and load testing your application could save you money when that business decides to use you for its next version.

As a developer, you’ve got to do your learning outside of work. No longer is yours a nine-to-five job.  It is a font of continual learning.  Spend an hour a night just catching up on the intracies of your programming language. Premature Optimization is the root of all evil, to be sure; but skipping optimization for time saved by your banks’ customers is a recipe for never getting that bank as a customer again.

Get out of your cubicle farm, and see your software in action. Spend five minutes on a friday afternoon with your customer and see whether or not their software slows down inexplicibly. If it does, fix it. If it doesn’t, congratulations; you’re the minority.

Bad Acting

During my time in the Army, I used to get rankled when I’d see Television or Movies portray soldiers.  Generally, they’d get something wrong; and usually, it wasn’t just something minor.  It didn’t usually bug me when it was clear they weren’t trying to get it right. It bothered the hell out of me when it looked like they tried to get it right, but failed in some way that could have been prevented if they would have spent $1000 and hired a military consultant for a day.

The same thing bothers me about naming in source code.  Well, not the military part, but the ‘bad acting’ part.  Here are a few bad names I’ve seen in source code recently, and they are all from commercial applications.

timeout  – Describes how old a file should be before it’s deleted

narrative – Refers to the ‘help’ field for a form or page.

nounset – where noun can be anything, like ‘bird’ or ‘category’ or ’email’ or ‘password’. The suffix ‘set’ is added to it to denote a ‘set’ of that noun. In some cases, it refers to a ‘template’.

That’s just a few; and there are more out there, probably in the application you work on.

What’s so wrong with bad naming?

Let’s say you have a new developer come onto your team. it doesn’t matter if this developer is just out of college or if he’s a 10 year veteran. He now has to learn what those words mean.  He then has to apply those names to the intent behind them, and daily has to remind himself of what they mean.

timeout  – fileage

narrative – instructions

nounset – nouns, or nounTemplate (This can also rely on the fact that in databases, a table is considered a collection of things; adding ‘set’ is redundant).