Tuesday, August 28, 2007

Developer Jokes

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/developer_jokes.htm]

Here are two developer jokes, just for laughs. I can't remember where I heard these:

Interviews: A confident college grad is interviewing at a software company. When asked what sort of compensation he's looking for, the grad suggests a 6 figure salary, 5 weeks time off, and free tuition for a masters degree.

"No problem," replied the boss, "We even give you your own company car."

"Really, are you kidding?" asked the grad.

"Well, no... but you started it."

 

Time sheets: A manager was staffing for a new consulting project, and insisted that he needed a developer with at least 15 years industry experience. When he found himself staffed with a young kid, barely out of college, he told his director "You must have made a mistake, this guy is just a kid, but I need someone senior".

"Oh," his director replied, "my bad, I determined his age from the amount of hours he logged in his timesheet."

 


Living in Chicago and interested in working for a great company? Check out the careers at Paylocity.

 

Monday, August 27, 2007

Using Nullable to create a null boolean

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/using_nullable_to_create_a_null_boolean.htm]

A classic problem in data mapping is how to handle null values. For example, a database column may be of type int, but it allows null. Many devs will just designate a sentinel value (like Int32.MinValue) to correspond to the DB null. That's okay for integers or DateTimes that have millions of values to spare, but it doesn't work well with booleans where you have only two values. You can't always assume that "null" corresponds to "true" or "false".  There are many common solutions to this:

  • Having an additional property "IsBooleanFieldSpecified" [Problem - this requires an extra property]

  • Not using booleans, and instead using a wrapper that has a third option for Null (like System.Data.SqlTypes.SqlBoolean) [Problem: most devs think in terms of System.Boolean]

  • Requiring all booleans to be not null in the database such that the null problem never appears [Problem: This may not be realistic, especially for legacy systems]

One easy way to handle this with C# 2.0 is with Nullable types. For example, you could write a method that takes a null boolean:


    public static string HandleBool(Nullable<bool> b)
    {
      if (b == null)
        return "NULL";
      else if (b == true)
        return "TRUE";
      else
        return "FALSE";
    }

 

    [TestMethod]
    public void NullableTest_1()
    {
      Assert.AreEqual("NULL", HandleBool(null));
      Assert.AreEqual("TRUE", HandleBool(true));
      Assert.AreEqual("FALSE", HandleBool(false));
    }

 

Note that without the "Nullable" prefix, passing in null would throw a compile error. The solution seems the best of all worlds.

 


Living in Chicago and interested in working for a great company? Check out the careers at Paylocity.

 

Sunday, August 19, 2007

Converting a List to an Array and back using Generics

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/converting_a_list_to_an_array_and_back_using_generics.htm]

UPDATE (8/21/2007): A comment from Martin shows that you can actually do this much simpler, using standard .Net constructors and methods. So, this code snippet is now just an example showing some features of Generics.

 

I love Generics in C# 2.0 because they let you abstract out type, which lets you code at a greater level of reusability. For example, you could use Generics to abstract out return type. You could also use Generics for standard set and conversion operations.

 

Say your code juggles between System.Collections.Generic.List and arrays. Lists are great for adding and removing items; arrays are just ubiquitous. You could easily write a converter utility methods to handle this:

 

    public static List ConvertArrayToList(T[] myArray)
    {
      if (myArray == null)
        return null;

      List myList = new List();

      for (int i = 0; i < myArray.Length; i++)
      {
        myList.Add(myArray[i]);
      }
      return myList;
    }

    public static T[] ConvertListToArray(List myList)
    {
      if (myList == null)
        return null;

      T[] myArray = new T[myList.Count];

      for (int i = 0; i < myArray.Length; i++)
      {
        myArray[i] = myList[i];
      }
      return myArray;
    }

 

Here we use the generic 'T' to abstract out an input value, the return type, and even to create a new object within the method. It's obviously much better than writing custom converter methods for all your object collections, or every using the ArrayList and unboxing.

 

Here's a simple unit test that shows how to call each method. It round-trips between the two - i.e. you should be able to convert from a list to an array and back to a list, and the final list should match the original one.

 

    [TestMethod]
    public void Convert_ListToArrayRoundTrip_1()
    {
      string[] astr = new string[] { "a", "bb", "ccc" };
      List<string> lstr = MyClass.ConvertArrayToList<string>(astr);

      string[] astr2 = MyClass.ConvertListToArray<string>(lstr);

      Assert.AreEqual(astr.Length, astr2.Length);
      Assert.AreEqual(astr[0], astr[0]);
    }

 

