Upgrades and Downgrades

by George 14. December 2011 06:15

I recently 'upgraded' my BlogEngine.NET installation from 1.6 to 2.5.  

That turned out to be a mistake.  You see, there was this annoying bug that plagued 2.5 (when upgrading from 1.6), and it made my blog unclickable from any RSS reader.

Instead of waiting for a bug fix, I had two choices, Reproduce it, fix it myself, and create a patch, or... wipe the slate clean and start over.

I chose the latter, which was not without peril.  After exporting my blog posts to OPML, installing the new version, and re-importing them, I found a nasty 'bug'.  All of my drafts were imported as actual blog posts. Published blog posts.

Oh crap.

I have about twenty-some odd blog posts lying around in a half-finished state, from fiction, to politics, to posts about The Motley Fool that never saw the light of day. They're not meant for human consumption just yet.

So with that in mind:

see something, say something.

Tags:

Legal monopolies

by George 2. September 2011 23:19

The @mises twitter account recently posted a link to an article from the Los Vegas Review Journal titled Backlog for driver's licenses irks many.  Nevada has a problem: many more people need driver's licenses than there are examiners to give them the necessary driver's tests.  There are waits of up to four months for driver's licenses. There is one story of a person waiting and sleeping in the DMV line four times in the span of a month. 

It's easy for us to be shocked, right? When was the last time you had to wait four months to get groceries? Or four months for a TV? Now, how long did you have to wait for your dentist's appointment? Or doctor's appointment? If your experience has been anything like mine, the first two were much easier to do than the last two. But we'll get back to this in a moment. First, let's go back to the DMV's problem.

The DMV clearly has a supply and demand problem. too Many people wanting licenses (demand) and very few people authorized by the state to test them (supply).  So, in the confines of the present system, what can the DMV do? They can:

  1. Hire more examiners
  2. Contract with private firms for testing
  3. Relax the requirements for licensed people that move in state

#1 is out, since the article states that there is a budget shortfall in the state of Nevada.  With the ongoing unemployment/housing crises in Nevada, it's unlikely the state could tax anyone at any rate higher than what they do now; it would be akin go getting blood from a stone. If you listen to the union in Nevada, #2 is out because it would, "not save money, based on the state's experience with a private women's prison. [...] Private employees could gain access to personal information of drivers and would not be accountable to the state." #3 is out because it would be up to the state to determine if the requirements should be relaxed. Currently, out of state drivers have to take a test if they:

  • have more than four moving violations in four years
  • a drunken driving conviction within seven years

Reading this article, I get the impression that according to the sources in it, there is no way to solve this problem. We are simply stuck with individuals camping out night after night at the DMV, hoping to get a spot to take their driver's test.

I don't agree.  The current approach is not good for anyone. Citizens feel like cattle (instead of customers), the state has a black mark on its record for its inability to handle a common market problem, and everyone else in the state would have to pay more to make the problem go away (when it's not even their problem!).

The budget shortfall should have no bearing on the DMV: The price of the driver's test should cover the cost of that driver's test. I understand why it doesn't. By socializing the cost (through taxing everyone), the state can hide the true cost of a license, and not expose the fact that (because of the labor situation) it costs a lot to get.  If they exposed that, there would likely be riots in the streets. So instead, they make everyone pay for it.  Something your local grocery store cannot do.

The union doesn't care about the people waiting in line, as is evidenced by the article. They erronously state it would not save money (more on this later), and they're worried that private employees would not be accountable for seeing private information.  A lawsuit if information leaks out would generally spell doom for a business, so I disagree with them there.  As far as #3: What does a drunk driving conviction have to do with someone being able to physically drive? It doesn't. (It's used as a tactic to keep people from driving drunk. Commendable, but misguided). If someone comes drunk to a driving test, it would be easy to spot and stop. But the misguided statutes aren't the focus of this article, rather, let's focus on something that is actionable: The really long wait for a license.

Why does this happen? How do these shortages in supply come about? Why isn't the market correcting for this (as we were taught in school)?  The shortage happens because the Nevada DMV holds a monopoly on who can get a license, and they don't have the capital to expand their employee base.  The market can't correct for it because by law, only state approved examiners can give a driving test, and the state hasn't changed its law or contracted with private firms to provide driving tests.

