Thursday, October 27, 2011

Occupy Stack Overflow!


image
Comparing cumulative reputation of users sorted by reputation vs. number of users.  Source:  StackOverflow Sept 2011 data dump file stackoverflow.com.7z, users.xml

Did you know that the top 1% of StackOverflow.com users own just under 60% of all reputation?  While the rest of us answer questions but seemingly get no farther ahead, Jon Skeet and his ilk get farther and farther ahead.  This situation is intolerable!

My modest proposal:  the bottom 99% of StackOverflow.com users occupy the site by posting questions with the text “We are the 99%” and tagging them with OccupyStackOverflow or OSO.  If you see these questions upvote them, then answer it with anything, like “Me too”, and then upvote all the other answers.  Power to the people!

If you don’t realize yet, I’m kidding about Occupy Stack Overflow.  But I’d like to compare the “inequality” on Stack Overflow with the “inequality” in incomes that the Occupy Wall Street movement appears to be concerned about, among other things. 

Stack Overflow’s design is such that almost every point of reputation is earned. There may be people who run around the site automatically voting up all of Jon Skeet or Mark Gravell’s answers, but for the most part the top 1%’s scores are a function of the long term consistent quality of their answers. We contributed to their scores because they answered our questions well and made our jobs easier. The top 1% hold 60% of the reputation but they’ve given us their knowledge in exchange.

Compare that to the top 1% of income earners in 2011.  Unless they’ve literally stolen money from others, or were given no-strings-attached money by the government to prevent their folly from impacting their own company, they owe us NOTHING. And I say still because they’ve already given us a lot. They’ve given us cheaper computers and smart phones and gasoline cheaper than beer every 10 blocks, access to our money almost everywhere, cars that go farther on less gas with less problems, and warmer/cooler/dryer houses. The Internet, entertainment, like TV shows, sports and video games.  Bicycles get better every year.  Drugs and technology that let us live longer lives with more healthy years.  Labour saving devices like dishwashers, frostless fridges, washing machines and dryers.  Clean drinking water.  Indoor toilets.  Ikea furniture.

Warren Buffet, LeBron James and Steve Jobs didn’t take their fortunes from anyone, and they weren’t handed it by the government.  They created wealth for others, entertained others and brought people incredible technological advances.  Their fortunes are not only the result of how good they are at their jobs, but also how many people can afford what they produce. 

Just like the top 1% of Stack Overflow’s users they translated their talents into rewards for themselves and a better life for many other people.  This is the invisible hand at its best.  To the 1% I say, keep up the good work!

P.S. I created a query on data.stackexchange.com that lets you find the percent of reputation found by the top x% of users here: data.stackexchange.com/stackoverflow/s/2001/reputation-inequality.

Monday, October 24, 2011

Music

Imagine it’s 1805 and you’re the Emperor of Austria.  You’ve commissioned a composer for a symphony.  He returns after just 3 days and delivers something he came up with by playing random notes on random instruments as fast as possible.

“Dies ist nicht Musik!” you say in German.  “This is not music!”

“Was?” replies the genuinely shocked composer in German.  “What?  These are all real musical notes on these sheets.  I certainly didn’t just pick random frequencies.   Did I not write parts for orchestral musical instruments?  I didn’t bang on trash bins and play empty jugs.”

“There’s no structure to it.  No melody, no chords, no counterpoints between instruments, no use of time signatures.  Just a long run-on sequence of random notes.  There’s nothing that we’ve learned about making orchestral music, or music in general, for the last 500 years.  I won’t pay,” you say.

“I’ll take you to court.  You asked for music and I delivered music,” threatens the composer.

(Let’s pretend this is a very democratic 1805 Austria and common citizens really can take the emporer to court and hope to win.)

“No reasonable person would consider what you’ve created music.  No musical theory would hold this as an example of an expression of that theory.”

The composer stews for a moment and then realizes that he’s out of his league.  He hangs his head and then looks up.

“I’ve seen symphonies performed.  They’re so complex and there’s so much structure to learn.  How can I even hope to do this in a reasonable time?” asks the composer.

“PRACTICE!”

A Real Life Example

I’ve seen real line-of-business web applications that are just page after page of this kind of thing:

ASPX File

<body>
<form id="form1" runat="server">
<div>
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="false">
</asp:GridView>
</div>
</form>
</body>


Code behind

protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
BoundField bf = new BoundField();
bf.DataField = "Title";
bf.HeaderText = "Title";
GridView1.Columns.Add(bf);
bf = new BoundField();
bf.DataField = "Year";
bf.HeaderText = "Year";
GridView1.Columns.Add(bf);
HyperLinkField hlf = new HyperLinkField();
hlf.HeaderText = "IMDB Link";
hlf.DataTextField = "ImdbUrl";
hlf.DataNavigateUrlFields = new string[] { "ImdbUrl" };
GridView1.Columns.Add(hlf);
using (ServiceReference1.MovieServiceClient mc = new ServiceReference1.MovieServiceClient())
{
var mvs = mc.GetMovies();
DataSet1.MovieDataTable mt = new DataSet1.MovieDataTable();
foreach (var mv in mvs)
{
var mr = mt.NewMovieRow();
mr.Title = mv.Title;
mr.Year = mv.Year;
mr.ImdbUrl = mv.ImdbUrl;
mt.AddMovieRow(mr);
}

GridView1.DataSource = mt;
}

GridView1.DataBind();
}
}


What?  It’s C#.  It compiles.  It even produces the required output.


If you are thinking these things without irony and sarcasm then please, please, please keep reading to find out why they’re ironic.


(I’m actually getting angry writing this code because of the pain I endure looking at this garbage every day.)


A difference between code and music is that even though the output that the code produces is correct the underlying stuff that produced it can fail to conform to any accepted theory of structure, called design patterns, or best practices, like the SOLID principles of object oriented programming.  It’s like using auto tune to correct someone who never learned to sing.  You just speak into the mic and a (somewhat) pleasing sound comes out the other end.


Another difference between a song and a program is that you don’t have to add things to a song or change it after it’s been finished.  The above program is fine to illustrate a point, like I’m doing, but it is not acceptable for any program that people will actually use.  They’ll eventually need a change or find a bug that will require updates.


