Format bytes as KB, MB, GB, etc.

Here's a useful little chunk of code to put in your toolbox.  I need to display file sizes to users, and I want to format the displayed file size as you'd see it in Explorer -- 10.1 KB, 23.31 MB, and so on (not 112230103 bytes, for example).  After a quick google search, I turned up a post on forums.asp.net that got me really close.  I cleaned up a couple of issues and built a unit test to make sure things were working correctly, and it's ready to go.  Read on to see the working code.

///
/// Format bytes suitably for display to user (ex: 12.3 KB, 34.41 MB).
/// If you need to handle sizes > Exabyte size, you'll have to modify the
/// class to accept ULong bytes and format accordingly.
/// Based on code as published here: http://forums.asp.net/t/304193.aspx
/// By Bart De Smet -- http://bartdesmet.net/members/bart.aspx
/// Algorithm fixed to handle KB correctly and modified to use Long
/// instead of int to handle larger file sizes.
///

public struct FormattedBytes
{
#region ctor
public FormattedBytes(long size)
{
_bytes = size;
}
#endregion
#region Bytes property
private long _bytes;
///
/// Get or set bytes.
///

public long Bytes
{
get { return _bytes; }
set { _bytes = value; }
}
#endregion

public override string ToString()
{
double s = _bytes;
string[] format = new string[] {"{0} bytes", "{0} KB",
"{0} MB", "{0} GB", "{0} TB", "{0} PB", "{0} EB"};
int i = 0;
while (i < format.Length @@ s >= 1024) {   //replace @@ w/ ampersands
s = (long) (100 * s / 1024) / 100.0;
i++;
}

return string.Format(format[i],s);
}
}

And here's the unit test I'm using to test the routine:

///
/// A test for FormattedBytes ()
///

[TestMethod()]
public void FormattedBytesTest()
{
FormattedBytes bs = new FormattedBytes();
Assert.AreEqual("0 bytes", bs.ToString(), "FormattedBytesTest - incorrect value (1).");
bs.Bytes = 10000L;
Assert.AreEqual("9.76 KB", bs.ToString(), "FormattedBytesTest - incorrect value (2).");
Assert.AreEqual("1.17 MB", new FormattedBytes(1230000L).ToString(), "FormattedBytesTest - incorrect value (3).");
Assert.AreEqual("434.87 MB", new FormattedBytes(456000000L).ToString(), "FormattedBytesTest - incorrect value (3).");
Assert.AreEqual("73.48 GB", new FormattedBytes(78900000000L).ToString(), "FormattedBytesTest - incorrect value (4).");
Assert.AreEqual("1.11 TB", new FormattedBytes(1230000000000L).ToString(), "FormattedBytesTest - incorrect value (5).");
Assert.AreEqual("1.09 PB", new FormattedBytes(1230000000000000L).ToString(), "FormattedBytesTest - incorrect value (6).");
Assert.AreEqual("1.06 EB", new FormattedBytes(1230000000000000000L).ToString(), "FormattedBytesTest - incorrect value (7).");
}

Here’s some more of the value Microsoft sees in Yahoo!

Image via CrunchBase, source unknown

Last time, I hinted that there was more than Google-phobia driving this attempted purchase, and there is.  In addition to vaulting overnight to a relevant search power, there are a few other areas where a combined company would become a real market force.

Start with email.  Even though GMail is growing quickly, Yahoo! still has a ton of email customers.  Add those to Microsoft's Live email, and the combined market share of these two email platforms is on the order of 80%.  That's a lot of captive desktop time where ads could be shown - if Microhoo can maintain that market share.

Then there's portal traffic. Yahoo's home page is a landing spot for a lot of users, and I have a hunch that these are users in the most stable demographics on the web.  All of those eyes are a valuable asset, not just for selling ads, but to serve as a launching pad for new initiatives.  Check out this article on readwriteweb where they talk about the impact of a recently-launched feature called "Buzzing Now".  According to the article,
  • Yahoo.com has sent approximately 16 million total referrals to just a subset of the publishers in the beta during the first two weeks via “Buzzing Now” links in the Featured section of the homepage.
  • Salon.com reached over 1 million uniques in one day for the first time in the company's 12-year history, after Yahoo.com linked to one of their highly "buzzed" stories.
  • US Magazine: Referral visits from the Yahoo! homepage accounted for 32% of total visits that day.