How can we fix this?

Send a message throughout the state: Any driving company that has private instructors can give driving tests. Don't limit it to one or two firms, because then there's no competition among the firms.  Allow these firms to set prices.  Allow them to keep the profits from this venture. There is no cost to the DMV's driving instructor department if a private instrutor gives the test. There is a raised cost for getting a license (as the lines are longer to get the physical license) but there are ways to fix that as well.  I would even say that the DMV could impose a surcharge of x amount of money, where x is the cost needed to sustain DMV operations for taking pictures and issuing licenses. If the DMV is like any private company, they know exactly how much it costs to issue a license (not just the license itself, but the staff, the power, etc).

What would happen if we took these suggestions? Well, overnight the lines at the DMV would go away, as companies sprang up to fill the supply gap.  The prices for these firms would probably be substantially higher than the DMV's price (but only as long as there were a shortage of examiners -- once enough companies came into the mix, or the demand fell, the prices would drop precipitously).  The firms would find methods to make the process more effecient so as to improve their profit margin; and the state wouldn't have to tax everyone in the state to fix a problem that isn't everyone's problem.  The unions would be unhappy because they currently hold a monopoly on that labor market; but knowing their tenacity, they would likely require the private companies to be unionized as well, which would keep the price considerably higher than the market clearing rate. Finally, the citizens of Nevada would finally know what it actually costs to get a license, as opposed to the 'We think it should cost $45 to get a license" that currently happens, with no feedback from customers as to whether the price is too high or too low'.

Problem solved, we can all go home happy.  But we still haven't answered why this happens in the DMV, or the post office, but it doesn't happen for groceries, or furniture, or anything else that is non-government.

This happens in government, but not in private industry. This is a problem that can never happen in a free market. Why? Because there is never a legal constraint on the number of entites that can provide groceries, or provide furniture, or in any other service or good we use or buy day-to-day.  If there were, shortages would inevitably follow when the number needed to sustain the populace fell below the demand.

The Nevada DMV is a nice example of this in action. Not only is there a monopoly, but there's also only one entity that can legally provide that good or service: the government. So too with the Post office. By law, no one else is allowed to accept or deliver first class mail (letters, and the like). The post office is a legal monopoly.

Starting to recognize these monopolies is the first step to being able to fix the problem, and it's a problem that doesn't have to exist.

 

Tags:

URL writing tips for ASP.NET MVC

by George 8. August 2011 00:01

I happened upon the following code in a recent project for one of our ASP.NET MVC web applications today:

<a href="/widget/show/<%=Model.ProductId%>/<%= Model.ProductName.ToUrlSlug() %>"><%=Model.ProductName></a>

This line of code works, in that it does what it's supposed to; but it's brittle. Like Ginger snaps brittle.

Let's imagine we have a route for this action already set up:

routes.MapRoute(
    "showWidget",
    "/widget/show/{productId}/{*productName}",
    new { controller = widget, action = show },
    new { productId = @"\d+" }
);

Now, what happens to that previous URL if we change the route?

routes.MapRoute(
    "showWidget",
    "/widget/show/{productName}/{productId}",
    new { controller = widget, action = show },
    new { productId = @"\d+" }
);

 

At best, our routes will return:

/widget/show?productName=hi-there-bad-url&productId=5

and at worst they'll die a horrible death when your user tries to click on one. The unfortunate thing about this is that there's no easy way to check whether or not your links 404 without the help of a third party library, not to mention checking whether they're pretty or not without a third-party library*.

There are also other side effects, like having to change every link on your site whenever you change your routes, and dealing with the hideously bad angle bracket code mixed in with HTML code (uggh).

Here are some other ways of writing URLs in ASP.NET MVC, each cleaner than the above.

Good Ol' Actionlink:

<% Html.ActionLink(Model.ProductName, "Show", "Widget", new {productID = Model.ProductId, productName = Model.ProductName.ToUrlSlug() }, null);

This particular approach creates the entire link for you; great if you're a developer, but it sucks if you spend your time styling with CSS. To style the above link with CSS, you have to do the following:

<% Html.ActionLink(Model.ProductName, "Show", "Widget", new {productID = Model.ProductId, productName = Model.ProductName.ToUrlSlug() }, new { @class = "widgetlink" }); >%