A problem with this code, but not the main one, is the obtuse variable names.  What’s GridView1 supposed to represent?  Oh, a list of movies.  Let’s call it MovieGridView then.  Mc?  Oh, it’s the data service client.  Let’s call it movieServiceClient.  Bf used again and again to represent different things?  If we really need to add columns dynamically to a grid view how about separate instances with distinct names.  Mvs, mt, mr, mv?  Wtf?  Poor variable names make code much, much harder to maintain than it needs to be.


Here’s the same code with just the variable names updated:


ASPX File

<body>
<form id="MoviesForm" runat="server">
<div>
<asp:GridView ID="MoviesGridView" runat="server" AutoGenerateColumns="false">
</asp:GridView>
</div>
</form>
</body>


Code behind

protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
BoundField titleField = new BoundField();
titleField.DataField = "Title";
titleField.HeaderText = "Title";
MoviesGridView.Columns.Add(titleField);
BoundField yearfield = new BoundField();
yearfield.DataField = "Year";
yearfield.HeaderText = "Year";
MoviesGridView.Columns.Add(yearfield);
HyperLinkField imdbUrlField = new HyperLinkField();
imdbUrlField.HeaderText = "IMDB Link";
imdbUrlField.DataTextField = "ImdbUrl";
imdbUrlField.DataNavigateUrlFields = new string[] { "ImdbUrl" };
MoviesGridView.Columns.Add(imdbUrlField);
using (ServiceReference1.MovieServiceClient movieServiceClient = new ServiceReference1.MovieServiceClient())
{
var moviesFromService = movieServiceClient.GetMovies();
MovieDataSet.MovieDataTable movieTable = new MovieDataSet.MovieDataTable();
foreach (var movie in moviesFromService)
{
var movieRow = movieTable.NewMovieRow();
movieRow.Title = movie.Title;
movieRow.Year = movie.Year;
movieRow.ImdbUrl = movie.ImdbUrl;
movieTable.AddMovieRow(movieRow);
}

MoviesGridView.DataSource = movieTable;
}

MoviesGridView.DataBind();
}
}


Now other folks’ brains don’t need to work nearly as hard to understand the intent.  We’re still using a DataSet to store non-SQL data internally, which is depraved, but I’m just mirroring what I see every day.  I also didn’t bother to re-add the service reference with a better name.


But here’s the biggest problem with this code:  no separation of concerns.  I’m talking about the S in SOLID, the Single Responsibility Principle.  This states that a class should be responsible for only 1 aspect of the application.  “A class should have 1 and only 1 reason to change”. 


In general, a “data over textboxes” app like the one above has 3 main aspects:



  1. moving data to and from a source
  2. formatting data/interpreting user input
  3. presenting data.

A single class currently handles all 3 of these aspects, the code behind.  Oh, you didn’t realize that it’s a class and should be treated like any other?  The declaration “public partial class” before the name of the page in the code behind wasn’t a clue?


Multiple aspects will require a change to this 1 class – a change in the data source, a change in the internal data model (the DataSet), a change in formatting of an existing field, or a requirement to get updated data some time after the initial page load.


There should be at least 3 more classes:



  1. One with a method named something like GetDataForInitialPageLoad that takes the page as an argument.  This will be called from within the if (!IsPostBack) block and pass the page in using the “this” keyword.  The method will use the next class to get data and wire it to the page’s GridView.  This class houses business logic.
  2. One with a method named something like GetMovies that retrieves data from the service and uses the next class to convert it from the service’s format to a DataTable.  GetDataForInitalPageLoad would call this method.
  3. One with a method named something like Convert that takes the service’s output as input and returns a DataTable.

In addition, the GridView fields being added in code should be specified in the ASPX file.


Now, if any 1 of the aspects I mentioned above change, only 1 class needs to change and you know no other aspect of the app has changed.  This cuts down on the testing needed and dramatically lowers the odds of inadvertently introducing a change in an unrelated aspect.  It also sets you up to follow the rest of the SOLID principles and allows unit testing.


My favorite pattern for separating concerns when developing WebForms is Model-View-Presenter.  The ASPX page and code behind are the View, some business logic class specific to the view is the Presenter, and the DataSet, converters and service comprise the Model.  The refactored version of this app using MVP follows below.  You’ll see that there’s not much more code, but there are more classes and interfaces.  The biggest leap to make is grasping the concept of the Single Responsibility Principle and the way the presenter and view share things.


But after you grasp it, you have to try implementing it again and again until it becomes second nature.  Learn the VS2010 shortcut keys for creating classes and code snippets for adding properties.  It’s a pattern; it’s not different every time.  Once you learn the pattern it will flow from your brain to your code just as quickly as mvs=mc.GetMovies().


Conclusion


Whether you’re the Emperor of Austria in 1805 commissioning a symphony or a private citizen in 2011 commissioning a piece of art you wouldn’t accept something that didn’t follow some well known precepts of the medium in which your artist works. No true artist would try to deliver something that they didn’t feel was an expression of some theory which they’d studied, if only a little. The more studied and practiced the artist the quicker they can produce works that conform to that theory. The top notch ones even expand on the theory.


So why is is that people who call themselves programmers think it totally acceptable to produce code that meets requirements but follow none of the best practices determined over the last 40 years?


I once sat in a class where the instructor went over the Model-View-ViewModel pattern in Silverlight and how, like any pattern that separates concerns, it leads to much more maintainable code. A “developer” put up his hand and asked “Yeah, but what if you’re trying to meet a deadline?” The instructor replied, “The more often you implement this the faster you’ll get".”


In other words, PRACTICE! 


Code Plz


The ASPX File

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="NotTheWayItsDone.aspx.cs"
Inherits="Wrong.NotTheWayItsDone" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="MoviesForm" runat="server">
<div>
<asp:GridView ID="MoviesGridView" runat="server" AutoGenerateColumns="False">
<Columns>
<asp:BoundField DataField="Title" HeaderText="Title" />
<asp:BoundField DataField="Year" HeaderText="Year" />
<asp:HyperLinkField DataNavigateUrlFields="ImdbUrl"
DataTextField="ImdbUrl" HeaderText="IMDB Link" />
</Columns>
</asp:GridView>
</div>
</form>
</body>
</html>