Image representing Yahoo! as depicted in Crunc...Go read the article - there are more traffic numbers there.  My point is that when Yahoo! still has the eyeballs and the clout to swing traffic like this, they're a jewel worth getting excited about.
Image representing Microsoft as depicted in Cr...Of course, Microsoft would have their work cut out for them.  The mere fact that despite all this traffic, Yahoo's financials have lagged expectations begs the question of how Microsoft could improve on that performance.  There's also the issue of culture.
Detractors of the Microhoo deal believe that Yahoo's open culture is going to clash mightily with Microsoft's, but I think they're wrong.  I've seen a big change in Microsoft over the last few months.  There's a greater embrace of openness than they've ever shown, and it's taking root and flourishing.  Microsoft is ready for Yahoo's sort of culture, and I really think there are parts of Yahoo! that could stand a little infusion of Ballmer's enthusiasm - maybe even a swift kick.  This could be a pretty cool partnership.
Reblog this post [with Zemanta]

Why you should care if Microsoft buys Yahoo?

Anyone not living under a rock knows that Microsoft is trying to buy Yahoo!, but so what?  What difference could it possibly make to an end-user or a software developer whether Yahoo! remains independent or not?

Clearly, this is a buyout of historic proportions.  The size alone is impressive: at $45B, this is a serious chunk of change and a sizable improvement over the market valuation of Yahoo! prior to Microsoft's offer.  But this buyout isn't notable just for size.  This is a pivotal moment in the growth and maturation of the net: a marquis player is quite possibly going to cease to exist independently, and another is at a "make or break" moment.  As far as brands go, this is an impact on the order of seeing Netscape fade away or AOL get gobbled up by Time Warner. Like AOL, it's quite conceivable that the brand will live on for a long time, but it's clear that it'll never again live with the vigor that it's had in the past.

So just like that, Microsoft is set to gobble up Yahoo!, and the giant from Redmond marches inexorably onward, right?  Not so fast.  Remember how that AOL / Time-Warner deal worked out?  Other industries have shown us the dangers of mega-mergers, as well - Sprint / Nextel has been in the news a lot lately as Sprint slowly continues its death spiral.  Most analyses of Sprint's current woes begin with theNextel takeover and end with gigantic accounting charges to reflect this failure and a mass exodus of (mainly ex-Nextel ) subscribers.  These failures can't be overlooked; Microsoft could catch a world-class case of indigestion if they're not careful.

So why is Microsoft doing this?  Nobody's holding a gun to Ballmer's head, right?  Or are they?  Conventional wisdom holds that Microsoft is making this move strictly out of fear of Google.  Microsoft is trying to buy search traffic (and the associated advertising revenue) because they haven't been able to capture that market share directly.  There's more to it than this, of course, and I'll go into a little more depth in a future post.

In the mean time, keep watching the developments in this buyout, because win or lose, this battle is going to change the face of software.

Reblog this post [with Zemanta]

Greenspan sneezes…

Alan Greenspan's in the news again after he was quoted as saying the current economic meltdown Is "the most wrenching since the end of the second world war."  Now, I know this isn't directly related to software design, but since I've got a degree in Finance, I can't help watching this train wreck, and let's face it - this "situation" has now reached the point where it's impacting the economy as a whole, including software.

Alan Greenspan, KBE, PhD (born March 6, 1926) ...I'll be honest - I don't think it's too beneficial for Greenspan to be skulking around the funeral parlor right now offering commentary on the medical care of the deceased. This man was single-handedly responsible for the most prolonged, sustained, and stable economies in the history of this country, and for that, we're all eternally grateful.  But he's got to realize that he's still incredibly quotable, and the best thing he can do for the economy right now is to just shut up and let the Fed work.  You don't see Bill Gates offering opinions to the Wall Street Jounal about how Ballmer's doing, and I'll bet you won't see Favre giving interviews next year about the play of their new quarterback, and we don't need to hear from Greenspan about how the economy's doing, either.  I know this is the way politics is done - look at the way Bill is campaigning for Hillary.  But Greenspan was always above that, so to see him doing this now is disappointing.

Finance, of course, suffers from its own case of jargon overload, so if you're looking for a really clearly-spoken commentary on our current mess, check out this interview with Princeton economist Paul Krugman.  It's light on financial jargon and deep on content, including a really interesting jab at Greenspan about what he might have done to limit the severity of the subprime mess.

P.S.:

Reblog this post [with Zemanta]

Google Apps trail MS Office, but for how long?

googlemirror This morning, I read a blog post describing how to add page numbers to a Google Docs document.  The crux of the technique was to embed some HTML into your doc such that page numbers are generated when the doc is printed via PDF.  "That's it!" I thought.  That's why Google Apps aren't ready to take down MS Office.

