Friday, April 9, 2010

Wrapping code: Good practice?

I wrap native code because:
  • Wrapping makes it extensible.
  • It's easier to remember.
  • The native code is absurdly lengthy / wordy / etc.
  • Code in the library will never be lost.
In the halls of computer science (a discipline that hadn't been invented when I was in college), do deep-thinking people ever advocate the idea that calling native code directly is a *bad practice*? That code should be wrapped in a method, to make it extensible?

Here's an example I ran into last night:

I've written a utility for executing miscellaneous C# methods, which has a f.OpenFile() helper method that wraps Process.Start(). Pass in a file name and it opens using the associated application. f.OpenFile() adds a *little* functionality, throwing an exception that logs the file name, when the file doesn't exist. So far, the method is called about a hundred places.

Last night I enhanced it to prompt the user when the file doesn't exist at the passed path, allowing the user to browse to the file's location, and applying that location going forward. If the alt-key is down when the utility method is run, the user gets the prompt regardless of whether the path is valid -- so the user can point the method at a different path. That let's me change the path without going into the code, a time-saver.

I could not have done that (without difficulty) if I'd had 100+ Process.Start() calls in my code. With f.OpenFile(), I only had to change the code in one place. It was easy to add the new feature because ProcessStart() was *wrapped*. I had a hook. It made Process.Start() extensible, in some sense.

Over the years, this pattern has occurred often enough, and *so usefully* -- that I wonder if it has been recognized with a special name??

Another reason I wrap code is because my brain has tired RNA. I can't possibly remember this:

using (StreamReader streamReader =
new StreamReader(HttpWebRequest.Create(_theUrl).GetResponse().GetResponseStream()))
return streamReader.ReadToEnd();

But I can remember the wrapper method f.GetUrlsHtml(). A few months ago, I refactored f.GetUrlsHtml(), and I *could* refactor it, because it was wrapped, instead of being native code in a couple dozen locations. I suspect this may be considered to be a bad practice, because *so often* I see the same tired block of code repeated and repeated, copied and pasted. Doesn't DRY imply *"Wrap it!"*?

Wrapping seems particularly appropriate, when it takes too many lines to do something simple.

f.ExecuteCommand(@"%SystemRoot%\system32\restore\rstrui.exe", 0);

The method executes about 10 lines -- which *begs* for wrapping, to me.

And yet another reason to wrap: laziness and/or esthetics.

if (String.IsNullOrEmpty( aStringVar1 ) || String.IsNullOrEmpty( aStringVar2 )) ...

To me, String.IsNullOrEmpty() seems ridiculously long. It's tedious and distracting. I wrap it:

if (f.ns(aString1) || f.ns(aString2))

The "ns" stands for Non-String. Once, it just called String.IsNullOrEmpty(), but now f.ns() returns true if the string is all *whitespace*. When you're validating a string, don't you want to catch it, when the calling code passes a single space? With f.ns(), I can set a breakpoint to catch where in the code an invalid string is passed.

Could that be done with String.IsNullOrEmpty()? I'd like to know; that could be very helpful.

Another reason for wrapping code is so it doesn't get lost. A friend emailed slick code applying LINQ to subtract one List from another (T being a simple type). I wrapped it in a method, so I could test it, and so it would be there when I needed it... which wasn't too long in coming. I routinely wrap code that I find on the web, that I'll find useful someday. It will never be lost if it's in my library.

I guess I could put code in a repository for that purpose (anyone have a recommendation?), but then I'd have to *find* it. It's easy to find in Visual Studio.


An argument *against* wrapping is that the code is unfamiliar, because I invented it, so no one else will understand it. f.ns() is obscure, I admit. "Right-click, Go To Implementation" is pretty easy, though. The name f.GetUrlsHtml() is more transparent than the code it wraps, right? Maybe f.GetHtmlFromUrl() would be better (I love VS's rename!!).

I guess using the methods creates a dependency on the method library. OK. I'll deal.

Are there other reasons why wrapping frequently-used code is a bad practice?

I'm really intent on getting better at this. Your responses are appreciated.

- Hoytster

Saturday, March 20, 2010

IronPython notes

Michael Foord http://www.voidspace.org.uk/ironpython/hosting_api.shtml

Business rules stored as a Python or Ruby backed Domain Specific Language could be extremely useful - they can be read / written by business managers, rather than programmers, and even changed at runtime.

.NET 4 offers the dynamic keyword in C#, which makes it much easier to use DLRs like IronPython.

This is an example of coding C# dynamically:

http://keithhill.spaces.live.com/Blog/cns!5A8D2641E0963A97!6676.entry?wa=wsignin1.0&sa=168208183

C# 4 supports named parameters and optional parameters, to make it easier to call Office methods.

Thursday, March 18, 2010

You're getting sleeeeeepy, sleeeeeeeeeeeeeeeepy

I saw Dr. Stillman (call him Mike!) yesterday. We focused on sleep. He prescribed Lunestra, every other day; eliminate alcohol; and get more exercise.

Last night Janet and I enjoyed a beer together to celebrate St. Patrick's Day. That is the last alcohol I'll have (in theory) until April 18. I was tempted to eat after dinner, as usual, and went so far as opening the drawer containing the huge chunk of super-sharp cheese -- but I closed it -- and decided that I was really looking forward to breakfast (I put some cheese in my organic tomato basil soup). And I didn't drink any alcohol.

Lights out was 10:30 and I feel asleep easily. I woke around 2:00, got up and played with the computer for 45 minutes, felt sleepy and returned to bed and slept. I woke up again at 5:00, stayed drowsily in bed until 6:00. Feel sleepy this morning.

Breakfast was too many calories: a good sized bowl of the soup, plus maybe 2-3 ounces of cheddar -- and then a large orange and a large Chinese pear on the way to work.

I did my first real weight-lifting session in at least a month, working pretty hard for maybe 45 minutes. I feel slightly weaker than previously. I added the leg press to the routine. I need a new routine.

Two pounds a week requires a calorie deficit of 1000 per day. Lots of luck. I'll settle for 1 or 1.5 pounds.

Monday, January 4, 2010

Take my own advice, dernit

Sent to a friend. Posted here so I can review as needed.


Here's the diet strategy that works best for me.

1) Commit to exercising every day. Make a plan at the beginning of the day. Even if I do not manage to exercise 7 days a week -- trying to helps me exercise more often that I would otherwise. I bought PowerBlocks so I have the equivalent of dumbbells in the range 10-45 pounds in 5 pound increments -- in the space of 1.5 shoeboxes. 20 minutes of weight-lifting kills me, and my bench is set up in the basement -- so there's always a way to exercise, and always time.

2) Get in the habit of eating more-or-less fixed meals for breakfast and lunch. I'm eating steel-cut oats for breakfast every day. Literally, the entire processing is cutting up the oats into smaller bits -- which means they take longer to digest and pose less of a sugar hit -- which is what leads to hunger. Lunch: broccoli and friends from the caf. Oats lower cholesterol.