Reasoning


The ASPX file is all about display.  Unless you’re adding columns dynamically to the GridView, specify here which data go in which fields and how they should be formatted.  Wire up client-side JavaScript calls here.  Use HTML class attributes to let CSS do its thing.  You get a pretty good preview of what things will look like.  You’ll go from this:


image


to this:


image


You can also start splitting the work between developers without everyone working on the same file.


Code behind

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.UI;
using Wrong.ServiceReference1;

namespace Wrong
{
/// <summary>
/// Really this is a page that displays a list of movies
/// </summary>
public partial class NotTheWayItsDone : Page, IMoviesView
{
/// <summary>
/// Class that contains business logic
/// </summary>
private readonly MoviesPresenter presenter;

/// <summary>
/// Initializes a new instance of the NotTheWayItsDone class.
/// </summary>
public NotTheWayItsDone()
{
// Pass this page instance to the presenter. Specify the IMovieService implementation to use, as per Inversion
// of Control principle.
// The presenter sees only the items defined in IMoviesView
this.presenter = new MoviesPresenter(this, new MovieServiceClient());
}

/// <summary>
/// Handles the Load event of the Page control.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
this.presenter.OnViewInitialized();
}
}

/// <summary>
/// Populates the movies onto the view.
/// </summary>
/// <param name="movies">The movies.</param>
public void SetMovies(MovieDataSet.MovieDataTable movies)
{
this.MoviesGridView.DataSource = movies;
}
}
}


Reasoning


The code behind file’s job is to react to events from the user and communicate data to and from the Presenter, which implements business logic.  That’s all.  No retrieving data.  No left hand-right hand code transforming data from one format to another.  No adding visual elements that don’t appear conditionally. 


It shares information with the Presenter by implementing an interface that the presenter knows about.  In this case, a method that allows the Presenter to hand the GridView some data, and we’ve exposed Page.DataBind.


The presenter doesn’t know that a GridView will receive the data.  It’s the View’s job to present the data to the user properly.  We could change the View to use a ListView and the presenter would be none the wiser.


We’ve exposed DataBind so that the Presenter can let the View know when it’s time to bind.  This is useful if you’re not using DataSource-type objects to receive data in your view, which would normally detect changes to source data and call DataBind for you.


Another class should implement business logic, like “when save is clicked, gather entered data and put it in the repository.” 


The View Interface

using System;
using System.Collections.Generic;
using System.Linq;

namespace Wrong
{
public interface IMoviesView
{
/// <summary>
/// Populates the movies onto the view.
/// </summary>
/// <param name="movies">The movies.</param>
void SetMovies(MovieDataSet.MovieDataTable movies);

/// <summary>
/// Causes the view to bind data-bound controls to their source data.
/// </summary>
void DataBind();
}
}


Reasoning


The documentation in the interface and the code behind reasoning should suffice.


The Presenter

using System;
using System.Collections.Generic;
using System.Linq;
using Wrong.ServiceReference1;

namespace Wrong
{
/// <summary>
/// Contains business logic for the movies view (page)
/// </summary>
public class MoviesPresenter
{

/// <summary>
/// Initializes a new instance of the <see cref="MoviesPresenter"/> class.
/// </summary>
/// <param name="view">The view.</param>
/// <param name="movieService">The movie service.</param>
public MoviesPresenter(IMoviesView view, IMovieService movieService)
{
this.View = view;
this.MovieService = movieService;
}

/// <summary>
/// The movie service
/// </summary>
protected IMovieService MovieService { get; private set; }

/// <summary>
/// Gets or sets the view.
/// </summary>
/// <value>
/// The view.
/// </value>
protected IMoviesView View { get; set; }

/// <summary>
/// Called by the view when it is first loaded.
/// </summary>
public void OnViewInitialized()
{
var moviesFromService = this.MovieService.GetMovies();
MovieToMovieDataSetConverter converter = new MovieToMovieDataSetConverter();
using (MovieDataSet.MovieDataTable movieTable = converter.ConvertAllFrom(moviesFromService))
{
this.View.SetMovies(movieTable);
}

this.View.DataBind();
}

/// <summary>
/// Releases unmanaged resources and performs other cleanup operations before the
/// <see cref="MoviesPresenter"/> is reclaimed by garbage collection.
/// </summary>
~MoviesPresenter()
{
IDisposable moviesServiceAsDisposable = this.MovieService as IDisposable;
if (moviesServiceAsDisposable != null)
{
moviesServiceAsDisposable.Dispose();
}
}
}
}


Reasoning


This is where all the action is.


The constructer requires an instance of something that implements IMovieView.  Typically this is the page, but for unit testing purposes you could pass in an object that implements the same interface.  It also needs the movie client implementation specified to it.  (WCF ) This is an example of the Inversion of Control principle.


In the destructor we need to check if the movie client requires disposing.  The real WCF client does, but any pretend versions used for unit testing doesn’t necessarily.


The Converter

using System;
using System.Collections.Generic;
using System.Linq;
using Wrong.ServiceReference1;

namespace Wrong
{
class MovieToMovieDataSetConverter
{
/// <summary>
/// Converts all from.
/// </summary>
/// <param name="moviesFromService">The movies from service.</param>
/// <returns>A MovieDataTable populated with the data from moviesFromService</returns>
public MovieDataSet.MovieDataTable ConvertAllFrom(Movie[] moviesFromService)
{
MovieDataSet.MovieDataTable result = new MovieDataSet.MovieDataTable();
foreach (Movie movie in moviesFromService)
{
result.AddMovieRow(this.ConvertFrom(movie, result));
}

return result;
}

/// <summary>
/// Converts from.
/// </summary>
/// <param name="movie">The movie.</param>
/// <param name="movieTable">The result.</param>
/// <returns>A MovieRow based on the movieTable parameter and populated with the data from the movie parameter</returns>
public MovieDataSet.MovieRow ConvertFrom(Movie movie, MovieDataSet.MovieDataTable movieTable)
{
var movieRow = movieTable.NewMovieRow();
movieRow.Title = movie.Title;
movieRow.Year = movie.Year;
movieRow.ImdbUrl = movie.ImdbUrl;
return movieRow;
}
}
}