googleprintdialogThen, this afternoon, I just happened (dumb luck, I swear) to use Google Docs to print a draft of an article I'm working on, and I saw this dialog with - you guessed it - an easy way to add page numbers.   And just like that, I saw the problem for Microsoft.  Google, it's true, isn't there yet, but they're closing the gap -- fast.

Microsoft is clearly working hard to neutralize the Google Docs threat with their Office Live Workspace, but I'll bet they're glancing nervously in their rear-view mirrors constantly.

Reblog this post [with Zemanta]

Bug fixes that are more than just bug fixes

It's that time again - time to go through the bug list and do some cleanup.  As I work through these bugs one by one, I've noticed that at least half of them end up being slightly more than just bug fixes.  As I crack the hood and peer in, sometimes I see that there's code inside that's not quite up to the standards of the rest of the application. 

When I see this, I generally try to fix the whole bug, and that means cleaning up (refactoring) the messy bits.  In some cases, you're working on an application that someone else wrote, and in these cases it's pretty easy to blame the mess on the moron who coded it in the first place.  But what if the moron was you?  How do you end up with code that needs this sort of attention if you wrote the stuff originally?  There are tons of great articles and books on refactoring, and they cover this area in much more detail, but here are some of the things you're going to run into when fixing bugs:

  • Code built upon code.  This is probably the most common reason for refactoring.  None of the code you wrote was wrong when you wrote it, but Agile development stresses development one feature at a time, and this sometimes means that you're going to add new code on top of old code and create situations where common functions need to be pulled out, base classes need to be created, and so on.  These things should really be done during development when the problem can be seen for the first time, but sometimes they're missed.  When you see these needs during a bug fix, don't ignore them - they won't go away on their own.
  • New patterns that haven't been implemented everywhere.  This is a similar concept on a broader scale.  Often, we find better ways of doing something during the course of a project - a way we want to organize code, a set of CSS styles that we want to implement all over, or something like that.  Again, we really should take the time to go back and retrofit all of our existing code when we agree on a new way to do something, but sometimes that doesn't happen.  And again, if you're working in a section of your application that was "grandfathered", take the time now to bring it up to spec.

Why bother cleaning up this other stuff if it was working?  For one thing, it's just the right thing to do.  If you don't take care of your code base in this way, your application is going to be legacy code before you go to production.  More fundamentally, though, is that the code probably wasn't working as well as you think if there are bugs logged against it.  Maybe the "old pattern" followed in this code is susceptible to problems that were fixed in newer code.  Maybe the code is more complex than it needs to be, allowing bugs to hide in the nooks and crannies.  Part of a good bug fix is to look for ways to prevent a bug like that from ever happening again, and very often, this means refactoring so that the "fixed" code can be painted onto the rest of your application.

There are times when you don't really want to rip up drywall in order to fix a surface blemish, of course.  If you're late in a release or making a production fix, you absolutely do not want to introduce any unnecessary instability.  This means you'll keep your fix as small as possible to limit the possibility of introducing new bugs with your fix.  Do yourself a favor, though - leave yourself a todo note in the code or a bug in your tracking system so you're reminded to go back at a more appropriate time and clean up.

The next time you fix a bug, take a little time to look around and look for the right fix - not just the quick fix.  You'll end up with a better code base in the long run.

Don’t bring an application home if you can’t feed it.

saddogsm About four months ago, I helped a client put an application into production.  This client has a mix of internal and external customers, and those customers are essentially captive (they have little choice about using this application).  As with any new application, there are infrastructure headaches, customer questions, training issues, and the like.

I was talking with someone today about a support issue, and I asked how they client was tracking calls, issues, and so on.  "Oh, we're not tracking them."  Ah.   And we talked about their customer service staff.  "Well, they're not so much customer service as they are department secretaries that take customer calls."  I see.  "But there's a help desk downstairs - I've seen it," I said.  It turns out that the help desk isn't staffed all the time.

Why?  No money.  And all the while, the customer calls are coming in, and the secretaries are doing what they can to help these poor customers, who don't have a choice but to keep soldiering on.

This organization is probably closer to the norm than we'd like to imagine.  It's pretty common, in fact, to look at the development price for an application and completely ignore the ongoing cost to maintain the system.

Purchased software is no less immune to this problem.  I've helped customers implement CRM systems, for instance, and a critical success factor is the ability an willingness for the customer to invest the time of their employees in the care of the system.  A CRM system is only as good as its data, and even the best systems require data maintenance and cleanup.  Duplicate records need to be merged, assignments need to be fixed, and dead data needs to be scrubbed.  Failure to invest in these activities will doom your system to obsolescence.