Besides convert methods, you could also write simple set methods, like something to remove all the items from a list:

 

    public static List RemoveItems(List mainList, List itemsToRemove)
    {
      if (mainList == null)
        return null;

      if (itemsToRemove == null || itemsToRemove.Count == 0)
        return mainList;

      for (int i = 0; i < itemsToRemove.Count; i++)
      {
        mainList.Remove(itemsToRemove[i]);
      }
      return mainList;
    }

 

You could write a test for the basic case:

 

    [TestMethod]
    public void RemoveItems_Some()
    {
      List<int> iMain = new List<int>();
      iMain.AddRange(new int[] { 10, 20, 30, 40, 50 });

      List<int> iRemove = new List<int>();
      iRemove.AddRange(new int[] { 30, 50, 70 });

      List<int> iFinal = MyClass.RemoveItems<int>(iMain, iRemove);

      Assert.AreEqual(3, iMain.Count);
      Assert.AreEqual(10, iMain[0]);
      Assert.AreEqual(20, iMain[1]);
      Assert.AreEqual(40, iMain[2]);
    }

 

Disclaimer: obviously you could have a lot more unit tests to fully test these methods.

 


Living in Chicago and interested in working for a great company? Check out the careers at Paylocity.

 

Wednesday, August 15, 2007

The Developer's version of Maslow's hierarchy of needs

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/the_developers_version_of_maslows_hierarchy_of_needs.htm]

We all know that there's a list of buzzwords that every app should have - it should be secure, fast, maintainable, functional, and reasonable to build. However, not everything is equal - just like there's Maslow's hierarchy of human needs, there's also a developer's hierarchy of needs. This is how I'd currently rank needs for the an enterprise app:

  1. Functionality - Ignoring security, performance, and anything else, the bottom line that every dev wants to show their client is that the app functions correctly. It the app doesn't even save results or calculate correctly, nothing else matters because no-one will pay for it.

  2. Security - This is really an extension of functionality. An unsecured app can be worse than no app at all.

  3. Build-ability: Can it be built? - I think that functionality trumps build-ability because developers will often learn new languages in order to meet the functional requirements (i.e. a dev learns html in order to functionally create a web app). We'd all love bells and whistles, but if a developer can't build it, it doesn't matter. This is why I'd rank the ability to implement above performance. For example, most developer choose C# over Assembly Language because it's more feasible to program in C#, even though Assembly is obviously faster.

  4. Maintainability - every app must be maintained. If the maintenance is impossible, it will drag everything else down with it.

  5. Performance - Performance is great, but only after all these other needs are met. Who cares how fast it is if the app doesn't do what you want, will likely get hacked, or just is too costly to build and maintain?

  6. Bells & Whistles - Every dev wants to sneak in some awe-inspiring bells and whistles, but as far as business goes, that's last on the list. This is why many development shops lag behind the latest technology, because they view the fancy features it provides as still unnecessary luxuries. For example, an app may not yet have fancy AJAX controls or a flashy GUI because they haven't gotten the more important needs met first. If a team has the first 5 needs met, then they'll be in a much better position to explore the "cool" tricks of the latest technology


Living in Chicago and interested in working for a great company? Check out the careers at Paylocity.

Tuesday, August 14, 2007

How easy maintenance will improve performance

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/how_easy_maintenance_will_improve_performance.htm]

We all want our software apps to perform fast, however sometimes we get so obsessed with immediate performance that we neglect the big picture and actually code in a way that degrades performance in the long run. The problem is that optimizing code for performance usually (1) takes more development resources, and (2) makes that code harder to maintain. About the second point - there is often a tradeoff between performance and maintenance: generalized code is easy to maintain, but because it handles all general cases, it is not optimized for speed. For example, it wastes extra resources on tasks that may not be needed for the current case, but are still included so that the code handles the general case.

 

So, the trap becomes a developer may spend all their resources upfront trying to optimize a specific component. However, if that component isn't truly performance-critical, then they've: (1) spent their resources on a non-critical item such that they have less resources for the really critical ones, and (2) created a maintenance issue that will continually drain their resources away from the components where a little amount of effort could really optimize it.

 

