Sunday, November 25, 2007

Building a Windows Home Server

WHS Parts

Around September, Kami and I decided we would dedicate some money to replacing our dying backup server. It was nothing fancy, just a simple box that backed up important stuff via FolderShare and provided access to our printer. With the impending release of Windows Home Server it made a lot of sense to just wait a bit and setup a new box with that for backup, printer sharing, and away-from-home access. A friend of mine had recently tried to convince me to start building my own PCs for the savings, the customization opportunities, and the ability to build something more likely to last longer. So after thinking about it a bit I decided to do just that, instead of just getting the HP MediaSmart Server. I'll outline the process of building the box in this post, and later talk about installing and setting up the software.

You can see the computer I got as a NewEgg (but without the motherboard, which is no longer available). Some of the things I wanted over the MediaSmart server included dual hard drives with more total storage space, a faster, upgradeable processor and motherboard, and 1G of RAM instead of 512 MB. What's cool is that I got all this for less than the price of the cheaper MediaSmart server.

WHS Assembling

So, everything finally arrived and I found an evening to put it all together. I basically followed the instructions that came with each part and used Jeff Atwood's excellent Building a PC series to direct my efforts. I skipped the overclocking, since I don't really care about that at this point, nor do I have the time to really put that kind of effort into this PC. However, I may do it with the new dev box I'm buying for home use next month.

WHS Assembled

I got everything set up and connected, and it worked! I have yet to install the software, because I have yet to get the software. I planned on using Microsoft's company store to get a nice discount on Windows Home Server, but they've been out ever since I started working on this. And the discount is big enough that I can wait, praying that our old backup server doesn't totally die in the meantime. So I'll post about that soon.

Tuesday, November 13, 2007

Why Keyboard Shortcuts Don't Matter

Photo taken by http://flickr.com/photos/cc511/So, my last post was all about how I'm trying to become more productive by learning a set of keyboard shortcuts that I can use for faster text/code editing. In this post, I'm going to argue against the premise that it could actually make you faster. The reasons I'll outline include opportunity costs, lack of portability, anything else? Well, we'll see, won't we.

First, opportunity costs. Yes, the dirty little secret about using keyboard shortcuts is that it takes time to learn them. The same could be said of command line interfaces. The main reason that most users (i.e. non-power users, those poor souls) don't use keyboard shortcuts, or command line interfaces, is because of the learning curve. And there is an obvious learning curve. I've spent too much of the last couple days working to remember the keyboard shortcuts and use them a lot so I can make them habits. "But wait!" you say, "It's an investment!". Sure, ok, I can buy that. Now let's look at the numbers to see what the payoff on that investment is. This page seems to indicate that you could save 16 hours a year by using keyboard shortcuts. Two whole workdays. Um, that's not much when you consider that it probably takes more than two full workdays to develop the muscle memory needed to really gain that much time savings. So you won't really start to see a return until you've been doing it for a couple years. Of course, others state that the mouse really is faster, so I'm not sure why I even argued that point. Okey, I know, the point is that the mouse is faster for people who haven't yet built up that muscle memory. But then again, maybe not.

Ok, now let's talk about opportunity costs. What else could you do with the time invested in memorizing keyboard shortcuts and making their use habitual? Wisely invested, a few days each year could let you read lots of books, take training courses or attend seminars, develop personal productivity tools (more on this in a future post), start learning a new programming language, or listen to the 1000 songs that can fit on your iPod nano. Doh, I mean your Zune.
Anyway, the next challenge is portability. Sure, you might learn all the cool keyboard shortcuts for vim, or emacs, or Visual Studio, or whatever. But you can't then use them in the others, or in Notepad, or a web browser, or a mail program, or whatever. Even the really basic navigation ones, much less the more interesting ones and potentially useful ones. This actually makes using other programs more difficult once you've mastered a lot of app specific shortcuts. Unless you want to go the route of the "Emacs As Operating System", which may actually have benefits, but only for a very small subset of people.