When your son or daughter wants to bring home a pet, most of us are comfortable explaining the responsibility of pet ownership.  "If you want a dog, you're going to have to take care of it."

But how many people apply this to their applications?

By the way, if you like the picture at the beginning of this post, check out http://www.imagechef.com/ - you can choose from dozens of stock photo backgrounds and add your own stylized text - pretty cool.

Do you know cause from effect?

I fixed a bug today - a bug that was introduced because a chunk of code was depending on side effects of another piece of code to work properly.  Depending on whether you're ever worked directly with a computer language, this may be a subtle transgression, but the problem is distinct and real, and here's the best part -- if you learn why this is a problem, you'll understand where this flawed thinking bites you in everyday business decisions, too.

So let's back up and look at a non-programming example. Let's say you go in to see you doctor because you're feeling under the weather. The doctor runs some tests and sees that your white blood cell count is higher than expected. A good doctor would know very well that there are lots of reasons this can happen, but someone a little less disciplined who's sitting at home playing "House, the Home Game" might shout out, "it's cancer!" before really having any evidence to support their crackpot theory.

Most of the time, mistakes like this are lots more subtle, but they always start with someone seeing an effect and thinking they know the cause. Sometimes, we guess and we get it right, but often, we don't.

How can we know when we've got it right? We need to relentlessly question the assumptions we make about the things we believe to be true. According to Alan Axelrod in his book, Patton on Leadership, Patton would frequently ask, "How do we know that?" His lesson is that we need to consider our sources of information, because some are intentionally misleading, others are unintentionally incorrect, and a few are reliable. If we can tell the difference, we're doing well.

Instead of asking, "how do we know," we could also ask, "why?" In a recent blog post, Joel Spolsky talks about his company's use of the five why's. Made famous at Toyota, and attributed for part of Toyota's legendary quality, the Five Why's are a structured approach to finding the root cause of a problem. In the case of a business problem, this might mean following a problem beyond our own department to uncover inter-departmental workflow issues, while in software development, this sort of root-cause analysis might lead us to find weaknesses in our architecture. The key here is not to stop asking questions when you get your first answer, because you're probably still missing something important.

In the case of my bug, the code was checking the state of a variable, but the variable wasn't a definitive indicator of the condition we were interested in. Rather, it was a variable the corresponded to the condition we were looking for most of the time. When this pattern changed, our code broke. The fix? Change our code to trap for the condition itself, not a coincidental side-effect.

Lest I lead you to believe that these problems are easy to spot, I'll assure you that many aren't. I've gotten caught a few times with the .Net framework, especially, when I've looked at the value of a .Net framework property while debugging and made assumptions about the general behavior of the property. By believing (falsely) that I knew how the framework was going to work, I left myself open to bugs.

Although it's not easy to train yourself to think this way, a questioning mindset can pay off in a better understanding of things that are really true versus the things we merely believe to be true. There's a world of difference.

Reblog this post [with Zemanta]

Printer-Friendly Calendars in Drupal

I'm maintaining a web site for a Boy Scout Troop, and I set up the Event module and associated bits and pieces a month or so ago in order to publish our calendar online.  Everything worked just fine until one of our parents pointed out that the calendars looked like drunken seagull tracks when they were printed.

Grrrrr.  So I went home and checked it out, and sure enough, the calendars wouldn't print.  So I googled for a solution and discovered that there's a great module for Drupal called, appropriately enough, "Printer Friendly".  I grabbed this, installed it, and sat back in amazement to see that my calendars now looked merely lousy, instead of the formerly illegible.  I have a feeling that the CSS powering the printer-friendly view could probably be tweaked, but I had a Plan-B up my sleeve.

The Events module also supports iCal.  So I wrote a little article explaining to everyone that we had a printer-friendly link, but we also have this cool little icon (  ) down at the bottom of the calendar that lets them load our events into Outlook, Google, or whatever toots their horns. So now, our users can grab all our events, sync them to the four corners of the globe, view them in their favorite calendaring app, and print them using *that* application!

   

Powered by ScribeFire.

Quote of the day

Here's a nice post talking about recent layoffs at an unnamed company.  Best quote:

And as a general rule, when your recently laid-off employees are looking up labour laws right afterward, you probably haven't handled things in the best possible way.

Been there, done that, looked up the laws.  Welcome the state of modern employment.