Tuesday, October 31, 2006

Regular Expressions: "Does not start with...."

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

 

A coworker recently asked me how to have a regular expression check if something does not start with a certain value. For example, how to tell if an input value does not start with 'abc'.

Note that it's very easy to see if something does start with a certain value, just use the anchor-to-first-start char '^'. For example, this regex will check for all strings that start with 'abc' (followed by any \w character(s)):

    ^abc\w+

To see that something does not start with a given value, use the Grouping Construct 'Zero-width negative lookahead assertion":

    ^(?!abc)\w+

This would handle the following cases:

Pass - none of these start with 'abc': Fail - all of these start with 'abc':
defg
ab
xyz
11999
abc
abcdef

Note that there are four similar grouping constructs based on the combos of Positive/Negative - Lookahead/Lookbehind

  • Positive Lookahead
  • Negative Lookahead
  • Positive Lookbehind
  • Negative Lookbehind

You can download a free regex editor from MVP Roy Osherove

Sunday, October 29, 2006

A Dozen Extracurricular Activities to be a Better Developer

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

 

I talk to a lot of developers, see a lot of resumes, and give a fair deal of interviews. One of the biggest gaps I see is a lack of any extracurricular activities - i.e. work-related tasks not required by your current job. Empirically, I notice a direct relationship between a dev's technical confidence and the quality of their extra curriculars. Here are some ideas of good extra curriculars that won't just make your resume stick out, they'll make you a fundamentally better developer.

  1. Write a technical article (such as for www.codeProject.com, or any website in the Codezone community).
  2. Start your own blog
  3. Give an internal presentation to your company
  4. Mentor newer developers
  5. Help out with your companies technical interviews
  6. Get a certification
  7. Get a patent (obviously not feasible with most companies, but the larger ones may support it)
  8. Start an open-source project
  9. Attend a user group (for example, if you're in Chicago, consider attending the Chicago .Net User's Group)
  10. Participate in online forums, answering others questions (which goes great with having your own blog and writing articles)
  11. Make your own personal website
  12. Help your non-technical friends set up their own web sites.

No matter where you are, there's likely at least some of these you could do in your current job.

Thursday, October 26, 2006

Why use Stored Procedures over direct SQL calls?

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

Two main ways to interact with the database: using a stored procedure vs. using a direct SQL statement. Here's a brainstorm of the pros and cons to each:

