Monday, November 21, 2011

I donated and so should you.

I read Wikipedia at least once a day.  Usually many times a day.  So...

Support Wikipedia

You have taught me so much that I was curious about and so much about what I didn't know I wanted to know. Keep up the good work.

Monday, November 07, 2011

My professional philosophy: "The General Problem" from xkcd

I don't think anything could describe my professional philosophy more succinctly or clearly than this xkcd comic:

"The General Problem"
"I find that when someone's taking time to do something right in the present, they're a perfectionist with no ability to prioritize, whereas when someone took time to do something right in the past, they're a master artisan of great foresight."

Wednesday, July 13, 2011

It's not easy being green

I had once been directly involved with the development team for an automotive market software product.  As a result, I worked with resources from the Automotive Aftermarket Industry Association and ended up on their mailing list for their publication: "Aftermarket Insider" which I receive monthly.  Volume 70 arrived recently.  I noticed, as often happens with periodical advertising supplements, that the issue was wrapped in a plastic sleeve containing a loose insert along with the primary publication.  I thought nothing of it until I noticed the content of the insert.  It was very nice, recycled card stock with a printed gloat about how "The automotive aftermarket industry was green long before being green was mainstream."

Really?  You tell me this by including it on unnecessarily thick paper enshrouded in plastic?

Instead, you could have emailed that to me in one of your regular blast mails from which I still can't seem to unsubscribe...

*sigh*

Monday, June 13, 2011

1 Year = 2.6 Million Keystrokes

A look back at my last year of typing.

Having mild OCD is advantageous to being a programmer.  But it has its drawback, such as forgetting to take breaks, use the bathroom, eat and sleep.  In April 2010, after seeing a coworker using it, I installed Workrave on my work desktop to help my effort to be better about taking breaks.  Workrave is a task tray tool that pops up reminders to take micro-breaks (to stretch your various appendages and eyes), longer breaks and can alert you to help limit your overall daily computer use, in whichever combinations you so choose.  All of this is an effort to help reduce repetitive stress injuries common among heavy computer users.  Along with these features, Workrave tracks your key-presses and mouse movement distance.  Since my "mouse" is a trackball and thus never really moves, the mouse movement figures are generally useless.  (However, it does track movement time which could be helpful for tracking how long your hand is working the mouse.)  The keystroke count is much more concrete, which gave me an idea.

I started recording the daily keystroke stats and now have some impressive numbers.  Since April 9th 2010, 2,899,821 keystrokes have been recorded.  Excluding those after April 9th of this year, the total is 2,599,992.  That's 2.6 Million keystrokes for one calendar year.

I moved the stats from post 4/9/2011 to the beginning to create one complete calendar year, and came up with the following detailed figures:

  • Grand Total: 2,599,992
  • Monthly Average: 216,666
  • Highest Month: 291,506 (Feb)
  • Daily Average: 11,255
  • Highest Day: 29,110

Some additional information that influences the numbers (positively and negatively):

  • Sometimes I work from home.  Occasionally I use remote desktop and work on my desktop where the count is recorded.  Some days I don't.  This could account for a lower count.
  • My work setup includes a laptop.  The laptop screens are set up next to the desktop screens and I use Synergy to control both machines from a single keyboard/mouse, giving me a single, contiguous desktop (another tool I highly recommend).  The desktop serves as the Synergy server, acting as the input master which allows all input control going to the laptop to pass through the Workrave counters running on the desktop.  Occasionally, due to a glitch or a reboot, I won't have primary control so I'll physically switch to the laptop keyboard/mouse.  This could account for a reduction in keystroke count, though probably not much.
  • I haven't really been doing much programming lately, certainly not as much as in years past.  I do a lot of systems administration, infrastructure and other tasks that require less typing.  On days that I am actually writing code, my numbers jump significantly.  A safe estimate is an average in the 10,000 to 20,000 range, usually towards the high end.

I took a look back over my daily numbers and journal entries for those high count days.  I found that the days I'm writing code, I average around 20,000 keystrokes.  So I can make a fairly safe prediction that if I spent most days writing code I would probably have numbers closer to these:

  • Daily Average: 20,000
  • Monthly Average: 418,333
  • Yearly Total: 5,020,000

That figure seems pretty crazy to me.  I never would have estimated in the millions if I'd been asked how many keystrokes I think I make in a year.  Considering that I've been a developer for a solid 11 years, and until recently, most of that has been spent programming, I would venture a guess that I have over 55 million keystrokes under my fingertips.  I have trouble fathoming that.  My typing teacher in high school would be proud.

Wednesday, May 11, 2011

Where I put my extension code