What this means is that, in the long-haul, writing maintainable code (which may be slightly slower) will actually yield overall performance gain because you'll continually have move resources to address the real performance problems. Functionality trumps performance - if your code functionally doesn't work, you won't care about performance. So if you're continually being distracted to go and fix bugs in old code because it isn't maintainable, you'll likely shift your mindset from "make this work fast" to "just get it to functionally pass". Of course the trap is that a developer starts out with good intentions - "I was just trying to optimize this code".

 

The optimal approach is to strike a balance between maintainability and performance. Some practical tips:

  • Not all code is equal - obviously code that is frequently called needs much more attention that code that is rarely called.

  • Check where your bottlenecks are. For example, if your database is ground to a halt, and your web servers are relatively free (keep in mind that web servers scale much more easily than database servers), killing yourself to optimize a simple codeBehind page may steal mental resources from optimizing the real issue - a database. Likewise, don't waste time trying to compress all your JavaScript, just to save 5 k of download, if that JavaScript now becomes impossible to debug or maintain.

  • Know what the standard is - Everyone knows that the app should be "fast", but how fast is fast enough? Clichés like "as fast as possible" are what get you into the downward spiral because they encourage you to squander resources on less-important tasks. If you know that given X users, a page should take Y seconds to load, then you can make rational decisions on how to spend your development time wisely.


Living in Chicago and interested in working for a great company? Check out the careers at Paylocity.

Monday, August 13, 2007

Running a batch in a hidden console window

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/running_a_batch_in_a_hidden_console_window.htm]

.Net allows you to run a batch in a hidden console window using System.Diagnostics. You can specify a ProcessStartInfo object (really a strategy pattern), and then run the process. This is useful when trying to integrate to other programs that only provide a command line interface.

This simple utility method also provides the ability to log the console output to some log file (specified with strLogPath). I have a simple unit test simply as a stub to see how the code is called. In this case, I call the "test.bat" file, passing in a single param "abc", ask the calling code to wait until the batch finishes, and then log it to a given path.

 

    [TestMethod]
    public void TestDiagnostics_1()
    {
      RunHiddenExecutable(@"C:\Temp\test.bat", "abc", true, @"C:\temp\log.txt");
    }

    public static void RunHiddenExecutable(string strFileName, string strArguments, bool blnWaitForExit, string strLogPath)
    {
      bool blnOutputLogFile = true;
      if (strLogPath == null || strLogPath.Length == 0)
        blnOutputLogFile = false;
      System.Text.StringBuilder sb = new System.Text.StringBuilder();
      try
      {
        //run in process without showing dialog window:
        ProcessStartInfo psi = new ProcessStartInfo();
        psi.WindowStyle = ProcessWindowStyle.Hidden;
        psi.CreateNoWindow = true;    //Need to include this for Executable version (appears not to be needed if UseShellExecute=true)
        psi.FileName = strFileName;
        psi.Arguments = strArguments;
        psi.UseShellExecute = false;
        psi.RedirectStandardOutput = true;

        Process p = System.Diagnostics.Process.Start(psi);
        sb.Append(p.StandardOutput.ReadToEnd());

        if (blnWaitForExit)
          p.WaitForExit();

      }
      catch (Exception ex)
      {
        sb.Append("Exception Occured:\r\n");
        sb.Append(ex.ToString());
        throw;
      }
      catch
      {
        sb.Append("A non-CLSCompliant exception was thrown.");
        throw;
      }
      finally
      {
        //Implement - log this however you want
        //if (blnOutputLogFile)
        //  Write out file (sb.ToString(), strLogPath);
      } //end of try

    } //end of method

 

See also: How to send the Console output to a string

 


Living in Chicago and interested in working for a great company? Check out the careers at Paylocity.

 

Thursday, August 9, 2007

Open up multiple tabs in IE7 from the command line

[This was originally posted at http://timstall.dotnetdevelopersjournal.com/open_up_multiple_tabs_in_ie7_from_the_command_line.htm]

I had a need to regularly view a quick collection of web pages, somewhat like a dashboard. Rather than manually click a bunch of links from my favorites, I just wanted a single click to open all the pages. I know that you can automate IE from the command line to open a single tab, like so:

 

"%ProgramFiles%\Internet Explorer\iexplore" http://www.msdn.com
 

... but I needed to open several tabs. I could then repeat this line multiple times, but that just opened multiple instances of IE instead of a single instance with multiple tabs.

 

MSDN blogger Tony Schreiner had a perfect solution using Windows Script Host (WSH). You can just have a single script open multiple tabs within a single IE instance, and then call that script with one click from the command line.


Living in Chicago and interested in working for a great company? Check out the careers at Paylocity.