Basically, those who would use Emacs As Operating System are people with a great memory. Those who can memorize, either in the head or in their muscles, thousands of useful commands. The rest of us are ok with a JIT use of commands. We find them and use them when we need them. Keyboard shortcuts are useful for commands we use more often then once an hour. That can actually include quite a lot of commands if you're a developer who lives in a text editor of some type most of the day. But it probably doesn't extend much beyond that. And trying to develop muscle memory of commands used less frequently will be very difficult.

Wow, I think I talked myself out of my latest project. Guess I'll have to go find some other way to save 16 hours a year...

Monday, November 12, 2007

Visual Studio keyboard bindings and text editor requests

I recently started experimenting with emacs on the many suggestions of Steve Yegge. Unfortunately, just getting up to speed in emacs (i.e. working as quickly as I do in Visual Studio or even vim) was taking a long time and when time is short, as it is during milestone development here at Microsoft, that's not the best way to spend it. So I'm putting off that experiment until work slows down, or until my parental leave in January. In making the decision to stick with VS for the next few months of coding, though, I definitely want to improve how I use the text editor and as I began working to do that I ran across this post by Noah Coad. So I thought I'd respond to Noah and share some of the things I'm doing to improve my keyboard use (and therefore, speed) during development.

My familiarity with the vim and emacs commands has led me to seek a keyboarding compromise. I love vim's ability to navigate very easily on the home row keys. But I like the fact that emacs doesn't have two separate "modes", command and insertion. I always get thrown off in vi because of that. So my navigation keys are basically the vi navigation keys while holding down the Ctrl key. I've also adopted a hybrid of the emacs convention of using Alt to switch from characters to words, lines to sentences etc. So Ctrl-Alt-J moves my down a page, etc. And then, I like the windows convention of holding down Shift while nagivating to select text, so I've added mappings to do that, e.g. Ctrl-Shift-K to select up a line. I've also added some other navigation keys that follow this same pattern, such as Ctrl-0 to go home. Of course, I've also remapped the commands that are at those bindings by default to other bindings depending on how often I use them.

So far this seems to be going well. I'm still learning these keyboard shortcuts and that's taking a little bit of re-education, but I feel faster than when I use the mouse, which is a good baseline to start from.

Now to respond to Noah. I am now trying to use visual studio for more of my text editing needs, and customizing it more so that I can. As I've started doing this I've been impressed at how much power is there that I didn't know about, but also frustrated by the little things that are possible but not easy to do. Searching, replacing, and regular expressions is an area that could definitely stand to be improved. Opening files from the explorer or from visual studio into new instances easily would be nice (an SDI type mode). One thing that would be useful is to have keyboard mappings that can be applied and then removed easily. This would be similar to modes in other text editors, but allow for some specific behaviors in certain cases.

Friday, November 2, 2007

Time for a new phone