There's also the RouteLink method that looks pretty similar to the above, except that it takes a route name:

<% Html.RouteLink(Model.ProductName, "showWidget"new {productId = Model.ProductId, productName = Model.ProductName.ToUrlSlug() }); %>

There are also other solutions that don't require so much interposition of C# code in a view.

Luckily, for our CSS friends (who may or may not be familiar with MVC), we have a few other solutions, and they each center around a different way of doing things in MVC. There are two major ways of getting a URL in MVC, by the route name that you're looking to hit, or by the Action you want to invoke.

For the action:

<a href="<%= Url.Action("Show", "Widget", new {productID = Model.ProductId, productName = Model.ProductName.ToUrlSlug() };" class="widgetlink"><%=Model.ProductName %></a>

For the Route, there are many overloads on RouteUrl that give you many overloads that aren't intuitive at first.

First, if you just want to match a route by route values:

<a href="<%= Url.RouteUrl(new { productID = Model.ProductId, productName = Model.ProductName.ToUrlSlug() })%>" class="widgetlink"><%=Model.ProductName %></a>

all the way to even specifiying the protocol and host (!). The latter is important because it helps when you need an absolute URL from a non-SSL site to an SSL site (or vice versa).

The one I use (when I need a URL) looks almost exactly like its URL.Action() counterpart, except that it takes a route name instead: 

<a href="<%= Url.RouteUrl("widgetlink", new { productID = Model.ProductId, productName = Model.ProductName.ToUrlSlug() })%>" class="widgetlink"><%=Model.ProductName %></a>

