Sunday, December 16, 2007

Resources for learning software development

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

I was thinking the other day how many different resources are out there to help someone learn software development. There's something to appeal to almost every style:

  1. Books
  2. Reference docs
  3. Articles
  4. Webcasts
  5. Podcasts
  6. Virtual labs
  7. Newsgroups, discussion forums
  8. Live Events
  9. Professional Groups
  10. Blogs
  11. Training (class room setting)
  12. Sample code - quickstarts
  13. Sample code - real projects
  14. Tutorials & Walkthroughs
  15. Local class at community college
  16. Bachelors or Master’s degree
  17. Teaching others (forces you to learn it)
  18. Write your own blog
  19. Personal pet projects
  20. Open source projects
  21. Your coworkers. A physically present person, who can look at your machine environment, can be the best way to learn.
  22. Private tutor – perhaps for introductory topics where such tutors are much more abundant.
  23. Certification

Any others that you've personally found helpful?
 

Thursday, December 13, 2007

Architecture: Keeping it non-exponential

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

Systems have a tendency to get more disordered. Architecturally, it's easy to always take shortcuts such that your application code becomes one big mess of tightly coupled objects and duplicated code. It starts innocent enough -you have only a few initial components, and each one has a dependency on the others. So that's still only a few dependencies.

But then, a few emergencies later (and what isn't an emergency?), your code has ballooned, and the dependencies have exponentially exploded into a mess. The project has accrued so much technical debt that the schedule is hopeless, and it's no longer fun. Every object is intertwined with every other object:

A much more sustainable model is to demand cleaner code at each step of the way, and end up with something maintainable, which the number of dependencies increases linearly with the number of new components. This lets you add, remove, and modify the code much more easily:

I see this as one of the basic issues of architecture: keeping the ever-growing code base in a maintainable state. In application development, this often boils down to conscious decisions where everyone "knows" the right way, but instead write sloppy code for ("we don't have time", "we'll fix it later", "this one won't hurt", "it works", "the maintenance team will fix it", etc...). Often, it seems like the team just needs a strong and credible voice to encourage everyone to do the right thing. Especially for long-term, enterprise projects, this seems like the optimal way to go. It sure beats having 12 months of garbled code.

Wednesday, December 12, 2007

SSN is not a secure password

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

I had a conversation the other day where SSN was considered viable to replace using a password. Yes, it simplifies single sign-in, but it has major consequences (and there are other ways to do single sign-in). Using SSN as a password is a bad idea, the kind of thing that blows up in your face with security and functionality problems.

  1. You can't change your SSN (unlike your password)

  2. SSN is too limited. It's merely a nine digit number, so it can't even pass strong password tests. Furthermore, the last 4 digits are often available (so down to 5 digits left), and there are rules that an SSN must adhere too (they aren't just any random 9-digit numbers). With less than 50,000 possibilities, it's fair game for a brute force attack.

  3. SSN is publicly available in many cases. For example, HR and managers can often see your SSN (but not your password).

  4. SSN has direct real life significance too, and is therefore immediately dangerous if lost. For example, if you lose a password, that's bad, but it's only dangerous if the hacker (A) knows the context - i.e. the system  to apply it to, and (B) the password hasn't changed yet. But the context for an SSN is immediately known (like any financial or government institution), and SSNs can't change.

What's your favorite Domain Specific Language?

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

I love domain specific languages (DSL). The idea is that instead of programming at a low level (i.e. tedious and error-prone), you program at a higher level of abstraction. This means coding with a language (or even class library) that closely maps to the problem domain. For example, here are several domain specific languages. While you could try to do without, it just becomes so much easier with them:

 

DSLPurposeExampleManually doing without:
Regular ExpressionsFind and replace patterns in textFind all numeric decimals in a fileYou could use core string methods like SubString and IndexOf
SQLManage database dataSelect all employees that meet a certain criteriaYou could do selects by getting the entire dataset and cycling through the object model
XPathQuery xml dataGet the custom order xml nodes where price is less than $100You could step through the xml with a reader, or loop through an XmlDocument
MSBuildMicrosoft's build engine to automate your processesCompile your application on a build server, run unit tests, and then produce MSI outputsYou could use System.Diagnostics to manually run a bunch of commands, and keep track of error conditions and logging output yourself.
String Format ExpressionsFormat a string using var.ToString("myPattern")Format the number 12.3456 to only two decimal placesYou could use core string methods, and pick apart the variable, and re-assemble it.

 

The point is that while someone could get by without knowing the appropriate domain language, it's just not practical to tackle the domain without it. Each of these has tons of tutorials and quickstarts, so there's no reason to avoid them. An application developer should probably be comfortable with most of these.

 

So, what's your favorite domain specific language?

Tuesday, December 11, 2007

Silverlight Image Utilities - clipping and shrinking an image to fit

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

For my TruckWars game, I needed to get the profile shot for an image. For example, when you select an object, it displays an image of that object in the dashboard. The two problems are:

  1. What if the image is bigger than the dashboard's profile size? (i..e image is 96x96, but the dashboard only allows 48x48).

  2. What if the image has multiple frames for animation (i.e. image displays as 48x48, but has two frames, and therefore actual size is 96x48).

I wanted a way that given any image, it would clip the image to a single frame, and then shrink it to fit within the allowed-profile size. You can do this if you know the actual image size. In this case, the size of the profile image in the dashboard is 48 pixels. Because I make the animation frames be horizontal (i.e. something with two frames is twice as wide), I scale the image based on height. Then I clip to just the first frame.

 

    public static void MakeProfileImage(ref Image image1, Size szActual)
    {

      //Scale back the img to fit to the view size
      const double profileHeight = 48;
      double dblScale = szActual.Height / profileHeight;
      image1.Width = szActual.Width / dblScale;
      image1.Height = profileHeight;

      //Always clip the view size (in case there were multiple frames for animation)
      RectangleGeometry r = new RectangleGeometry();
      r.Rect = new Rect(0, 0, profileHeight, profileHeight);
      image1.Clip = r;
    }

 

I added this to a ImageUtilities class for reuse later.

 

Monday, December 10, 2007

Silverlight and Globalization: System.FormatException from NumberFormatInfo

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

Through recent error-logging that I added to TruckWars, I found out the sometimes this line would fail:

 double x = Convert.ToDouble("12.5");

 

The input string was static (not user input) as it came from an xml config file. The line threw this exception:

System.FormatException: Input string was not in a correct format.
   at System.Number.StringToNumber(String str, NumberStyles options,
    NumberBuffer& number, NumberFormatInfo info, Boolean parseDecimal)
   at System.Number.ParseDouble(String value, NumberStyles options, NumberFormatInfo numfmt)
   at System.Double.Parse(String s, NumberStyles style, NumberFormatInfo info)
   at System.Convert.ToDouble(String value)

At first I thought "of course '12.5' is a valid double." And of course it worked on my machine, and all the servers I was checking. But, the logs still showed this occasional error. Then I thought - what if it's a globalization problem? In other words, for the "en-US" culture, "12.5" is a valid number, but not for other cultures. For example, this would fail for someone in France, where "12,5" is used for a decimal place (note the comma instead of the period).

 

So, I set up a unit test to check for a different culture:

[TestMethod]
public void ParseFromString_Global_Decimal()    
{      
  System.Globalization.CultureInfo culture =
  System.Globalization.CultureInfo.CreateSpecificCulture("fr-FR");
  System.Threading.Thread.CurrentThread.CurrentCulture = culture;

  //run my parsing method here

  //ensure that culture wasn't overridden:
  Assert.AreEqual(culture.Name,
   System.Threading.Thread.CurrentThread.CurrentCulture.Name);
}

And the test failed with the exact error that I expected. I could then fix it by passing in a specific culture (like "en-US") NumberFormat:

private static System.Globalization.NumberFormatInfo _formatNumber =
System.Globalization.CultureInfo.CreateSpecificCulture("en-US").NumberFormat;

//essentially fixed by this:
double x = Double.Parse("12.5", _formatNumber);

I don't normally get this error because for our ASP.Net apps I use a set of utilities that already handled this, and I didn't need to worry about international users for the  windows forms because I only make those for internal development tools. However, it's another reminder why it's nice to have logging for even simple apps.

Sunday, December 9, 2007

Becoming a credible developer

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

Every developer wants to be taken seriously. We want to be credible. But what makes someone credible?

 

I've seen a lot of devs who think that being credible means:

  • Sending out a link to a guidelines document

  • Keep referring to your  last project (that no-one else on your current team was on) as that perfect project

  • Throwing out buzzwords

  • Never admitting that you're wrong

The problem is that all of these require little effort and don't really help anyone else. They don't distinguish the speaker - anyone can send out links, bluff about a former project, or throw out buzzwords.

 

I think a much better way to see if some is credible is if they:

  • Have experience in the problem domain

  • Have work products they can point to (i.e "I made this website", "I wrote this tool")

  • Can accurately predict what will happen (not "try this", but rather" do this and you'll get that")

  • Have a reputation of being correct (including other credible people who will back them up - i.e. "good references")

  • Can point to the official source (not "I heard on some blog that...", but rather "The MSDN reference spec for C# 2.0 says ...")

  • Are willing to invest their own resources into the approach or product (i.e. dogfood it). If someone won't even put their own resources in, then they probably don't believe in the approach.

You can't easily bluff these things. For example, your prediction either comes true or it doesn't (if it's ambiguous, then it's a bad engineering prediction); you either have a concrete product you can show people, or you don't. I think every industry leader you find does these things - they have tons of experience and products, make accurate predictions, have a reputation that precedes them, they write the official source, and they dedicate their lives to their cause. Now that's being credible.