In a comment on my "ASP.NET MVC - Excluding Model Validation Rules" post reader @wow0609 asked:
Where do you put something like this in your MVC project? This is a specific extension method, probably in a file by itself. Do you have a specific structure (directory / folder) you use for this? Do you have a generic /common folder or something?

I felt this question was worthy of a dedicated post. I break it down this way.

Sharable Code
If the code I've written is not specific to a particular application (as is the case of excluding model validation rules) then I will most likely put it into one of the shared libraries used by my development group.  Those libraries have lots of utility functions and such that are generic to the platform/stack they support.

Application Specific Code
When the code is really only applicable to one application then I'll put it into the application's project.  For a web project I'll typically put them in a class under a "Components" directory.  Often, code will start here and then I'll refactor it to be more generic and move it to a shared library.

In either case, for extension methods I usually name the class/file using this pattern: "[extendedclass]Extensions".  For example: HtmlHelpersExtensions.  I set that class' namespace to the extended class' namespace.  In the case of the MVC model validation rule exclusion extension it would be "System.Web.Mvc".  This eliminates the need to explicitly import/include the custom namespace to discover extension methods which is particularly helpful for shared libraries (or if you are like me and can't remember what you wrote last week).

Friday, February 04, 2011

ASP.NET MVC - Excluding Model Validation Rules

While building a simple MVC app, I came across the problem where I am using one model in several views. The model includes DataAnnotation attribute rules for validation. However, some rules don't apply to certain views. It seems this is a common problem, without a well established solution. After searching a bit, I found this post by Andrew West that nicely summarizes the problem and several solutions. His last suggestion is to remove the items from ModelState that you don't want to participate in the validation. I agreed that this was the simplest and least dependent solution and pursued it.

What I finally came up with was a simple extension method for the ModelStateDictionary that looks like this:
public static void CleanAllBut(
this ModelStateDictionary modelState,
params string[] includes)
{
modelState
.Where(x => !includes
.Any(i => String.Compare(i, x.Key, true) == 0))
.ToList()
.ForEach(k => modelState.Remove(k));
}

The method removes everything in the model state dictionary that doesn't match one of the "includes" strings. Being a params argument to the method, the call to it becomes very clean and readable (unlike the extension method itself). So I added this call to my controller method:
ModelState.CleanAllBut("username", "password");

While we can use the existing ModelStateDictionary.Remove() method for when we only want to explicitly remove one item, for multi-key removal we could make a similar extension method that takes a list of keys to remove.

Thursday, January 27, 2011

Adding MVC view file extension exclusion to T4MVC

Yesterday I wrote about creating razor view engine code behind files. I've been playing with the T4MVC T4 template for ASP.NET MVC that I learned about by watching this video.

Today I discovered that the view code behind files I created are showing up in the MVC.<controller>.Views list because the files (*.cs) are in the views folders next to the actual views (*.cshtml). Due to the naming convention I used, the *.cs file comes first in the directory listing. While the T4 template code gracefully deals with files with the same name portion of the full filename, the consequence of my names resulted in the generation of the following two properties:
MVC.Shared.Views.PlantListPager
MVC.Shared.Views.PlantListPager_cshtml

The first is the result of the code-behind file (PlantListPager.cs) while the second comes from the actual view (PlantListPager.cshtml). Again, the template gracefully deals with a potential name conflict. However, access to the code-behind path is not needed and the resulting extra property looks messy.

I looked through the T4MVC.settings.t4 file and found the ExcludedStaticFileExtensions array of extensions that excludes the specified file extensions from property generation for the files found in the static folders (as specified by the StaticFilesFolders array just above it in the settings). Unfortunately, I didn't find a similar array specifying exclusions for view folder(s)'s files. Presumably, this is because the view folders would typically not have anything other than actual view files. So I added the following block to the settings:
// View file extensions to exclude from the generated links   
readonly string[] ExcludedViewFileExtensions = new string[] {
".cs"
};

In the T4MVC.tt template file, I found the code that excludes the static files in the "ProcessStaticFilesRecursive" method after which I modeled the following block that I added to the "AddViewsRecursive" method:
if (ExcludedViewFileExtensions.Any(extension =>
item.Name.EndsWith(extension, StringComparison.OrdinalIgnoreCase)))
continue; // ignore defined extensions

This checks for extension exclusions when the list of views to create as properties is first built up.

Now I realize that I should probably just contribute this change back into the MvcContrib project. However, I'm going to cop out for the following reasons:

  • I don't have the infrastructure tools and knowledge required (Mercurial & NUnit)

  • I thought it would be valuable to illustrate how relatively simple it is to make a change to an existing T4 template without totally messing it up.


If there's a T4MVC contributor out there reading this who'd like to include this change, by all means, please do.