Reasoning


This class’s only function is to populate a DataTable with incoming data.  If the incoming data type or the DataTable changes then only this class needs to change.

Wednesday, September 14, 2011

ASP.NET 4.0 Menu Outputs a Table or Anchors Instead of an Unordered List

 

The Short Answer (In My Case, Anyway)

A configuration setting in web.config is causing the .NET 3.5 behaviour of outputting a table or a set of anchors.  The setting is:

<pages controlRenderingCompatibilityVersion="3.5" />

Remove this to get the desired 4.0 behaviour of building an unordered list. Visual Studio added this because you created your project using .NET 3.5 then changed the version to 4.0. Um, thanks, VS.


The Long Answer


I’ve spent the last few days trying to understand why my instance of a Menu control was creating a table and not an unordered list. It’s a .NET 4.0 site and every test 4.0 app I’ve created has produced an unordered list.


I thought maybe it was because I was using a SiteMapDataSource. I tried defining the items within the Menu control, but this made no difference.


Maybe it was because I was using WCSF to create populate the SiteMapDataSource. So I created a new WCSF-based project and found it output an unordered list. So nothing in WCSF was triggering the behaviour. I studied the code generated in a new ASP.NET 4.0 website (the non-empty template) and in a new WCSF and I couldn’t find anything different.


Some Googling finally revealed that certain controls look at a configuration setting called controlRenderingCompatibilityVersion to decide how to act. This isn’t normally present. It gets set when you change your web project from 3.5 to 4.0. Once I read this I remembered accidentally creating my app targeting 3.5 and then switching to 4.0.


This appears to be the only significant change to a web app when switched to 4.0.  Lots of entries disappear from web.config. This is probably because 3.5 is really a bunch of extensions to 2.0, and all of the extensions are now just part of 4.0. 


This config setting sounds like it will make Menu act the same way under 4.0 as 3.5, but it turns out that’s not true.  Native 3.5, 3.5 “compatibility” under 4.0 and native 4.0 Menus all produce unique HTML.  Let’s have a look.


Create a new 3.5 ASP.NET website (the non-empty template) in Visual Studio 2010 and add:


  1. A Sitemap file with the default name of Web.Sitemap.  Make the contents
    <?xml version="1.0" encoding="utf-8" ?>
    <siteMap>
    <siteMapNode title="Home" >
    <siteMapNode title="Services" >
    <siteMapNode title="Training" url="~/Training.aspx"/>
    </siteMapNode>
    <siteMapNode title="Services" >
    <siteMapNode title="Training" url="~/Training2.aspx"/>
    </siteMapNode>
    </siteMapNode>
    </siteMap>
    

  2. A SiteMapDataSouce in Default.aspx, e.g.
    <asp:SiteMapDataSource ID="SiteMapDataSource1" Runat="server" ShowStartingNode="false" />

  3. A Menu control in Default.aspx, e.g.
    <asp:Menu runat="server" ID="MenuTest" DataSourceID="SiteMapDataSource1" Orientation="Horizontal">

Now run it and take a look at the source:

<span><a class="MenuTest_1" href="javascript:__doPostBack('MenuTest','oServices')">Services<img src="/WebResource.axd?d=wAEvwChqppIeDD27eosuLSSKK1v72lmXTc50uPK75upm7hfsxNhE9GeVh7SSC19_P7eqejSkCMIMAhKEvlwbQTVPYtk1&amp;t=634244938920000000" alt="Expand Services" align="absmiddle" style="border-width:0px;" /></a></span>
<span><a class="MenuTest_1" href="javascript:__doPostBack('MenuTest','oServices')">Services<img src="/WebResource.axd?d=wAEvwChqppIeDD27eosuLSSKK1v72lmXTc50uPK75upm7hfsxNhE9GeVh7SSC19_P7eqejSkCMIMAhKEvlwbQTVPYtk1&amp;t=634244938920000000" alt="Expand Services" align="absmiddle" style="border-width:0px;" /></a></span>

A messy set of spans and anchor tags.

Upgrade the project to 4.0, run it again and look at the source code:

<table id="MenuTest" class="MenuTest_2" cellpadding="0" cellspacing="0" border="0">
<tr>
<td onmouseover="Menu_HoverStatic(this)" onmouseout="Menu_Unhover(this)" onkeyup="Menu_Key(event)" id="MenuTestn0">
<table cellpadding="0" cellspacing="0" border="0" width="100%">
<tr>
<td style="white-space:nowrap;"><a class="MenuTest_1" href="#" style="cursor:text;">Services</a></td>
<td style="width:0;"><img src="/WebResource.axd?d=Jl7bM-JFbdoWBEh7C2q3EyZR8K6O6d4YLATzREzpY2ex3k5XYksROon9Z1cxmO8alNxDSkn-ofGqiqw-z6u74-AwPDdR9USUgzqIlqL9sBA1&amp;t=634486182303750217" alt="Expand Services" style="border-style:none;vertical-align:middle;" /></td>
</tr>
</table>
</td>
<td onmouseover="Menu_HoverStatic(this)" onmouseout="Menu_Unhover(this)" onkeyup="Menu_Key(event)" id="MenuTestn1">
<table cellpadding="0" cellspacing="0" border="0" width="100%">
<tr>
<td style="white-space:nowrap;"><a class="MenuTest_1" href="#" style="cursor:text;">Services</a></td>
<td style="width:0;"><img src="/WebResource.axd?d=Jl7bM-JFbdoWBEh7C2q3EyZR8K6O6d4YLATzREzpY2ex3k5XYksROon9Z1cxmO8alNxDSkn-ofGqiqw-z6u74-AwPDdR9USUgzqIlqL9sBA1&amp;t=634486182303750217" alt="Expand Services" style="border-style:none;vertical-align:middle;" /></td>
</tr>
</table>

Now it’s a messy table.