Technique (called from managed code): Pro Con
Stored Procedure
  • Performance, as SP is already on the database
  • Reusability - multiple sources (including other SP) can call a SP.
  • Security, especially against SQL injection attacks.
  • Maintainability - you can create the SP (and run and test it) in a database editor.
  • Powerful - A SP consists of multiple SQL statements.
  • Deployment - Modifying a database object is often easier than redeploying managed code.
  • Code Generation - You can code generate a data access layer off of stored procs (although most of the time it's code-generated off of table schemas).
  • Have to install each SP on the database
Sql Statement
  • Quicker to get started, especially for simple code and a RAD, non-production app.
  • Sql string is stored in managed code, so no need to install on the database.
  • Flexible - you're generating any SQL statement you want.
  • Lacks most of the benefits of a SP.

In general (of what I've seen), many enterprise apps will use Stored Procs, while sometimes a RAD will use raw SQL statements.

What has your experience been?

Wednesday, October 25, 2006

Getting data snapshots with the MassDataHandler

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

The other day I had a to investigate some data corruption. A certain table started out with one set of data, I ran an upgrade process, and QA told me it wasn't upgrading correctly. The problem was that I needed to compare two snapshots of SQL data, from the same table. I know there are many ways to solve this problem. The way I solved it was with the open-source MassDataHandler.

One of the main purposes of this free tool is to convert data back and forth between an Xml format and stored SQL data in a database. So, with the "Use Existing Data" feature, I took a snapshot of the table (using a select clause to specify the columns and order) and saved it as an Xml file. I then ran some black-box upgrade process, and took a second snapshot of the table. Because I now had two xml files, I could easily just diff them (I prefer using Beyond Compare for this).

The idea was to reduce the problem from an unknown state (how to compare Sql data) to a known one (how to compare two Xml files).

Tuesday, October 24, 2006

The MassDataHandler 1.2 has been released!

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

This is a free, open-source tool to assist with database unit testing. The new version offers several new features:

  • The GUI now offers the ability to ignore primary keys when generating from existing data.
  • The Build process has a reusable script to drop all foreign keys from a database. This makes it easier for you to adapt the demo script to your own project.
  • The Readme has been updated with better documentation.
  • A few miscellaneous bugs have been fixed.

You can download it here.

Monday, October 23, 2006

Comments as version control

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

At every company I've been, I see source code with old code commented out instead of deleted. In a sense, this is almost using commenting like a primitive form of version control. I see pros & cons to this approach:

Pro:

  • In environments where requirements constantly change, some developers are more comfortable seeing how the chuck was previously written so that they can easily revert.
  • You may be intending to switch back to the previous code, and it's easier to see it if the code is commented out, as opposed to digging through version control.

Con:

  • As Steve McConnell suggests in Code Complete, the purpose of comments is to show the intent of your code. Using comments as version control can be misguided.
  • It can imply a lack of confidence. If the code is really no longer used, why not just delete it and make your code leaner.
  • It can bloat the source code very quickly, requiring future developers to read through more.

I think ideally old and obsolete code should be removed instead of commented out (makes for leaner, easier-to-read code), but I can see the other approach in certain development cultures.

Sunday, October 22, 2006

How many ways to represent True and False

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

I was recently serializing data from both the database and user input, and it made me reflect on how many ways you can represent a boolean value as a literal string. For an English-language app (no globalization), here are several ways to represent a boolean:
  • TRUE / FALSE - converting from a literal string.
  • T / F - users who only want to enter the first character.
  • Yes / No - non-technical users who want "friendly" terms.
  • Y / N - again, users who want to only enter the first character.
  • 1/0 - A bit, such as how SQL Server stores booleans.

And of course, the first three options can be case insensitive and trimmed white space (i.e. "tRUe" becomes "TRUE").

I had talked about using Convert.ToString to convert different objects to string, so I'd initially look at it's related method: Convert.ToBoolean. But one quickly sees that that won't handle all the cases (and with good reason). The only literal string it takes from this group is "true"/"false". For example, it would handle converting the integer 1, but not the literal string "1". Having a single function that just converts these different inputs to a boolean is a nice convenience. Here's a sample:

public static bool ConvertToBoolean(string strVal)
{
  if (string.IsNullOrEmpty(strVal))
    return false;

  strVal = strVal.ToUpper().Trim();

  if (strVal == "TRUE" || strVal == "T" || strVal == "1"
    || strVal == "YES" || strVal == "Y")
    return true;
  else if (strVal == "FALSE" || strVal == "F" || strVal == "0"
    || strVal == "NO" || strVal == "N")
    return false;
  else
    throw new ArgumentException("Cannot convert '"
    + strVal + "' to Boolean.");
}

Wednesday, October 18, 2006

What to do before just asking someone?

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

Some projects have the local superstar. Any whenever anyone has a question, rather than figure it out for themselves (or even try to), they just ask their local star. There are two problems to this approach: (1) It eventually burdens that "star", and (2) It weakens the average guy's ability to find out info for himself.

Sometimes you need the answer right away, so you'll just ask someone. (And it would take too long to figure out yourself). However, most of the time it's worth first taking a stab at it yourself. Here are some ideas:

  • Tell yourself that you're just going to try for the next 5 minutes (If you say "I don't have 5 minutes", consider does anyone else?)
  • Read the documentation (feature spec, help doc, inline code comments, etc...)
  • Google the buzzwords, especially if it's a unique error message (like '__pendingCallbacks[...].async' is null or not an object)
  • Step back and think of the higher level concepts (maybe there's a knowledge gap you need to fill)
  • Step through the code in the debugger (such as to see the context it's being used in)
  • Use SQL Profiler to find data sources (what SP does this call?
  • Start at the problem and try working backwards
  • Find the steps necessary to deterministically reproduce the problem, then take a divide and conquer approach, checking each part of the code in isolation to see if it is the cause.
  • Work on something else and come back to the problem later with a fresh mind.

While having other star coworkers is a nice safety net, it is a luxury that may not always be there. And during those times, it will be nice to have had the practice at figuring out answers for oneself. Besides, the more someone practices at solving problems, the more likely it is that they'll become that goto guy that everyone else asks questions too.

Tuesday, October 17, 2006

Sql Tools - Profiler and SqlCommand

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

Everyone knows how to use SQL Management Studio, but there are two other useful tools that SQL Server 2005 has.

  • SQL Profiler - This lets you profile the SQL Server calls. It's very effective to determine what page is making which calls (and how long those calls take). It's much easier to just run profiler, as opposed to stepping through all the code to find what SP gets triggered when you click Button X.
  • SqlCmd - This is the command line for SQL Server (replaces osql for SQL 2000). It's useful when you need to Automate, or don't want the full SQL GUI installed (such as when you have limited space on a build server).

Monday, October 16, 2006

Converting to a string

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

In web development, we constantly need to get string values (from objects of different data types) that we can display to the user. For example, ints, dates, bool, and even custom objects eventually need to be rendered as some string. There are different ways to handle this conversion, but I think one of them is best.

      //Fail if type is wrong, such as an integer
      //Compile error: Cannot convert type 'int' to 'string'
      string s1 = (string)i;

      //Fails if object is null
      string s2 = i.ToString();

      string s3 = Convert.ToString(i);

As the code snippet shows, there are at least three standard ways: (1) casting, (2) calling the ToString method - which every object has, and (3) using the System.Convert class. I think the third way is often the best because the first will throw a compile error if the the object is an incompatible type (like converting a value type int), and the second will fail at run time if the object is null (not possible with value types like integers, but very likely with other reference types). However, using System.Convert handles both of these cases - you can convert value types and handle null instances of reference types. This lets you use a consistent approach for your conversions.

Sunday, October 15, 2006

'__pendingCallbacks[...].async' is null or not an object

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

I was doing so ASP.Net 2.0 callbacks (see an overview here: http://dotnet.sys-con.com/read/192509.htm), and kept getting this error when I did a document.location redirect on the ReceiveCallback JavaScript function.

Microsoft JScript runtime error: '__pendingCallbacks[...].async' is null or not an object

Looks like a flagrant Microsoft bug: http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=101974

People have different suggestions

What worked for me is the setTimeout. However, I needed to pass a parameter to the variable, so I used a technique like so:

var _gRValue;
function ReceiveCallback(rValue)
{
  _gRValue = rValue;
  window.setTimeout('__ReceiveCallback(_gRValue)',0);
}

function __ReceiveCallback(rValue)
{
  //Do stuff here
} //end of method
 

To handle the nature of setTimeout, I stored the returned data in a member variable.

Backwards: "I wanted to do Unit Tests, but my manager wouldn't let me"

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

I've heard this before when I give interviews or meet new developers at tradeshows.  The thinking seems to go that "While I'd personally love to do this best practice of 'Unit Tests', adding them takes a lot longer (like adding a new development phase), which costs extra money, therefore I need managerial approval." This is fundamentally backwards.

The whole point of Unit Tests is that:

  1. They save you time: Obviously with regression testing, but also by stubbing out the context so you can very quickly test things in isolation (without wasting tons of time constantly re-setting up that context). They also help you to see all the boundary test cases, and hence prevent future bugs.
  2. They are free to use - open source tools like NUnit can be downloaded for free and instantly used for your own personal development. It's not like you need to purchase a separate expensive tool, or hire out some auditor to review your code.
  3. You write tests as you develop, not afterwards.

Here's an analogy: Think of your schedule like a bucket, and your tasks are like rocks that fill up the bucket. You can't increase the size of your bucket, or decrease the number of rocks, therefore the bucket (i.e. your schedule) seems full. However, there are gaps between the rocks (just like there are gaps between tasks - like setting up the context and regression testing). You could pour sand into a full bucket, in the cracks in between the rocks. That's what unit tests are like. If you do them as you develop, you can squeeze them into your schedule without overflowing it.

Friday, October 13, 2006

What makes programming fun?

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

A brainstorm of some ideas. (Feel free to add your own in the comment section).

  • Writing new, interesting code
  • Not hunting down regression bugs
  • Not repeating yourself
  • Sharing work with others
  • Learning new things
  • Seeing your code just work

Certain methodologies, like Agile and TestDriven.Net are designed to fulfill many of these things. For example, by having sufficient unit test coverage, you minimize your regression bugs and get to focus more on new things.

Thursday, October 12, 2006

The myth of the "perfect past project"

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

In today's world, developers switch projects a lot. Whether it's a consultant at the same company who keeps jumping between 3 month projects, or a developer who switches jobs every two years, most people can refer to some "previous" job. I notice an interesting trend, that some people insist that they've had that perfect project in the past - the one (unlike their current job) where everything was done properly. It almost comes across as their development life was great before (i.e. their last job did it "right"), but their current employer is a bozo. Many people can refer to a good previous project because some other star (not them) made it good. For example, a past project may have had awesome process or tools - but someone else set it up. It seems like a bluff (or the grass is always greener on the other side thinking), but because you don't know about their previous project, and have to just take their word for it. But, you can always ask what they did to make that last project so great, and what they can do on the current team (besides just reminiscing about the "Good old days") to make the current project better.