Drop in the Bucket
One coder in the sea of s/w knowledge

Please Read the Error Message

Generic List Doesn’t Support the Query Pattern

I recently wrote similar code to this little fragment (this is a sanitized version for the purpose of this example).

 

   12 
   13 List<int> nums = new List<int> { 0, 1, 1, 2,
   14                     3, 5, 8, 13, 21 };
   15 
   16 var evenQ = from n in nums
   17             where n % 2 == 0
   18             select n;
   19 

 

I was shocked when I received this error message

WTF! What do you mean, a list doesn’t support the query pattern!? That’s absolutely ridiculous. I’m quiting C# development, and I’m converting to writing Rails apps on the Mac….

We interrupt this moment of panic for the following public service announcement:

Developers, do you get tired of reading those pesky error messages? Me too, but remember the compiler team has gone through a lot of trouble to tell you when you’re an idiot and help you recover. Take it from me, if you read the entire error me sage instead of the first half sentence, you’ll be better informed of why you’re such a bonehead and more likely to recover. Now back to our regularly scheduled moment of sanity.

...”missing a using directive?”. Yes, as it turns out I prematurely used one of my favorite VS features: remove and sort using statements.

All is well, and the universe is in a causal state again. Turns out that if you don’t have any dependencies on statements or extensions in System.Linq “remove and sort” will remove the LINQ using statement (duh), and thus all the LINQ goodness will be hidden from the compiler.

Simply adding using System.Linq; fixed this particular goof. Yes, perhaps I’ll read the entire error message next time.

Goodbye Motorola

The Post I Should Never Have Written

I spent the entire month of April, writting and re-writting this post. You see, I used to work for Motorola. As a matter of fact, all combined I worked for them for a total of nearly 13 years. Some of my original drafts blasted middle management, upper management, CEOs, and pointed out all that was wrong with the company.

I finally decided to shelve the burn Motorola post. Motorola is burning by itself without any additional help from me. I will say one thing, the one thing that I feel doomed Motorola, more than any of its problems with management: Motorola forgot that it survived by providing a place for people to innovate. The company started treating everyone like an interchangeable commodity. The company turned its back on being loyal towards its people, and as a result the company lost the loyality of its people—mainly through fear. The end result was the company cutting its own lifeline: innovation.

Refactoring the Sieve of Eratosthenes

I have recently been reading "Agile Principles, Patterns, and Practices in C#" by Robert C Martin and Micah Martin. So far, it's been an enjoyable read. Early on the authors explain the concept of refactoring by showing how they would go about refactoring the "Sieve of Eratosthenes":http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes. The algorithm is a way to generate a list of prime numbers. The final refactored solution is full of loops and breaks, which is fine, but like most things -- it looked like a job for LINQ! I decided to repeat the exercise using as much LINQ as I could reasonably stuff into algorithm. Here is my green pass (of a red-green-refactor cycle).
   18 
   19 public static IList<int> GenerateListOfPrimes(int maxNumber)
   20 {
   21     IList<int> result = new List<int>();
   22 
   23     if (maxNumber > 1)
   24     {
   25         var candidateNumbers =
   26           Enumerable.Range(2, maxNumber - 1);
   27 
   28         double stopNumber = System.Math.Sqrt(maxNumber);
   29 
   30         int nextPrime = 2;
   31 
   32         while (nextPrime <= stopNumber)
   33         {
   34             candidateNumbers =
   35             (from n in candidateNumbers
   36             where
   37               n <= nextPrime ||
   38               n % nextPrime != 0
   39             select n).ToList();
   40 
   41             nextPrime =
   42                (from p in candidateNumbers
   43                 where p > nextPrime
   44                 select p).First();
   45 
   46         }
   47 
   48         result = candidateNumbers.ToList();
   49 
   50     }
   51 
   52     return result;
   53 }
   54 
Well, it uses LINQ, but it ain't lovely. I ended up refactoring the code in much the same way that the authors did. Primarily by breaking up the long method (Extract Method). The final pass of the method ended up looking like this:
   31 
   32 public int[] GeneratePrimes(int maxNumber)
   33 {
   34     int[] result = new int[] { };
   35     if (maxNumber > 1)
   36     {
   37         InitializeRangeOfNumbers(maxNumber);
   38         InitializeLastNumberToCheck(maxNumber);
   39         int prime = 2;
   40         while (RemainingNumbersContainFactorsOf(prime))
   41         {
   42             RemoveFactorsOf(prime);
   43             prime = NextPrime(prime);
   44         }
   45 
   46         result = _remainingNumbers.ToArray();
   47 
   48     }
   49 
   50     return result;
   51 
   52 }
   53 