Finally, remove the controlRenderingCompatibilityVersion setting from web.config and look at the source:

<ul class="level1">
<li><a>Services</a><ul class="level2">
<li><a class="level2" href="/Training.aspx">Training</a></li>
</ul></li><li><a>Services</a><ul class="level2">
<li><a class="level2" href="/Training2.aspx">Training</a></li>
</ul>
</li>
</ul>

A nice, clean unordered list.

I really don’t understand why the controlRenderingCompatibilityVersion setting doesn’t produce exactly what a 3.5 Menu does, but I don’t care that much. I just want my unordered list, and now I know how to get it.

This is the kind of thing for which people criticize ASP.NET WebForms. Some people want almost complete control over the HTML that a framework produces, which leads them to ASP.NET MVC, Ruby on Rails et al. Those are great, but WebForms hasn’t grated on me that much in my life so I‘m nowhere near ready to give up on it. People’s lack of understanding of event-based web programming and getting data directly from the page code-behind has lead to far worse headaches for me.

MS Test, the unit testing framework built into Visual Studio, on the other hand…

Sunday, July 10, 2011

Four Types Of Programmers

 

I recently rewrote some code that calculates the distance between 2 latitude/longitude coordinates.  I was using a method that used Pythagoras, which assumes Earth is flat.  Apparently this works well for distances under 20 km, but my app needs to deal with all of Ontario, which is larger that 20 km.  I came across the haversine formula, which assumes a spherical Earth.  Still not 100% accurate (the Earth is an ellipsoid, and has mountains and valleys) but much closer.

Some of the example implementations I found in JavaScript (about 1 screen down) and C# were oddly similar.  Same variable names, no code comments that indicate an understanding of the algorithm.

I sat with the Wikipedia article open in one window and the JavaScript version on the other until I understood what was going on.  (Basically,  haversin(x) = (sin(x/2))^2 so you can use a language’s sin function to calculate it.)  Though, I still don’t understand why atan2 is used to calculate the inverse of haversin and not arcsin (or even what atan2 does).  My inverse implementation uses arcsin, but I wrote a parallel one that uses atan2 and gives the same result for the few unit tests I wrote.  Given that these are trig functions I ‘m pretty confident this isn’t a coincidence. 

I was happy with my implementation, but a few things still bothered me.  What’s the relationship between atan2 and arcsin?  What’s the derivation of the haversine formula?  It should be high school or first year trig, but I don’t get it.  I could probably keep Googling and refresh my knowledge at Khan Academy, but I’ve spent enough time for now.  I have a house and family to tend to too.  (This was a personal project so no employer time was harmed in the writing of this article.)

But it got me wondering about the thinking behind the C# example I found vs. what I did.  I think you could tell the difference between 4 types of programmers with this interview question:

You’re writing an app that needs a mathematical algorithm.  Nothing too fancy, but the math is just a little beyond you because it’s been 10 to 15 years since you really understood trig/calculus/algebra/stats.  You Google for it and find the following:

  1. Info on the theory behind the algorithm on, say, Wikipedia
  2. Some code example in your programming language on various websites

How do you proceed?

This shouldn't be presented as multiple choice.  You’re looking for answers of the following types:

A.  Copy the code examples into your code and move on.
B.  Use the code examples as inspiration for you own version, perhaps with a little refactoring and variable renaming and move on.
C.  Use the Wikipedia article to write your own implementation from scratch, adding comments to document what each complex bit does, and move on.
D.  Do C and spend some time trying to understand how the algorithm was derived and why it works.

If you answered A you now have 2 problems.  You now have code that you can’t support because you don’t understand it, and it’s probably a copyright violation.  SCO will find you.  Next applicant please.

If you answered B you’ve avoided the copyright problem but you still don’t understand the algorithm.  Junior programmer material.

If you answered C, nice work.  You have code that you understand and that others can understand.  It’s a well known algorithm so it’s not vital that you can explain why it works.  Just keep the URLs to your research handy, or add them to your comments for justification.  Welcome, new senior developer.

If you answered D there is a follow up question – how much time did you spend?  An hour or two, or did you get lost down a rabbit hole and spend a whole afternoon (as I did)?  If you spent just a couple of hours you get the team lead job, whether you stopped because you figured things out or you knew enough to not spend any more time.  If you spent a whole afternoon, you still get the senior developer position, but you need to learn some hardcore time management skills before advancing.

Diving deep into a problem is pretty typical of good coders but the very best keep this tendency in check.  This is where a personal system of organization can save you from rabbit holes.  Or at least let you get your code out the door and look into the lingering details at an appropriate time.

 

PS:

I now understand the relationship between arcsin and atan2, and why the JavaScript examples are written the way they are.

First, the inverse of haversin(x) is

haversin-1(x) = 2sin-1(√x)

Second, the relationship between arcsin and arctan is

sin-1(x) = tan-1(x/√(1-x2))

So,

haversin-1(x)= 2tan-1(√x/√(1-x))

When x > 0 the atan2(y,x) function in most languages gives you

tan-1(y/x)

So,

haversin-1(x) = 2*atan2(Math.Sqrt(x)/Math.Sqrt(1-x))

I suppose this is a handy definition for those languages that don’t have an inverse sine function but do have inverse tan.

I still don’t understand why the haversine function works, but that’s fine.  I’m now confident my implementation that uses inverse sine is equivalent and I’m moving on.

Friday, July 1, 2011

The Three Types of Project Documents

 

All project documentation can be given one of the following classifications:

  1. Bridesmaid dress
  2. Christmas tree
  3. Monument

The first 2 were inspired by a line from Fight Club (about 1/4 of the way down).  Here’s how to tell which type you’re working on, with examples and how much time you should spend on each.

 

Bridesmaid Dress

A bridesmaid dress is important only to the bride, costs serious money and is thrown away after 1 wearing.  A bridesmaid dress document is a document that is just as expensive to create as any other document, whose sole purpose is to fulfill a process requirement, and read only once, if at all.

Like any other project document someone has to spend time filling in the control sections (e.g. version history, links to other docs, approver list, distribution list), in addition to crafting the real content.  The control sections take longer to fill out than the real content.  The content usually comes from a source to which project members already have access and could look up themselves if they really cared.  Project members must attend a meeting to review it.  Real time is spent, not just 1 person’s afternoon.