But maintaining these Urls or ActionLinks is still a pain in the ass (if you don't have ReSharper). Everywhere you want to change the route name, or the Action name (say we wanted to change "Show" to "ShowWidget"), you have to conduct a Find and Replace on potentially dozens of method calls. Luckily, there's an easier way. Url.Action and Url.RouteUrl belong to the 'UrlHelper' class; which holds extension methods for Urls.  Likewise, the Html.Action() and all its brethren belong to the HtmlHelper class.  These allow us to create extension methods to the extension methods:

public static MvcHtmlString GenerateProductLink(this Htmlhelper helper, Product product)
{
    return MvcHtmlString.Create(
        helper.ActionLink(
            Model.ProductName, 
            "Show"
            "Widget"
            new {
                    productID = product.ProductId, 
                    productName = product.ProductName.ToUrlSlug() 
                }, 
            null
        )
    );
}

and similarly for the UrlHelper:

public static MvcHtmlString GenerateProductUrl(this Urlhelper helper, Product product)
{
    return MvcHtmlString.Create(
        helper.RouteUrl(
            "widgetlink"
            new {
                    productID = product.ProductId, 
                    productName = product.ProductName.ToUrlSlug() 
                }
        )
    );
}

Then both of those become:

 

<%= Html.GenerateProductLink(Model.Product); %>

and:

<a href="<%= Url.GenerateProductUrl(Model.Product)%>"><%= Model.ProductName %></a>

But that still doesn't fix our issue of icky views. Do we really want our views to look like this?

<%  foreach (var product in Model.Products) { %>
<ul>
  <li><a href="<%= Url.Action("Show", "Widget", new { productID = Model.ProductId, productName = Model.ProductName.ToUrlSlug() }) %>"><h2><%= product.ProductName %></h2></a>
    <% if (product.Id.HasManySellers()) { %>
      <ul>
      <% foreach (var seller in product.Sellers) { %>
        <% if (seller.BuyerId == product.MainSupplier) { %>
            <li><%= Html.ActionLink(seller.Name, "Details""Seller"new { id = buyer.Id, sellerName = seller.Name.ToUrlSlug() }, null)%></li>
              <% } %>
            <% } %> 
      </ul>
  </li>  
  <% } %>
<% else { %> </li> <% } %>

Gross, right? Now imagine maintaining that?

Luckily MVC gives us an easy way to simply that logic, or at least hide it away from unsuspecting front-end developers, and it is all because of the Extension methods we used before. 

Since they're extension methods, it's really easy to move all the logic from the above into an HtmlHelper method:

public static MvcHtmlString GenerateProductsAndSellers(this HtmlHelper helper, ProductViewModel model)

    StringBuilder html = new StringBuilder();
 
    foreach (var product in Model.Products) 
    { 
        html.Append("<ul>");
        html.Append("<li>");
        html.Append(helper.ActionLink(product.Name, "Show""Widget"new { productId = Model.ProductId, productName = Model.ProductName.ToUrlSlug() });

        if (product.Id.HasManySellers()) 
        { 
            html.Append("<ul>");

            foreach (var seller in product.Sellers)
            {
                if (seller.BuyerId == product.MainSupplier)
                {
                    html.Append(String.Format("<li> {0} </li>", helper.ActionLink(seller.Name, "Details""Seller"new { id = buyer.Id, sellerName = seller.Name.ToUrlSlug() }, null));
                }
            }
            html.Append("</ul></li>");
        }
        else
        {
            html.Append("</li>");
        }
    }
}

return MvcHtmlString.Create(html.ToString());

}

It's messy, but far less messy than having that in the HTML markup, and now the resulting View becomes simply:

<%= Html.GenerateProductsAndSellers(Model) %>

which is exactly what we wanted to express, not to mention it vastly improves our relations with the maintenance programmer (or ourselves in six months).

 

Important things to remember:

  • Use RouteLink and ActionLink when a virtual path URL will do.
  • RouteLink and RouteUrl  perform faster (although we're really talking about a micro-optimization) because there's no need to iterate through every item in the RouteValueDictionary to find what we're looking for.
  • The HtmlHelper is preferable to another RenderPartial in cases where you have display logic that would otherwise be in the view (easier to debug also, since we currently can't set breakpoints in Views).
  • Using an HtmlHelper to generate links also allows you to keep your link generation in one place, giving you only one place to change it when someone wants something else.
  • *todo, find a .NET tool that does this at compile time.

    Tags:

    Comcast: A New Beginning?

    by George 7. August 2011 01:29

    I don't trust Comcast.  Since moving up to the DC area 2 years ago, I've dealt with Comcast half a dozen times, and ultimately they caused me to go unplugged.  Installs that never happen, sneaking in bill charges, and shoddy tech support helped to ruin that trust.

    So why the hell am I going back to them?  Because they're the only game in town. In fact, they're called a natural monopoly, only that's a myth. So that and that they seduced me with their pricing.

    Right now I'm paying 67.95 a month for Internet. Just internet. Plain ol' 6Mb/sec internet (notice the little 'b', that's for 'bit'). I called up their customer support line (at 10:13am) and spoke with Harriett.  Here's what she told me:

    If I upgrade to their "Digital Preferred Double Play", I get HD Digital Cable for $49.99 a month, and my internet goes down to $19.99 per month (leading to the inevitable conclusion that the original 'cost' of internet is bumpkus) for 12 months.  After that, the price rises to $69.99 for the "Digital Preferred Cable" and the internet cost rises to $34.95.  This does not require a two-year agreement.  There is a one time installation fee of $29.95, and a $7.00 per month for renting the cable modem (which is already included in the cost of what I pay for my internet now).

    So now: $67.95 - Internet.

    By Tuesday: $49.99 for cable & $19.99 for internet.

    I'm recording this here so that in a year, when the price inevitably goes higher than Harriett told me today that I have some sort of record of what Comcast said.  I don't trust Comcast, but maybe this time it'll be different?

    Edit:

    I tried really hard to find the deal I was quoted on Comcast's website. The closest I could come to is the Digital Starter + Internet double play package for $69.99 a month (screenshot below):

    Notice the differences: The package I was quoted was a Digital Premiere package, with no 2-year agreement required. This package is the Digital Starter package that requires a 2 year agreement.

    I'm going to contact Comcast again and get verification on the deal.

    Tags:

    Hulu Plus: A Tale of Two UIs

    by George 10. July 2011 02:25

    Earlier today I tweeted about Hulu's abysmal UI for Xbox 360:

    Right after that, they responded to my tweet (great Customer service, by the way),

    and that prompted this blog post.

    I love Hulu+, so much so that it was a major factor in me 'unplugging'.  My wife and I have two TVs, and two distinct personalities when it comes to watching shows (although, admittedly I love Grey's Anatomy). That means that most of the time I want to watch something different than she does.  She gets the PS3 for the living room, and I get the man cave and my Xbox360.  Hulu+ is on both, though the experience is radically different on each.

    The PS3 version of Hulu+ is great, and there are very few changes I'd suggest for them. However the Hulu experience on Xbox 360 makes me want to throw things.  Maybe it's a story best told with pictures.

    First, the main screen:

    The Hulu+ main screen (Xbox360)

    The menu options are not helpful at all.  When I load Hulu+, I'm loading it to view shows that I've already Queued on the website. It would be extra helpful if my Queue were the first thing I'd see (since that's what I'm most likely going for):

    Hulu+ Queue (Xbox360)

    The problem with the Queue screen on the Xbox 360 version is that it doesn't have any coherence.  Random Glee episodes that I haven't watched are next to random House Episodes, which are next to random Modern Family Episodes.

    Randomness abounds. Hulu+ Queue(Xbox360)

    Admittedly, all of these are in my queue, but does anyone really want to scroll through 188 items just to find what they're looking for? (And keep in mind I have about 8 series in my queue, 3 of which are web-only so they shouldn't even be available on the Xbox).

    To put it simply, the queue doesn't group the episodes by Show, as it does on the PS3 version:

    Hulu+ Queue (PS3)

    If I want to watch the next episode of Quantum Leap on Xbox 360 (many kudos to Hulu for picking that up), then I have to do the following (from the home screen): Find my history (PS, it's below Featured so it's not visible, instead of being near Queue.

    Where's my history? (Hulu+, Xbox360)
    Ah, found it!

    hA

     

    If I forget where it is, I have to cycle through the whole menu to find it), click on history, potentially search through 96 (!) items to find which show it belongs to, click on an episode from that show, and hope what I wanted to watch is in the same season, and click on it.

    That took some doing.

    Contrast that to the exceptionally easy to use PS3 version:

    It doesn't sort my queue by episode, but by show.

    Click on queue. Everything is sorted by show, so I dont' have 188 items (!). Click on the Show, and find the season, and click on the episode.  I've never needed to use the history tab on PS3, because the Queue is so well put together. On the Xbox 360, the Queue is virtually useless.  

    You may object and say, "Well, if you click on an episode in your queue, it takes you to the same place that your history does", and you'd be correct. But the behavior isn't apparent. Look at the image: Does it give you a hint that it'd take you to the whole show, rather than just open the episode?:

    Glee Episode

    No, it doesn't. Clicking on that makes me think I'm going to start that episode, which is what I don't want.  

    Hulu+ could improve their Xbox360 design by categorizing things like they do for their PS3 team. A Queue should show the 'shows' I have queued, not the individual episodes randomly mashed together.

     

    Tags:

    Food Week at the Fool: Pizza Day!

    by George 24. June 2011 00:42

    One of the perks of working at The Motley Fool is how awesome of an environment it is to work in. Before the Fool, I never really cared about sharing the details of my job with anyone, because really, they're all the same.  There are varying levels of purgatory, but most jobs are still squarely in purgatory.  I can only imagine Dante rolling around in his grave at such thoughts.  

    I hesitate to say thiss, for fear of being struck down from the heavens, but the Fool is stationed in paradise.  And not just because of the pizza, though that's what I'm covering today.

    Pizza day is a tradition at the Fool, insofar as it has its own 'time of the month' and that stays constant.  The last Friday of the month is the customary time for Pizza, as it should be.  When you need to feed hundreds of people, you can't just call up your local Papa Johns and tell them you need 100 Pizzas.  It doesn't work like that.  So we have pizzas from just about every local Pizzaria in town, as well as the standard 'chain' pizza stores:

    In Google ranked order for "Pizza, Alexandria VA":

     

    • Valentinos
    • Monterey's Pizza
    • Bugsy's Pizza
    • Faccia Luna
    • Delia's Brick Oven Pizza
    • Bertucci's
    • Pizzeria Venti
    • Pizza Pan
    • Red Rock's Pizza
    • Generous George's Positive Pizza and Pasta
    • Ledo Pizza
    • Vocelli's Pizza
    • Primo Pizza
    • Domino's Pizza
    • Papa John's Pizza
    • and others I may have missed.
    The Pizza is 'old hat', something we do every month.  What makes this particular Pizza day special (or more special than having work sponsered Pizza every motn) is that today's Pizza is accompanied by Wine tasting from Le Tastevin Fine Wines.

    But wait, there's more!

    Not only do we get to sample wine, but also making an appearance are the craftsmen of Alexandria's newest (and only) brewery, Port City Brewery! If you're interested in a history of Port City, there's a great write-up here.

    I'm on vacation, so I won't be able to live-tweet images from today's events. Mea culpa and all that.


     

    Tags:

    Food Week At The Fool: A boatload of Cereal

    by George 22. June 2011 12:10

    Just after I put in my vacation notice last week, I received the following email from our amazing Office Ops team:

    Wednesday, June 22: Cereal Extravaganza!

    Enjoy this morning of childhood. Head to the cafeteria to enjoy all your favorite cereals. We'll have Lucky Charms, Fruit Loops, Honey Bunches of Oats, Cherrios, Smacks, Special K, Reeses Puffs and more to satisfy your inner child. Enjoy them topped with Skim, 1%, 2%, Whole Milk, Soy Milk, Lactaid Milk, Chocolate Milk, or mix in some Nesquik! We will also serve fresh fruit (to be eaten on the side or on top or your cereal!), danishes, croissants, and the like.

    All I can say is, it's a bad week for me to take vacation.

    Tags:

    Going Ape at the Fool

    by George 22. June 2011 01:24

    Last Friday, the Office Ops at The Motley Fool sponsored a trip to Go Ape! in sunny Rockville, MD.  

    If you haven't heard about Go Ape!, allow me to educate you, better yet, let me show you.

    Note: I would have embedded the video, but apparently BlogEngine.NET doesn't like that idea. Many apologies.

    Tags:

    To Tag or Categorize?

    by George 22. June 2011 00:01

    I have a hate-hate relationship with BlogEngine.NET.  As I mentioned so long ago, I want to replace it as the blog that runs this site; and as a programmer I'm reasonably qualified1 to do that. Part of replacing it is dealing with the categorizations that Blog Engine.NET does.  There are 'tags', and then there are 'categories'. I'm not at all sure the reason to have two things that categorize content.  Why can't it just infer what I write about by using a word cloud or something?  

    So I've done what any cantankerous human would do when presented with two near identical choices: I chose neither of them.  The end result is that I have a few years worth of blog data that isn't categorized at all.  Since this is a low-traffic blog, I don't have that much of a problem with it right now; but I would like to have a way to categorize content.

    Update: It appears that BlogEngine.NET has upgraded to 2.0. I'm going to download it and see how it goes. I'm still building my own lightsaber though.

    1It's really bad when I sic the snark on my own writings. By reasonably qualified, I mean that I'll probably screw it up big time and hate myself when it's done.

    Tags:

    Food Week at The Motley Fool: Rocklands BBQ

    by George 21. June 2011 00:01

    If you live in NoVA (Northern Virginia), you're on the fringe of birth of Barbeque.  It isn't as if this is Lexington, NC or anything. That doesn't stop the word barbeque from taking on a whole 'nother meaning when discussed in polite company, generally with lots of napkins.  Words like, "whole hog", "vinegar based" and "dry-rub" permeate the smoke filled atmosphere.  I have it on good authority that if you were to pit the barbeque peoples of Kansas City and North Carolina against each other, a new reality series would be born of their blood, sweat, and barbeque sauce.  This shit is that good.

    BBQ sandwhich.

    Rocklands is a BBQ venue that is renowned in these parts (to use the vernacular of our time).  Our awesome Office Ops team arranged for Rocklands to cater lunch for all of FoolHQ

    On the menu:

    Pulled Pork, pulled chicken, beef brisket. For our vegetarian friends, portebello mushroom sandwiches on a potato split roll.

    Can you say, delicious? 

    The sides are your traditional southern fare: Mac and Cheese, BBQ baked beans, coleslaw, traditional potato salad (we have traditions, duh), and if you're low-carbin' it, grilled seasoned vegatables.

    Sadly, all that's lacking is cavity-inducing Sweet tea.

    Tags:

    Me!

    This space intentionally left blank.

    Month List

    Page List