3) Continually get information on the subject, to keep me in the game. FitnessRocks.org has 150 podcasts from a physician - fitness nut, that Susie can put on her iPhone and listen to while she grocery shops or works out. I'm on podcast 60 -- my second pass through the collection. RealAge is good. I keep this excellent book next to the bed and pick it up every few days. Check the reviews on Amazon. You want to be eating the Mediterranean diet. A huge error I made for decades was avoiding fats in food. There are healthy fats, esp. olive oil. Atkins worked for millions, and that wasn't low fat.

Something I have not tried, which I intend to try, when I'm a bit fitter and the weather is less nasty -- is seeking the company of skinny people. A FitnessRocks episode and other sources present research that being around heavy people makes you heavier. Your psychological set point changes, or something. With luck, this spring, I'll get routinely involved with my wife's running club. There are a couple people there as chubby as me -- but the average is more like the general population looked, 40 years ago. I went to the club's annual party a few weeks ago and was struck by the seeming gauntness -- which is what used to be normal. I wince when I think of Wall-E -- how the captains were successively heavier, the whole population huge. How many captains into that sequence am I? With 67 percent of U.S. adults overweight or worse, "normal" is not healthy.

An email about identifying duplicate MP3s (etc)

How do I find duplicate music files?

Here's an idea for finding duplicate music files at the album level, that is, when the MP3s are organized from the start by album.