It is important only to the project manager because she is the one responsible for championing the process.  Mind you, it’s not her fault that it has to be completed, she’s just doing her job.  No one else really cares about it, though.

Only a few lines are relevant; many other pages won’t be read.  Even the relevant sections will be read only once, and only by the people for whom it really is relevant.  It might require 5 people to sign off, but only 1 will actually care about the contents.  Bridesmaid dress documents could easily be replaced with a maximum 10 line email, but no one creates template emails for projects.  Only a 10+ page Word template with a ton of control content will do.

An example is a test stage exit report.  Only the page with the defect status count summary is read by those interested.

As little time as possible should be spent crafting such a doc.  If you are starting from a template leave as many sections “N/A” as you can.  Only fill them out if someone asks, and even then with the bare minimum.


Christmas Tree

A Christmas tree costs time and money to assemble.  But the cost is borne because it is vital to those celebrating Christmas, and everyone benefits.  It’s enjoyed for weeks at a time, but after Christmas is thrown away or put back in the box for another year.

As with any project documentation, it costs real time and money to produce.  The template has all the same control sections as any other doc, like the bridesmaid dress doc, but the content takes much longer to produce than the control sections.  Team members review it, make changes that make it better and really read it before signing off.  People spend serious time on the doc but it is well justified.

A document of this type is a real necessity for the project.  Without it you couldn’t have the project.  People look at multiple sections multiple times throughout the duration of a project because it has useful, important information that project members must reference .  This doc is the first time in which this content appears – it’s not just a summary of other content.  The information feeds people’s efforts.  But it’s context is still limited to the project itself.

At the end of the project, though, the document itself is forgotten.  The content itself should be incorporated into a monument document.  Failure to do so will cause many future headaches because information is spread across multiple documents that no one can find.

An example is project business requirements for an application or system.  There’s nothing for a project to do without requirements.  They’re specific to the project, though, so they only express the changes, not the whole application or system.  By themselves they’re pretty useless to other projects, especially after the same requirement has been changed in a few projects.  They need to be added to a monument document to make sense across projects.

It’s totally appropriate to spend time on a Christmas tree document.  Everyone must remember, though, that it will be tossed aside or put away after the project and that the content must be put into a monument document to stay relevant.  Link to as many other project and monument documents as possible – don’t copy and paste content.  This is a waste of your readers’ time, and you’ll just have to spend time updating your copy when the source content changes.

Monument

A monument costs a lot of money, is relevant to many people and is used and lasts a long time.  Think war memorials, gravestones, the pyramids.

A monument document template has all the control sections of the other two, but are a tiny fraction of the total content.  The cost of producing the information may have been paid in previous projects.  Indeed, if you’re doing things right the content should already exist in Christmas tree documents, short of a complete rewrite of an existing monument document.  You’ll pay some time incorporating and reviewing new information, especially if the new info supersedes old info.  It’s well worth the cost, though, because people will be able to reference this one true source of information years later.

And people will reference it. This will be the authoritative source of knowledge about what a system should do, how it does it, how to test it or how to use it.  It will be your starting point for creating project Christmas trees and bridesmaid dresses.  Folks will actually enjoy reading it because it will be the one doc that others really care about and want to ensure its usefulness.  When you update it you’ll feel like you’re making a real contribution to something that will last longer than your employment at the company.

Which leads into the lifespan of a monument document.  It will be around as long as the thing it describes.  This could span a decade, even in technology.  I personally have worked on live code that is literally 10+ years old.  If a design doc had been written when the code was written people would still be updating it today.

Examples of monument documents are application or system design, or system/application requirements.  It doesn’t have to literally be a document, either.  A database of test cases or requirements would count too.  Really, anything that aggregates project-to-project changes and is kept up to date.

This is where anyone should spend serious time.  This is the most valuable type of document a company can own.  It will cut down on  new hires ramp up time.  It will be invaluable when you rewrite an application 5 years from now.  It will save you from mistakenly asking for a change that will affect changes made last year.  Such documents ARE your business.

This has been a summary of the three types of project document.  Hopefully it will help you spot the differences so that you spend the right amount of time on each one.

Monday, June 13, 2011

My Little Fermat

Fermat

I didn’t have the heart to tell him that there is already a proof for when x>2.  He was just so happy with himself!

Tuesday, April 5, 2011

Everything That Glitters Isn’t Gold, But It May Be An Overpriced Used Car

Some signs a dealership paid too much for the used car you’re looking at, and won’t let it go for very much under asking:

  1. It’s parked out in front of the dealership.  A dealership that also sells new cars of the same brand, that is.  As in, “look at this great car as you drive by and come in and ask about it!”
  2. The engine is clean.  Very clean.  I mean like it just came from the factory.  Stickers are vibrant, metal gleams, even the black plastic is coated in something that makes it gleam.
  3. The dealership is not serious about negotiating for your trade-in that is in above average shape.  They start waaaay below average wholesale, and won’t even consider offers near the average.

This was our experience recently when my wife and I tried to negotiate for a used Honda Element. 

When I saw the condition of the engine I thought all dealerships shined used cars inside and out.  Not so.  It was definitely an above average vehicle for it’s age (2008, ~55,000km), but it was dressed up and shown off out front. 

We may have been coming in a little low, but still above average.  We were sure the tires wouldn’t be replaced as part of Honda’s certification process.  They’ll replace tires under “40%”.  Considering the rest of the truck’s appearance I’m sure they would have already replaced the tires if they were below minimum.  They looked to be down to about 4mm, and would probably need replacing in about 6 months.  That was a $1000 cost we didn’t want to incur so soon after purchase. 

They sure didn’t seem to think too highly of our offer, and were obviously not interested in our trade-in.  For a car we could probably have gotten around $10,000 if sold privately they offered just $6000.  Basically, get your stinking car off my lot, you damn dirty apes.

So we walked.

They didn’t call us back.

We ended up finding a less “prestigious”  Element at another dealership that was willing to be reasonable.  It will come with new tires.