The implementation of the methods look like this:
   54 
   55 private void InitializeLastNumberToCheck(int maxNumber)
   56 {
   57     _lastNumberToCheck = Math.Sqrt(maxNumber);
   58 }
   59 
   60 private void InitializeRangeOfNumbers(int maxNumber)
   61 {
   62     _remainingNumbers = Enumerable.Range(2, maxNumber - 1);
   63 }
   64 
   65 private int NextPrime(int currentPrime)
   66 {
   67     return
   68         (from p in _remainingNumbers
   69          where p > currentPrime
   70          select p).First();
   71 }
   72 
   73 private bool RemainingNumbersContainFactorsOf(int prime)
   74 {
   75     return prime <= _lastNumberToCheck;
   76 }
   77 
   78 private void RemoveFactorsOf(int prime)
   79 {
   80     _remainingNumbers =
   81         (from n in _remainingNumbers
   82          where
   83            n <= prime ||
   84            n % prime != 0
   85          select n).ToList();
   86 }
   87 
You might be interested to know that the LINQ implementation is (ever so) slightly faster than the Martin version. Both versions can compute the first 100,000 primes in less than a second. I haven't dug into the reason why. For fun, I decided to implement an algorithm that would fall into the LINQ way a little easier. I came up with this:
   27 
   28 public int[] GeneratePrimes(int maxNumber)
   29 {
   30     int [] result = new int [] { };
   31     if(maxNumber > 1)
   32     {
   33         var primeNumbers =
   34             from n in Enumerable.Range(2, maxNumber - 1)
   35             where n.IsPrime()
   36             select n;
   37 
   38         result = primeNumbers.ToArray();
   39 
   40     }
   41     return result;
   42 }
   43 
The @IsPrime@ method is the trick.
   48 
   49 static class IntExtensions
   50 {
   51     public static bool IsPrime(this int p)
   52     {
   53         bool result = false;
   54         if (p > 1)
   55         {   
   56             IEnumerable<int> testNumbers =
   57                 from n in Enumerable.Range(2, (int)Math.Sqrt(p))
   58                 where 
   59                     p != n && 
   60                     p % n == 0
   61                 select n;
   62             result = testNumbers.Count() == 0;
   63         }
   64         return result;
   65     }
   66 }
   67 
This algorithm might look a little nicer (from a LINQ point of view), but it's tragically slow. Essentially, the code performs some heavy looping for each number in the range being tested. I could probably juice up the prime test a little bit by digging into some of the more advanced algorithms, but for now it was a fun exercise.

Download the Source

Deming was the Brooks of Business

W. Edwards Deming was an incredibly lucid business visionary that understood what really makes business tick. Deming had a holistic understanding of producing a product  from employee, to management, to customer. Through his publications and work with post WWII Japanese industry, he proved that his observations and hypothesis are not only valid but powerful tools for success (e.g., 1977 Ford Pinto vs. 1977 Toyota Corolla). Here is a block quote from wikipedia that explains his philosophy (in a nutshell).

Deming's 14 points

Deming offered fourteen key principles for management for transforming business effectiveness. In summary:

  1. Create constancy of purpose toward improvement of a product and service with a plan to become competitive and stay in business. Decide to whom top management is responsible.
  2. Adopt the new philosophy. We are in a new economic age. We can no longer live with commonly accepted levels of delays, mistakes, defective materials, and defective workmanship.
  3. Cease dependence on mass inspection. Require, instead, statistical evidence that quality is built in. (prevent defects instead of detect defects.)
  4. End of the practice of awarding business on the basis of price tag. Instead, depend on meaningful measures of quality along with price. Eliminate suppliers that cannot qualify with statistical evidence of quality.
  5. Find Problems. It is a management’s job to work continually on the system (design, incoming materials, composition of material, maintenance, improvement of machine, training, supervision, retraining)
  6. Institute modern methods of training on the job
  7. The responsibility of the foreman must be to change from sheer numbers to quality… [which] will automatically improve productivity. Management must prepare to take immediate action on reports from the foremen concerning barriers such as inherent defects, machines not maintained, poor tools, and fuzzy operational definitions.
  8. Drive out fear, so that everyone may work effectively for the company.
  9. Break down barriers between departments. People in research, design, sales and production must work as a team to foresee problems of production that may be encountered with various materials and specifications.
  10. Eliminate numerical goals, posters, slogans for the workforce, asking for new levels of productivity without providing methods.
  11. Eliminate work standards that prescribe numerical quotas.
  12. Remove barriers that stand between the hourly worker and his right of pride of workmanship.
  13. Institute a vigorous program of education and retraining.
  14. Create a structure in top management that will push every day on the above 13pts.