Photo taken by http://www.flickr.com/photos/compujeramey/It's time to buy a new phone. One of the cool benefits at Microsoft is discounts on phones and phone plans from most major carriers. So when my contract is up I go back to the discount web site to see what the latest deals are and if I should get a new phone. My current phone is a T-Mobile SDA that is falling apart because I dropped it when running across a parking lot in the rain. It's a great little phone, but it would be nice to have one without a dorky rubber band around it. However, I have noticed other people with pretty beat up SDAs, so they must be reliably durable. However, having used it for a year and a half now, there are definitely some things I don't like about it.

  • Candybar style. It's just to bulky to put in my pocket, so I carry it around in belt clip, but I'd much rather have it in my pocket. The candy bar shape also requires that I lock the keys (which I don't) or I randomly call numbers consisting of an odd mix of 0's and *'s. So yes, I randomly call numbers consisting of an odd mix of 0's and *'s cause locking the keypad is too much of a hassle.

  • No secondary display. I loved being able to look at my last phone (a flip phone) and see the time, missed call information, and number of messages. Now I have to push a key to get that and the information is mixed in with random stuff that the window mobile software puts on the home screen.

  • Four useless buttons. Yes, I know there are hacks to customize the SDA's media buttons, but again, I'm too lazy to do it. So I use the speed dial, which, instead of being speedy, requires me to hold down a button for a long time. Its better than nothing for launching key apps (Calendar, OneNote Mobile), but it could be so much better.

  • Very tiny, but important, buttons. The home button, back button, and the two soft keys should not be the smallest buttons on the phone. And certainly not smaller than the media buttons. I'll throw in here that the power button is difficult to use.


So yes, it could be better. Most of my qualms are with the hardware. However, I think the truly useful benefits and changes to phones could be done in the software. Before going further let me deal with the iPhone thing. The iPhone seems really cool. However, I doubt I'll ever get one. Even if they sync with my outlook perfectly, have a flip phone, all that stuff. I just don't want or need something so complicated. The same critique applies to the Windows Mobile phones out there. I want a phone that does three or four things perfectly.

  • Making phone calls. I don't make a ton of phone calls, but when I do I want it to be seamless, fluid. I want a nice big number keypad with good feedback when I hit the buttons. I want an integrated list of recent calls (in and out), my contacts, etc. Modern phones basically have this list working well enough for me. But most phones don't have a good keypad, least of all the iPhone.

  • Provide reminders. I want my phone to synchronize with all my calendars (home outlook, work outlook, etc.) and remind me of appointments and tasks. It should also be very easy to add one-off reminders for a relative or absolute time in the future. Those should be synced back to the appropriate calendar also.

  • Provide a recording service. But I'm not just talking about the wimpy voice recorder found in Windows Mobile. I want a button on my phone that kicks off recording so that I can instantly start talking. Once that happens, I want a list on the screen of things to do with the recording. The default, for me, would be to put it in my email inbox so that I can be reminded of it. Other possibilities would include making it a task, an appointment, emailing it, etc. Each of these would be preconfigured and would take just one more button click. If I just hit the "End Call" button it should do the default one. And for each of those it should run voice recognition, extract the best guess as to what I said and include both the text and the voice recording.

  • Provide voice access to information. I not only want the increasingly competitive 411 services automatically added to the speed dial (and a good speed dial would be nice), but I want a 411 service that allows me to access some of my own information that is in the cloud. I should be able to ask questions about my schedule, retrieve notes (like my wife's library card number, which is currently in OneNote Mobile), and check for urgent emails.

  • Preferably a slim flip phone. I want to put it in my pocket. I want to have an external display with the time and information about missed calls and appointments.


It's important to note what I left out. I do not want

  • An internet browser. They're too much of a temptation when I'm sitting at my desk. I don't need that with me all the time.

  • A camera. I'm not a picture taker. If I were, I'd want a decent camera with me also, not a significantly degraded phone experience. That said, I'll take a camera in my phone if it is very much a secondary feature.

  • Driving directions, games, instant messaging, videos, a calculator, etc. Whenever something here is useful, it should be rethought as a phone number service I can call. Just as there are web services for many existing desktop apps, so most mobile apps should be phone services with voice as the main UI. Any time I need to enter text it should be possible to do so with my voice and decent voice recognition software, either on the phone or over the line.


At this point I don't think there is a phone that meets my needs. I'll probably settle for something that handles phone calls reasonably well, syncs my calendars, and is a flip phone. And it will have a bunch of stuff I don't need or care about. But I can dream, right?

Tuesday, July 31, 2007

Habits are a Moat

From http://www.flickr.com/photos/logicalrealist/Charlie Munger and Warren Buffett often talk about companies with "moats" or with some intangible asset that makes it very hard for other companies to effectively compete with them. Coca-Cola's brand is their moat. The network effect has created an amazing moat for Microsoft around their operating system business. Google has a similar network effect moat around their advertising business. While I have almost always heard moats discussed in a business context, I was considering Munger's "multi-disciplinary" approach recently and realized that moats apply just as well to individuals and the success that they can achieve.

An individual's moat is their habits. After reading just a little of Munger's writing it becomes clear that his great success in life comes from his habits of learning constantly, using mental checklists, and approaching all problems in a multi-disciplinary way. I've learned enough to recognize how powerful these practices can be but I haven't really made them into habits. Most people haven't. Of course, these aren't the only habits that lead to success, and I'm sure Munger himself has many more. In some ways, his message for individuals is the same as Stephen Covey's in The Seven Habits of Highly Effective People. Although Covey discusses seven specific habits to develop, he also states up front that it is the habits we have that create success. He wouldn't limit success to just seven habits any more than Munger would.

Of course, corporations have the equivalent of habits in their corporate culture, and some corporations have great cultures that work like moats. The moats I discussed above, however, are not primarily culture based. Likewise, individuals can have non-habit moats such as personal networks or reputation. However, I believe that to develop these we need to have the right habits. Scoble's habits of constant blogging and networking have made him into a force to reckoned with in the technology world. Many others have developed the same habits and the same ability to influence others.

Regardless, as I try to become a better software developer in the coming months, one thing that is weighing on me is the idea that I need to be developing the habits of a professional engineer in order to create a personal moat that makes me more competitive. But I'm also looking beyond that to the habits I need to be more successful in other areas of my life - my family, church, hobbies, etc. I suppose its time to go back and read 7 Habits, if only for the reminder of how to change them.

Monday, July 30, 2007

Old Construction Prerequisites

Code CompleteSo it's now been two weeks since my last post committing to a daily post about what I've been reading. I went on vacation to Bear Lake for a family reunion that was great fun except for the bad sunburn I got. I'll have to tell you sometime about my bad burn from '91 (Florida).

Anyway, I did manage to get chapter 3 of Code Complete read at some point during the vacation. I was half-surprised by how much of McConnell's advice parallels the agile principles that are so popular currently, given that it was written about 15 years ago. While the focus is still on waterfall development the value of iterations is recognized and the need for using development practices that "accomodate changes." I did get a kick out of how many of the questions in the checklists are things that might not even be considered up front by many agilists nowadays. The most dated section was the section on programming languages, with no real discussion of modern programming languages like Java, C#, or any functional languages. I'll have to go get me a copy of the second edition.

Wednesday, July 18, 2007

Becoming

Taken by http://www.flickr.com/photos/simonov/Because I've been working to develop myself as a professional software engineer, I recently read Designing Learning by by Andy Hunt and Dave Thomas, the authors of The Pragmatic Programmer. It inspired me to go a little further and write down a specific plan for the things I want to learn and how I'll learn them. Then I noticed that the meme has been making its way around the blogosphere. Ok, now I feel like a copycat. That's out of the loop. Ah well. I'll be documenting my plan and how well I follow it here on this blog. I'll also be using the blog to record things I learn and my thoughts about them.

Just for background, here's a bit about my current state as a developer. While, I don't consider myself a great developer, I do want to improve more than most of those I know. At work I code in C++ and do some powershell scripting.

After brainstorming, I've decided that the areas where I would like to focus my learning are:

  • .NET framework and C#

  • TDD and unit testing

  • Software classics - CS theory and software engineering especially

  • MicroISV and software entrepreneurship

  • Automating everything

  • Other programming languages, such as Erlang

  • Regular reading of journals and magazines, such as Dr. Dobbs


I will be using the following proven techniques to learn:

  • Reading (includes watching presentations)

  • Writing

  • Projects

  • Experiments

  • Discussion with others


So I've chosen 5 specific things to do that include a mix of the things I want to learn and the techniques for learning.

  1. Project: Write unit tests for EGX, begin TDD, avoid Mocks

  2. Read one article, book chapter, etc per day (at work or on commute)

  3. Write about what I've read about on blog, even if it's just a link and a note

  4. Experiment: Spend a day thinking about every activity I do, and how it could be automated

  5. Discussion: After reading an article or two, talk to David about starting a MicroISV


And to make sure it happens, I'll do the following in the next few weeks:

  1. Do an hour of EGX development on each driving day of my vacation

  2. List chapter, article, etc. to read on Joe's Goals each morning

  3. Joe's Goals checkbox for writing about reading

  4. Spend tomorrow considering how I could automate everything I do

  5. Find some MicroISV articles to read on vacation, forward to David


Wednesday, June 6, 2007

The Quality Feature

Waterfall photo taken by http://www.flickr.com/photos/dirgon/In typical waterfall software engineering, the development team goes away for a while and writes a bunch of code. They usually do this after a bunch of planning to estimate how long it will take to write the features they've decided to work on. Usually, near the end of their coding time they start cutting corners to get things to work, and if they're lucky the software will compile and seem to work reasonably well.

At this point it is time to write the code for the Quality feature. This feature presents some challenging when you approach it:

  1. The Quality feature affects all code in the product. It may require work in every class, every file, at every level of depth, and written by every developer on the project.

  2. The Quality feature has a huge test matrix. Basically, think of the cross product of all the test matrices of all the features ever added to the project.

  3. The Quality feature has an unknown scope. Scope is defined only as quality assurance finds bugs and the severity, reproducability, and frequency of those bugs is determined.

  4. The Quality feature determines the success of the product. No other feature, no matter how cool and amazing, can make a product successful long-term if that feature does not have quality.


In the latest IEEE Software, Ron Jeffries and Grigori Melnik present some of the research done on the effects of practicing TDD on both code quality and effort expended. With only a couple of exceptions, the studies summarized show that practicing TDD increases the effort (i.e. time) required to do the work of writing code, and also increases the quality. Although the numbers vary from project to project, the implication is that you spend some more time to get higher quality code. In essence, you have one more feature that you're developing, the feature called Quality. That feature takes some amount of time to write, and it is roughly equivalent to the increased effort required when practicing TDD. Measuring the difference in time or effort expended can provide some idea of the cost of Quality as a feature.

Quality is a feature, like performance, that can sometimes be very hard to tack on after the fact. Implementing the Quality feature while writing code through TDD and other good practices can increases our understanding of how much effort it requires. Because of the unique challenges around the Quality feature, leaving it to be done later not only decreases that understanding, but it also increases the effort required significantly.

Friday, April 20, 2007

TDD and Negative Splits

Taken by http://www.flickr.com/photos/matt_alt/As a sometimes cross country and track runner, I was taught and quickly learned that the best way to run any longer distance is to do the second half faster than the first half. In distance running, we call this negative splits. Those of you who have run negative splits know how different it feels from "positive splits" where you run the second half slower. When you finish a race in which you run negative splits you generally finish more quickly, feel much better, and are excited about running the next race. When you finish a race with positive splits you feel wiped out, beaten down (by everyone who managed to do negative splits), and uninspired. Although there may be and probably are physical reasons for these results, much of it is definitely psychological. If you spend the first half of the race conserving energy and then the second half passing people, it doesn't matter that much that you spent the first half further back than many others. As you begin passing people the psychology of lots of small wins kicks in and really makes you feel good.

But negative splits are hard to do. When the gun goes off your adrenaline is already racing and you want to win. You don't want people to pass you left and right while you run conservatively. Even when you know through experience the benefits of negative splits, it's easy to get caught up in the moment and start too quickly. Or it may just be that the race leaders seem so far ahead of you that you have to go faster or lose all hope of remaining competitive. Pride may drive you to run faster earlier. Or it might be a justified fear that by trying to run negative splits you actually start off too slowly and never make up the time.

In the past couple months as I've started practicing test driven development of a new feature that I own, I've felt very much like I'm in the first half of a distance race. I know that I'm progressing slower than I have in the past, if you simply measure my progress in writing code that will ship. I can feel that I'm taking longer to do what I'm doing. However, I also feel like I'll be able to complete the feature faster, which mostly means that the bug tail will be much shorter. Looking at the code I've written vs what I've done in the past I know there is an improvement. The daily process of writing tests, and then writing code that makes them succeed is as addictive as passing people in a race and keeps me excited about the end result, even if I'm moving slower by some measures. At the same time, I feel like a better developer, I'm able to make changes more quickly, and I'm more excited about my work.

Tuesday, April 3, 2007

Moderation and Measurement

Moderation is a quality that I would say I lack. The Oxford English Dictionary defines moderation in this way:
avoidance of excess or extremes in behaviour; temperateness, self-control, restraint.

The specific example I'm thinking about at the moment is eating. Although I've never been fat, I have definitely been prone to eating more than is healthy. Around the holidays I would get sluggish, cranky, and apathetic because I filled up on junk food and didn't eat anything healthy. During the rest of the year I ate healthier (out of site, out of mind), but still ate too much. As my life has become busier and I haven't made time to run on a daily basis, that meant I started to gain weight. While it was slow gain, after a few years the pounds add up and I was having to buy clothes that were a different size. I felt fat, though I know I didn't necessarily look it.

During the time I was gaining weight I became acutely aware of my problems around the holidays - they just weren't fun when I felt drugged up on chocolate, sugar, and grease. So, immoderately, I forswore candy and chocolate. Initially, I wasn't sure how long I could keep it up, but as the weeks and months passed I gained a sense of self-control that I had never had before. It felt great. Of course, I had to put up with my wife heckling me because now she had to eat all the chocolate and candy and knew it wasn't healthy for her. I also didn't eat some of the things she loved to make for me. And when Christmas came around again, she struggled to come up with treats to fill my stocking with. Besides all this, she wasn't sure whether to be proud in public situations when her husband declined candy or chocolate, or to be embarrassed.

I ultimately kept up the chocolate and candy ban for over a year. Why did I go back? Well, when it came down to it, living without chocolate and candy wasn't very fun. However, about a year later I knew it was time for a change again. I couldn't seem to enjoy chocolate and candy in moderation. But I could abstain completely, or risk going overboard. This time I only banned candy, and kept it up until I started trying to lose weight. Then I promised myself I could eat as much candy as I wanted once I hit the bottom of my target weight range, and do so as long as I was within that range. But after just a couple months of that I was reminded (again!) of how crummy it made me feel, no matter how much I weighed. So I'm off candy again. So that gives you an idea of my problems with junk food.

Now back to losing weight. You might imagine that when I noticed that I was eating too much I would start fasting until I hit my target weight. It sure felt like, because I started Weight Watchers, and that reduces your caloric intake (well, mine anyway) by about half. Fortunately, I didn't take it too far (hunger is very powerful), but was able to get down to my target weight in about three months. As I did that I developed the habit of checking my weight on a daily basis. I know that this is more frequently than necessary, but it gave me motivation each day when I was hungrier than normal.

Now, almost six months later, I'm still well within my target weight range and I'm able to eat pretty much what I want. The key, I've found, is the daily measurement. By doing that it's easy to see over a week or so, if I'm starting to head up and to correct course. For me, the daily measurement is just enough incentive. And because I'm doing it, I feel very free to eat whatever I want (candy excluded for other reasons). So I have no qualms chowing down at a restaurant or filling up when Kami makes my favorite food.

The key to my success in keeping the weight off, so far, has been daily measurement. So I've been thinking about what it means to use regular measurement as an aid in developing moderation. Of course, my daily weighing is more than just measurement - it is a negative feedback loop. If my weight starts to creep up, my natural desire to stay on target moves me to restrict my eating a little bit to fix the problem. Because I'm measuring daily "fixing the problem" is fairly easy to do, and doesn't require a lot of self-control or discipline like the initial weight loss did. Tight negative feedback loops are how nature is able to moderate its processes, and the same is true for us humans.

One trick to setting up effective negative feedback loops to moderate our own behavior is tuning the feedback to our weaknesses. For me, just knowing how my weight is changing, combined with my natural desire, is enough to move me to start tightening my intake. However, I know that I need something more powerful if I want to attempt moderation in my candy eating. I would need the feedback to make me quickly and significantly unhappy in some way, or I'd just keep eating.

Another trick is to make the feedback come automatically. If I have to do too much to get the feedback I need, I'll just tend to avoid it so I can keep eating candy (or whatever it is). Fortunately, weighing myself was done on a daily basis and became a habit. It didn't seem directly related to eating food, so I didn't have any desire to avoid it. It worked out well for me. In general though, I think this can be very challenging when it comes to personal habits that we want to moderate. It tends to be easier to abstain completely or indulge completely.

For certain habits and certain people a tool like Joe's Goals might be just right, though it does require some work to record how you did on a daily basis. Ultimately, though, I think the real gains are going to be in areas where you can find a way to make the feedback more automatic, and the feedback response the correct strength to make the change happen. That said, I really need to wrap this up so I can go invent a machine that will shock me every time I eat more than one piece of candy in a day...

Thursday, March 22, 2007

Unit Tests and Asserts in Legacy Code

Because I'm currently learning about unit testing, TDD, and other agile practices, I admit that I recently considered the possibility of doing some greenfield development. While a part of me would love the experience, the challenge of using these techniques in legacy code to improve the product is very motivating to me. Along those lines, I recently followed an interesting debate about the relationship between unit tests and asserts in production code on an internal discussion list. Microsoft is big enough that you hear from people using all types of technologies and at lots of different stages in the transition to unit testing and TDD.


Assertions


Years ago, the state of the art practices for verifying code included a liberal dose of assertions scattered through the code that would run in a debug build. Generally, an assertion would notify the user and abort the program. When an assertion failed, you could debug to find out what was wrong. Generally the assertions are closer to the problem in the code than any other bad behavior you might see if the assertion hadn't fired. Often assertions were used to verify contracts along an interface. Unfortunately, in some cases assertions were used in place of proper error handling. At other times assertions were used to verify global state assumptions. Assertions generally lead to two sets of binaries for your program - an official set and a "debug" set that developers and testers can use to find bugs.


Good Guy, Bad Guy


Assertions can often be categorized as either error handling or as there-is-no-way-this-could-happen. Assertions that are used for handling errors are bad. Instead errors should be handled either via a proper return value, or via exceptions. I won't get into the debate here about which should be used. Assertions that fall into the there-is-no-way-this-could-happen category are probably better handled via code correctness tools that analyze code paths to verify certain properties of the code, though there is probably little harm in using these assertions.


Often assertions were used to do in-place unit testing. External unit testing is a natural next step from such assertions. Before discussing unit tests, however, it's helpful to note that these assertions were a good thing. They tested the code every time it was run (at least in the debug version) and was often easy to understand with the surrounding code as context.


Unit Tests

Unit tests are a different way of validating code correctness from within the code. Instead of creating two sets of binaries, you essentially create two sets of source code: one that is the program, and one that verifies the program (Note: two sets of binaries may still be created). Unit tests, if written well, can verify the code in ways that are not easy to do with asserts alone. Unit tests are run regularly while writing code, while asserts fire only if a given code path is exercised in some way. Unit tests can specifically test code paths that might not be exercised normally. Unit tests can be written with the code to shape the code itself, if you are doing TDD.


Unit tests can do a lot more ... Oh wait, like I said, I'm still new to all this agile stuff. So it was interesting to listen to the agile believers argue against any assertions while others made the case that assertions were useful in some situations. I must admit that the idea of having no assertions at all was shocking at first. But it immediately became appealing as an ideal once I understood how clean code without assertions might be. However, in a large legacy code base with lots of asserts you're not going to escape assertions easily. And honestly, after some thought and experience, I believe that the two methods are complementary.


Asserts in existing legacy code are an excellent starting point when trying to get the code under test. Using the techniques in Working Effectively With Legacy Code, write tests for your code that exercise it well. Initially, if you've got a good set of asserts, positive unit tests can be written that don't even verify much, as long as your framework interprets asserts as unit test failures. Of course you'll want to write tests that cover more than just that, but it is a start and will provide some level of safety when refactoring. If your unit test does not interpret asserts as unit test failures you can use a seam (link seam, preprocesser seam) to redefine assert in the binary you compile for unit testing.


Do unit tests make assertions redundant?

In writing new code within the legacy code base I definitely find myself using less asserts because I am writing unit tests as I go. However, certain things are much easier to test with a well placed assert in the code, rather than the unit test. In talking with a colleague the other day I was reminded that making code unit-testable can make it more complex than it has to be. Because of this, I believe that assertions in code can have the beneficial effect of simplifying the code you write by making it somewhat easier to write unit tests around it. This can lead to better factored code that doesn't make it so obvious that it's been engineered in order to accomodate unit testing.


Resources


_ASSERT macro , assert , Java's guide to Programming With Assertions


Unit Testing , Unit Testing Legacy Code

Tuesday, February 20, 2007

More on personal advertising

Thanks to blogosphere commentary on my last post, I found out about Take Back Your Brain, a whole blog devoted to advertising to yourself. This is awesome, and just wanted to let everyone know about it.

Monday, February 19, 2007

Advertising to Yourself

I recently read J.D.'s post at Get Rich Slowly warning us to Beware the Insidious Power of Marketing. It reminded me of the power of what we see, hear, smell, taste, and feel to influence our actions, even in ways we are unaware of. Advertising takes advantage of this by doing it's best to subtly move us closer to making that next purchase, to buying just one more whatchamacallit, to "investing" in a bigger home, a faster car, or a nicer computer. However, the power of advertising and marketing can be used for good too. The concepts behind effective advertising are fairly simple psychological principles. Because they are being used by people to make a living, the application of the principles of psychology to influence behavior has been studied and perfected over many years. We can take advantage of those principles in our lives to change our own behavior just as effectively as the advertisers do.


Personally, this means that I try to surround myself with "advertising" for my goals. The idea is embodied in lifehacker's recommendation to make a collage to get motivated. They don't talk about doing anything more than just making one, partly because that can be so motivating by itself. But of course, you'd need (well, I'd need) something more frequent and regular to fight the advertising designed to get us to eat a lot. Make sure to put the collage up somewhere that you'll see it every day, preferably many times a day. Trust me, that's cheaper, timewise and magazine-wise, than making a collage every day.


Of course, making a collage is not the only way you can advertise to yourself. Something I've started doing is listening to motivational talks by men and women I admire. Podcasts about hobbies you want to spend more time on can be just what you need to actually do something about it. I can't tell you how many times in the last few months I've been listening to a podcast on the commute home and made a note to myself about something I should change or do. When I follow through on that, I feel great. Even better, when I don't I'm usually reminded of it the next day or the next week by another podcast.


And that's exactly what advertisers are trying to do. They fill your head with ideas of things to buy and then incessantly remind you about them. They often do it by claiming, explicitly or implicitly, that if you just have their product, then you'll be rich, famous, in control, powerful, funny, cool, athletic, healthy, happy, relaxed, or whatever. Of course, owning a given product doesn't make you that person, or we could all be perfect by taking on enough debt. And a perfect person could pay off the debt easily, right?


But wait, aren't I recommending that you advertise to yourself in order to become all those things and more? Frankly, yes, if that's what you want. However, the key to advertising to yourself is finding out what it really takes to change. If your goal is to run a marathon, then advertise that goal to yourself in a way that actually helps. Some of that advertising can be "awareness" based, just to regularly remind you of your goal. At least some of it should link that goal to the actual steps required to acheiving it. And by this I don't mean buying the latest, most expensive running shoes that you saw in the mailer from your local sports shop. The key is finding ways to link the euphoria that you're sure will accompany accomplishment of your goal to the sometimes hard-to-do things that are required.


Of course, advertising for real products can be used when you're doing this. Some of the most inspiring stuff out there is in the form of advertisements, such as Nike's Move commercial. Just don't feel like you have to buy Nike's shoes in order to move. And the tools now exist to make exposing yourself to this great stuff, whether it's commercial advertising or not, very easy.



Speaking of tools, I have to admit that my MP3 player died a couple weeks ago, and I've gotten so used to my personal advertising during the commute that listening to the radio is a trial. In my mind, it's well worth the investment to buy a new MP3 player, because it's an investment in myself.
The key for me to remember is

"If I can market to myself the person I want to be, slowly but surely I can become that person."

I'll have to post that quote on my mirror or something...