Saturday, February 19, 2011

References

I would have thought the following was Visual Studio 101, but I’ve seen senior people confused by this, so I will elaborate.

If you’ve ever expanded the References section of a .NET Visual Studio project then you’ve seen the list of DLLs that your project can access.  Most of the items in a typical list are .NET Framework DLLs.  These are the Release build of DLLs, and they live in the GAC, or maybe somewhere in some Program Files directory if they are little extra packages, like the Silverlight Map Control.  Changing your project from Debug mode to Release mode doesn’t change the DLL link.  There’s only 1 available, the Release mode DLL from Microsoft or whoever.

Now, if you have a project in your solution that another project in your solution uses, (e.g. the business layer that your UI layer calls into) then there are at least 2 ways to add a reference.  One is a bad idea, and one is a good idea.  One way, the bad way, is the same as the references to framework DLLs – by referencing a particular DLL on disk.  The other way, the right way, is a project reference, which makes Visual Studio aware that project x depends on project y in the same solution.

If when adding a reference to another project in your solution you are using this tab then you’re doing it wrong:

image

See how you’re specifically selecting the debug version of a DLL in your project?  What will happen when you switch to Release mode and build your application?  It will include the debug version of this DLL, if it’s available on disk.  Not good.

The right way to set up a reference to another project in your solution is to use the next tab to the left, the Projects tab:

image

By using the Projects tab you get the following behaviour – when you switch your solution between Debug and Release build modes each project will use the corresponding build mode DLL from referenced projects.  That is, in Debug mode all Debug builds of referenced projects will be built and loaded.  In Release mode, all Release versions will be built and loaded.

There are a couple of ways of detecting references that were added using the Browse tab rather than the the Projects tab.  One way is to open .csproj files with a text editor and look for the following, which indicates a project reference:

<ProjectReference Include="..\DrinkLocatorMvvm.Data\DrinkLocatorMvvm.Data.csproj">

A non-project reference to a specific file will look like this:

<Reference Include="HtmlAgilityPack, Version=1.4.0.0, Culture=neutral, PublicKeyToken=bd319b19eaf3b43a, processorArchitecture=MSIL">

followed by a HintPath entry, which helps Visual Studio find the DLL on disk:

<HintPath>DLLs\HtmlAgilityPack.dll</HintPath>

If you don’t like looking at .csproj files then a dead give away is the behaviour of reference paths when you switch from Debug to Release.  Put your solution in a particular mode, say Debug.  Right click on the reference in one project to a DLL that you know is in another project in your solution, select Properties and make a note of the Path.  For example:

C:\Users\jmclachl\Documents\Visual Studio 2010\Projects\DrinkLocatorMvvm\Lcbo.Model\bin\Debug\Lcbo.Model.dll

Now switch your solution into the other mode, say Release, and check the Path property of the same reference.  If it has changed to the corresponding DLL version, then you’re looking at a properly set up project reference.  For example:

C:\Users\jmclachl\Documents\Visual Studio 2010\Projects\DrinkLocatorMvvm\Lcbo.Model\obj\Release\Lcbo.Model.dll

If it doesn’t change then the reference was added as a file reference with the Browse tab.  Remove the reference and re-add it with the Projects tab.

Using file references, added with the Browse tab, may build fine in one mode, e.g. Debug.  But if you, or someone else who has checked out the project from source control, perform a Clean before a Release build the compile will fail.  That’s because the debug version of some project doesn’t exist on disk.  One very bad solution for this is to perform a Debug build before a Release build, but that will still add a debug version of a project DLL to your release build.  How slow do you want your app to run in production with debug code?  And do you really want to suggest performing a Debug build before a Release build to the folks maintaining your build server?  They should laugh at you.  If they don’t then your company has at least 2 problems – you and the build server person to whom you’re talking.

Understand the difference between a project reference and a file reference and you won’t end up with broken builds or the wrong build version of DLLs in your bin directories.

Sunday, February 13, 2011

Biggest Regret

I recently read an article about Donald Rumsfeld’s biggest regret (not pushing Jr. hard enough to accept his resignation after the Abu Ghraib abuses came to light), and it got me thinking about my biggest regret.

For many years my biggest and only regret was getting the arms on a leather jacket trimmed too short.  I liked to think that this was a nice only regret because it meant I didn’t regret any of my other life decisions, like the woman I married, the house and car we bought, having kids etc.

But I recently had to move a bunch of dishes and glasses given to us as  wedding presents.  It made me realize that my biggest regret was registering for wedding gifts. 

I appreciate the folks who came to the wedding and spent their money on us, but I regret not talking to more people about the whole idea of registering.  I’m sure I would have found out before it was too late that if you don’t register for gifts people will just give you money.  Register for a few gifts and they’ll give you a few gifts and a bunch of money.  Register for a lot of gifts and you’ll get a lot of gifts and a bit of money.   Get a lot of gifts and you’ll need to store a lot of gifts.  As a consequence I now just give money for weddings whether people have registered or not.

How this happened is, we went to the Bay and they handed us three things:

  1. A cardboard wheel on which you rotate a circle to the number of guests you plan to have and it tells you the number of table place settings and total dollar amount for which to register.  I seem to remember it suggesting 16 place settings.  I don’t remember the total dollar amount.
  2. A list of things that constitute a place setting.  From the gifts we received the list must have been:
    1. A soup bowl
    2. A salad plate
    3. A dinner plate
    4. A dessert plate
    5. A white wine glass
    6. A red wine glass (still can’t tell the difference)
    7. A martini glass
    8. A water tumbler
    9. A champagne flute
    10. A salad fork
    11. A dinner fork
    12. A knife
    13. A dinner spoon
    14. A tea spoon
  3. A bar code reader with which you run around the store scanning the things you want to add to your registry.  If you want 16 of something you don’t even need to scan it 16 times, you just enter ‘16’ on the scanner and scan once.

These are your “good” dishes, not your everyday ones.  This means you have to store it all somewhere separate from your everyday dishes.  Which is the situation we’ve found ourselves in.  What do we do with a dozen wine glasses, a dozen martini glasses and a dozen champagne flutes?  Store them.  Move them around the house, carefully.  Use them once every 6 months.  In short, manage them in a high cost, low benefit manner.