Seven Deadly Diseases

The Seven Deadly Diseases:

  1. Lack of constancy of purpose.
  2. Emphasis on short-term profits.
  3. Evaluation by performance, merit rating, or annual review of performance.
  4. Mobility of management.
  5. Running a company on visible figures alone.
  6. Excessive medical costs.
  7. Excessive costs of warranty, fueled by lawyers who work for contingency fees.

What is surprising is how relevant this work still is. What is equally surprising is how many companies simply don't learn from history and the collective experience. What do they teach in business school anyway? I can recall a point in time where a certain company stopped doing most of the 14 points and caught in earnest most of the seven deadly diseases. That point in time was the beginning of an all too certain end.

I'll admit that I have no right to cast stones. The software industry has long had our own version of Deming in Brooks. I can't tell you how many times management has attempted a full-on interview-hire cycle to try and pull in features and schedules. What do they teach in Computer Science anyway? I've always wanted to structure a software team around Brooks concept of the "surgical team". I've never seen it done, but it sounds like it would work.

Why did I write this post? I've recently been asked my opinion, "What would you do if you were CEO/CIO/CxO?". I think it surprises the people asking that I have a long list of answers. I'm also trying to satisfy a condition of my employment in the form a lengthy essay that flies square in the face of Disease #3 -- and it just seems that something isn't quite right.

Featured Developer in Community Credit


I am one of the featured developers in Community Credit!

Community Credit is a great site devoted to rewarding those who contribute to the .net community. I am truly honored. Thanks Dave

The most embarrassing thing is the quick head shot that I put together. Check out this mug:

This truly shows off my l337 PhotoShop skillz, as I ripped my head out of a random Christmas photo and put it on a neutral background (please note the sarcasm).

My First CodeProject Article: LINQ to Life

One Down, n to Go

I posted my first article to code project today. I decided that it would be fun to write Conway's Game of Life using LINQ. I wanted to stress how query expressions, lambda expressions, extension methods, and the rest of the .net 3.5 enhancements make code more expressive, readable, and easier to understand. Please click through the image, and take a look.

The First Time is Always the Hardest

I had a little trouble knowing what's what in their article submission editor. I even got this screencast:

 ...to work fine in the preview screen. No dice on the actuall submission. I had to punt back to providing a link to the screen cast stie.

I'm Amazed

I hadn't even finished all the cleanup: figuring out why my download link wasn't showing up, removing that last typo, punting on the embedded screen cast, when I noticed that the article had been read 473 times, had 2 votes (5/5), and a positive comment.

Wow! Certainly, that's humbling, and I'm very gratefull for the positive feedback. I'm just amazed people have read my work :)

 

WinForm Settings with C#

Download Source

The other day, I built a quick demo app using WinForms. It had been a while, and I couldn’t remember how to save the form’s current settings for the next session. Fairly old school, but I thought that it was pretty nifty anyway.

To demonstate, I built this little sample app:

When you close the form by clicking the Exit button, or by clicking the X in on the title bar, this application will save whatever was typed in the three text boxes. When you open the application the next time those text values will still be there. My demo uses the text in text boxes, but this could apply to anything: window position, background color, or some custom object.

Inside the Solution Explorer for my WinForm project, you simply have to expand the “Properties” folder, and double-click the default settings file.

If that file does not exist, create it by going to the project properties and choosing the “Settings” tab.

This will bring up the settings editor dialog.

Type the name of your settings, their data types, and any default values. The default values will be used if the settings have never been used (i.e., when the application starts for the first time). The settings file will be compiled into a type-safe class that you can use to retrieve and save these settings.

Add this function to your code behind, and call it from within the Form_Load event handler:

 

   33 
   34 private void ApplySettings()
   35 {
   36   aInput.Text = Properties.Settings.Default.A;
   37   bInput.Text = Properties.Settings.Default.B;
   38   cInput.Text = Properties.Settings.Default.C;
   39 }
   40 

The code above uses the “Default” instance of the Settings class to simply transfer the setting values into the text boxes.

Add the following function, and call it from your Form_Closing event handler:

 

   28 
   29 private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
   30 {
   31   SaveSettings();
   32 }
   33 