Order the MP3s by run time -- how many minutes and seconds they run. Using the run time accounts for the fact that there can be several versions of a song -- if you want to keep the versions (like, single vs album). It would work across formats, like MP3 vs WMA vs FLAC.

Compute the ratios (within some accuracy) of one to the next, and turn that into a hash that serves as a unique key for the album. #1 is 1.3 times longer than #2, which is 1.13 times longer than #3, which is 1.4 times longer than #4, etc Using the ratios might help with error estimating the run time; the time would be off systematically, we hope. It might be best to compute the hash from the 3 or longest, to avoid accumulating too much error. Experimentation would show that, maybe.

Given the hash, compare it to the other albums that have the same number of songs. If you find a match -- keep the bigger set, hoping for higher quality. Or always keep FLAC, if you like FLAC.

Can you determine the MP3 run time in C# code? I dunno. I saw a couple comments where people were struggling.

So figure it out by playing them! Write a hugely multi-threading app that simultaneously plays as many MP3s (or FLACs, etc) as your computer will manage. Use some tag-writing code to stash the run time in the ID3 tag, so you only have to play it once. Do the math: if you get (pick a number) 100 players going at once -- can you get through your collection before the energy death of the universe?

This might be helpful. This was impressive, but probably not so helpful, except conceptually maybe. Here's a way to play 'em. This enlists Windows Media Player to get the length.

Tuesday, December 15, 2009

Email not sent, because NO ONE COMMENTS

I just decided not to email this to the local standards keeper, as we set out on a new project.



I would like to suggest a standard that almost no one else is the world things is sensible: a developer coming to unfamiliar code should be able to understand it by reading the comments. In my view, the comprehension of code is like a transuranic element -- rapidly decaying, short-lived -- and that's in the mind of the coder. Expecting someone else to read code and simply get it is unrealistic. Oft times, the coder spent a lot of time figuring out how to code something; the code embodies business logic. When that thought process is not captured in a comment -- it vanishes. And it has to be in a comment in the code, else it will be lost. "We wrote that up in the functional spec, that's never been updated and we can't find it anyway." That doesn't work.

It doesn't take that long to type comments. We type for a living! The confusion and uncertainty presented by poorly commented code yields wasted time trying to comprehend code, and more time chasing down bugs introduced because of a failure to comprehend the code correctly. Comments save time.

I have heard of the argument that excessive commenting is worse than no commenting, because the comments get stale and are misleading. The easy answer to that is "Maintain the comments as you modify code." I would encourage people to comment excessively -- because if they lean in that direction, the chances are increased that they'll comment adequately.

A while back, I incorporated this standard in a automated code reviewer utility: it computed an estimated ratio of comments to code, and while there was no specfic ratio required, a low ratio made the coder suspect, and more likely to get dinged for insufficiently commenting during the real code review. The utility worked with enhancements, in addition to new code, because we applied the utility to the differences listing for existing code.



I write to deaf eyes, I know. No one comments. It mystifies me and makes me crazy.

Thursday, December 10, 2009

DropBox: Switching out the music with ease

DropBox.com is a service that synchronizes files across the internet.

Today I put it to good use for the first time. I decided to would listen to the most recent 5 remastered Beatles albums at work today. So, this morning, I copied the albums to the DropBox folder on my home computer.

About 20 minutes after I turned on my notebook at work, the Beatles music was there in the notebook's DropBox folder.

It couldn't be much easier.

Do any operations on the DropBox folder -- adds, deletes -- and they are reflected in however many other computers have the DropBox client installed, associated with your account. When I'm done with the Beatles, I'll move some Frank into the folder; it's the anniversary his birthday Saturday.

DropBox gives you 2GB of space for free. The next price point is unfortunately expensive: $10/month for 50GB. If they charged by the GB, I'd sign up for 10GB for $1/month.

Maybe I'll suggest that.