So, for Jebus sake, don’t register for much, or anything, for your wedding.

I’m only in my 30’s so maybe I haven’t lived long enough, or had a high powered enough career to have a significant biggest regret.   I certainly  haven’t been the CEO of a multiple companies, or defense secretary of the U.S., so I probably won’t have regrets on the level of Donald Rumsfeld.  (Seriously, how does he sleep?  On a pile of money surrounded by many beautiful ladies.)  But I hope to hold on to this current regret as long as possible.

Sunday, February 6, 2011

Better Bass On Your iPod

The iPod has an equalizer setting called Bass Boost.  However, for most modern songs this setting will cause a buzzy sound during bass-heavy sections.  As I understand it this is because most modern music is recorded very loud and the iPod doesn’t have the power to add the needed decibels.  One suggestion I read was to use iTunes to reduce the volume of all your modern music.  Rather time consuming.

The solution I’ve found is to go the other way – enable the Treble Reducer EQ setting and turn your music up.  This works best if you use headphones that produce really good bass.  I use and highly recommend the Klipsch Image S4 headphones.  With these headphones I’ve found the default sound setting has great bass but too much treble at higher volumes.  Reduce the treble and you’re golden.  The iPod doesn’t struggle to remove decibels.

(English is such a screwy language.  Every time I wrote the word bass I thought it was a type-o and that it looked like I was talking about fish.  We should standardize on “base” to mean low frequency sounds and the thing I’m in killin ur d00dz.  Leave the word that doesn’t end in e and has repeated consonants to be pronounced with a short and to refer to fish.)

Sunday, January 30, 2011

What Would You Do if You Knew You Couldn’t Fail?

I recently watched a talk of Naomi Klein’s on ted.com, where she mentions that Tony Hayward, the CEO of BP at the time of the spill in the Gulf of Mexico, had a plaque on his wall with this phrase:

What would you do if you knew you couldn’t fail?

Klein’s implication is that when Hayward and other people ask themselves this question they get a deluded sense of the possible.  Unless a person is bipolar and has a psychotic view of his or her own abilities, I disagree.

The first thing that springs to most people’s mind is to do something illegal, like rob a bank, or kill someone.  In this case failure is interpreted as getting caught.  Ok, let’s say you actually did that illegal thing – could you live with yourself for the rest of your life?  If you robbed a bank while it was open, scaring tellers, customers and their kids could you live guilt free?  If you killed a person you definitely wouldn’t, unless you were a conscienceless sociopath.

Another thing that tends to come to mind is to do something that isn’t illegal, but is unethical, like cheat on your spouse.  Again, this is interpreting failure to mean getting caught.  And again, could you live with yourself?  I hope not.

So how should you interpret this question?  By thinking about the definition of failure in your imagined scenario.

As I stated above, failure doesn’t equal not getting caught, so this question isn’t about getting away with something.  Failure also doesn’t mean that succeeding would be a walk in the park.  “Having a 3rd/4th/nth kid” could be considered a good answer because even though you might have hard times, you can sort of define success (e.g. kid graduates high school/college/university without a criminal record and moves out).  Failure means not achieving a goal, and having not succeeded you don’t have any more chances.  If you have unlimited tries at a goal then you can’t really fail, you can only give up.  The goal also has to be in the realm of the possible.  Bringing someone back to life is not an acceptable answer.

So the question is about doing something where you only have one chance, or a very limited number of real chances.  By real chances I mean that even if you can theoretically try lots of times, people will remember you failing and not even consider you, like people who try out for American Idol again and again, or losing presidential candidates.

In Tony Hayward’s defense, I’m sure he didn’t think to himself, “I’d drill a hole deep into the ground that’s deep underwater with no testing and no safety measures in order to produce cheap oil.”  Like any sane person I’m sure he realized there is a follow up question:

Ok, cool.  Now, realizing that you could fail, how will you make sure that you don’t?

Oil companies have been drilling successfully in the Gulf of Mexico for a long time, and know the answer to this question.  Safety measures, testing, redundant systems, following documented and tested procedures.  Not doing these things led to the BP failure.  But I don’t think someone looked at his plaque and thought, “I’d bypass all known ways to succeed to save some money.”  If someone did think this, then he’s out of touch with reality i.e. a psychopath.  The mistake wasn’t in drilling for oil so far down, it was doing it in a really unsafe way.

The question is meant to inspire personal audacity, but with risk mitigation.  Was it a mistake to try to reach oil beneath 1.5Km of water and even more rock?  No, no more than it was a mistake to try sending men to the moon, or to leave Africa 70,000 years ago.  As Jim Kirk said, “Risk is our business.”  The Enterprise’s mission was to explore.  It didn’t go into space without defenses, weapons and the prime directive, though.  (Ok, Kirk was a little TS;DR with the prime directive, but I’m sure there were other captains at the time who followed it.)

By audacity, I mean reaching for a result for which the path is not clear.  Perhaps you think “remodel the kitchen” is an answer.  If you intend to hire a contractor, no, not a good answer.  You can throw money at this until it succeeds.  It has to be a personal challenge, too.  If your answer is “remodel the kitchen myself, even tough I don’t know what lefty loosey, righty tighty means”, then good answer.  This would prompt you to learn the needed skills to mitigate the risk.

Now for my own answers.  Audacious personal actions I would take if I knew I couldn’t fail:

  • Get some of Milton Friedman’s ideas implemented in Canada, namely a flat tax, free immigration, negative income tax, voucher school system.
  • Dismantle the CRTC
  • Change the US Constitution to allow foreign-born citizens to become president
  • Get Arnold Schwarzenegger on the presidential ballot (I think the rest would take care of itself)
  • Strike out on my own as a free lance .NET C# developer
  • Reunite Guns N Roses members at the time of Use Your Illusions and patch things up to the point that they could produce another album
  • Convince MC Plus+ to create another album
  • Prevent Jack Black from making any more movies
  • Ensure Robert Rodriguez, the Cohen Brothers and Ridley Scott keep making movies until they fall over