Whenever the form closes the settings are assigned the values from the text boxes. The save method persists the information for the next session.

Change or Perish

During some big-company planning today, I was brought back to an old saying:

Fine I thought, things could be better. I have my doubts, but in general change is good. During the meeting, I could not help but think of this image:

After the meeting I felt like a real “red shirt”.

Change or perish indeed!

Make the Car Go Faster

The Best In-House Programming Gig Ever

I would currently be classified as an in-house programmer. One of those programmers that Joel warned you about. I don’t feel too badly because it is in fact, what 80% of the software jobs are out there. You have to feed the babies somehow. Working in the IT basement is absolutely brutal on your psyche for all the reasons Joel lists.

There are always exceptions. I had the great privilege of working with a brilliant software engineer named Alex Soto. I have to relate this experience vicariously, unfortunately. The best job he ever had was at a tractor company in Chicago.

He worked on an awesome crop visualization thingy, was treated with great regard, sent to some killer training out in CA to learn Eiffel) just because he was interested in it, etc… He was forced to leave the company because it was in Chicago and his family was in Miami (sigh).

Not the Best In-House Programming Gig Ever

That little day-dream doesn’t match reality for most of us. So how do we make peace with our lives (that is until we can go off and form our own killer bug-tracking software company, dating web site, or get the dream-team assignment building Microsoft’s next generation web framework from your home office).

  1. Work on an open source project. I myself am still trying to find the place in my personal life where this will fit. I am going to do it one day (hey I started blogging).
  2. Make the Car Go Faster

Making the Car Go Faster

Legend has it that the Toyota Racing Team hired a brand-new CIO some years back. On his arrival, he studied the existing infrastructure and software. He studied the processes and the resources. He determined that none of what was in place passed muster, and did what new execs/architects/programmers do best: restructure, re-organize, and put in new systems, software, and processes.

At the end of the year, the CIO goes before the board with a long laundry list of accomplishments; proud of what he’s accomplished. The CEO’s reaction: “How does any of this make our car go faster?”

Think outside of the craft of software, perhaps just long enough to realize that your day job is really to make the car go faster (or sell more groceries, or build better PDA’s, or whatever). As long as your love for the unique craft that is software remains, your talent will find its way out.

Now that Our URLs are Friendly

This post is more of a question because I really haven’t made up my mind about it yet. Maybe you can help.

Typical front-controller based web frameworks like rails and MS MVC push around URLs that might typically look like this:

mysite/products/details/2

This would typically show the details from a row of the products table with an identity primary key of 2 (never mind the ProductsController and the actual Product object).

Everything in this example works just fine. Of course, you’re not supposed to reveal your identities in the URL, and search engines like words, yadda, yadda, yadda… This leads to URLs that look like this:

mysite/products/details/mace-windu-light-saber

You can tell the sorts of sites I shop at.

In our example, the product with primary key 2, has a product name of “Mace Windu Light Saber”. So assume that our Products table has an integer identity field used as the ProductId and some nvarchar ProductName.

My question is: Should the Products table also contain a column to contain the munged product name that is unique part of the URI for the coveted Mace Windu Light Saber?

The function that munges product name to URI is pretty simple. All it needs to do is replace any non-word character (\W+) with some URL friendly character (e.g., the ’-’). If you did have the URI column, it would contain redundant information wouldn’t it? It’s really a derived expression.

To perform a lookup based on the URI, you would need a function to essentially replace all those friendly characters (e.g., ’-’) with a wildcard and you’d end up with a SQL statement that has a WHERE ProductName LIKE 'mace%windu%light%saber'

We don’t have to have the URI column in the DB. The URI can be derived for writing. For lookups a similar function and some wild cards allow us to do the trick.

However, wouldn’t life be a little easier if you did have the URI column? You would only have to munge that product name once; say on the initial insert (ignoring collisions for a moment). Lookups would be a lot faster, as you can get rid of the LIKE expression, put an index on the URI column, and do a search over on an indexed column. Essentially you’d get rid of the reverse munge (de-munger?) all together. Writing the URL would be as simple as accessing another property.

You could also open up the possibility of having exceptions to your munging function. For example, if I really wanted the URL for the “Mace Windu Light Saber” to read:

mysite/products/details/purple-wand-of-death

that scenario is trival with the URI column.

I suppose what bothers me is having that weird URI column in my Products table. It seems to be an artifact of accessing my products over HTTP.

What do you think dear readers?