Visual Studio 2008 installs .NET 3.5 SDK v6.0A, which is what NAnt 0.86 expects to run against – however, the .NET 3.5 SDK that is available for download, via the "Windows 2008 and .NET 3.5 SDK", is v6.1. It’s a small difference, but that difference will cause NAnt 0.86 to not be able to target .NET 3.5 if you are using the downloadable .NET 3.5 SDK. When you try to run NAnt 0.86 and have it target .NET 3.5 with the downloaded .NET SDK, you will get an “Object reference” error from NAnt and the build will fail immediately. Page Brooks has the details of how to fix NAnt to work against the v6.1 SDK. It is an easy fix, but it requires that every machine running NAnt have the v6.1 SDK installed (and if you want your devs to be able to run NAnt from their local machine, you’ll need all of the developers to install the updated version of the SDK). End Result: If you want to automate your VS2008 project builds with NAnt, you should probably have every developer on your team to install the new version of the SDK and have NAnt target that version.
I decided to jump on the bandwagon of Twitter, to see what it may be able to do for me and getting into the community a bit more. You can follow me, at http://twitter.com/derickbailey For my client, I've installed Twhirl, which uses Adobe AIR as it's platform. http://twhirl.org/ It's a pretty nice client, so far. Easy to setup and use. Thought it's my first Twitter client, so I don't really have anything to compare it to, other than standard IM clients.
If you have a batch file that takes two parameters with quotes around them, and you concatenate them together, you get too many quotes. For example, if you have “test.bat” file with this code in it: Echo %1%2 And you run it like this: Test.bat “C:\” “Program Files\” You end up with this result “C:\””Program Files\” Which is not a valid folder. I’m trying to get this result: “C:\Program Files\” The problem is, I have to put quotes around both parameters on the command line, in case there are spaces in the folder names. The solution to this is to use a ~ character in the variable, like this: Echo %~1%~2 Running that command in the test.bat file produces this result: C:\Program Files\ More info and parsing capabilities can be found here: DOS - String Manipulation
I'm watching G4TV and they bring on "The Feed" - news bit and updates on stuff - and start talking about how Twitter was talking about the earth quakes in China well before any new coverage was occurring; including major Internet news providers. ... and what images do they decide to show during this bit? A very large image of "The Scobilizer" website with his post on Twittering China. Man, this guy is huge!
I hate the Try Catch syntax in C# - it's bulky, ugly, and makes my code hard to read. try { // do some stuff here } catch { //handle exceptions here } finally { //clean up here }
Although very functional and well documented, to the point where it can be effectively used, I don't see the elegance that I want in my language - especially if you actually have to catch a specific exception and deal with it in the middle of your functional code.
So, I'll create the elegance that I want.
public class TryCatch { public static Exception Do(Action action) { Exception caughtException = null; try { action(); } catch(Exception ex) { caughtException = ex; } return caughtException; } }
With this very basic implementation, using lambda expressions, I can create a much more friendly syntax to use:
Exception ex = TryCatch.Do(() => { //Do Stuff Here, with assurance that an exception will be caught, if thrown. }); //send the exception off to the exception processing / handling, if needed.
From there, you could add a "fluent" interface to catch specific exceptions, have a finally block, etc - but you end up with the same ugliness that I wanted to avoid.
//Blech. This just puts us right back in ugly-ville TryCatch.Do(() => { //throw exception here }).Catch<Exception>(() => { //handle exception here });
ugh - ugly, for that matter. That didn't help us at all. And we don't need it, anyway. You are guaranteed to have the before and after TryCatch.Do execute.
//setup IDBConnection conn = GetMyConnection(); TryCatch.Do(() => { //execute conn.Open(); }); //cleanup if (conn != null) conn.Dispose();
I like it.
A lot of people talk about software in terms of manufacturing and construction - laying the foundation, getting the architecture in place, building components, assembling the final product, make sure we have all the plumbing setup, wire it all together, etc, etc, etc. "The problem with the construction and manufacturing analogies, is that they fall apart as soon as you start talking about software as construction and manufacturing." - me Software developers are not construction or manufacturing workers. We don't sit on an assembly line, mechanically reproducing the same result over and over and over again. We don't (or at least, shouldn't) put all the plumbing and frames in place before anything else. We're not line workers, warehouse workers or laborers. The only parallel that exists between any manufacturing or construction positions, and software development is that we are research, design and development workers. Some manufacturing companies have R&D positions, some don't. Some construction companies do, too. Software development is ALL research, design, and development. When it comes down to it - source code is not a foundation, a structure, a component or any of the other parallels that people try to use. Source code is a specification for how an executable software package will be built and will behave. We don't build the executable software package - the compiler and build scripts do that for us (if you are manually building the software, go learn NAnt, Rake, Make files or some other automated build process for your environment). What we do when we write source code is R&D - research, design and development... hence the name, "Software Development". Therefore, "The only part of software development that even remotely resembles manufacturing or construction is the moment we click the 'build', or 'compile' button, or kick off whatever script or command, and the build process does the work for us." - me 
I saw "The Forbidden Kingdom" this weekend. Overall it was a great movie - lots of good action, a good storyline, etc. But there was one scene that stuck in my mind specifically. Jackie Chan is pouring some drink into a cup while the person holding it is talking. The cup quickly overflows and the person holding it notes that the cup is full and now overflowing. Jackie Chan's response was something to the effect of How can you fill your cup when it is already full? How can you learn anything when you 'know so much' already? The point of this, of course, is that the student thought he knew so much already and wanted to get right to the advanced stuff rather than letting the teacher guide him through the basics into the advanced stuff. As silly as it is for a pop-culture movie to have deep wisdom, I really thought that this scene's message was applicable to more than just martial arts. The same can be said of any situation where knowledge, learning and growth are present. One of my coworkers (Michael Adkins - who's blog is not publicly available, yet... *nudge nudge*) recently had a post that talked about the same thing, with a slightly different quote at the beginning. Rather than me re-hashing his post with my own interpretation, I'm re-posting his post in it's entirety (with his permission, of course). So, you think you know everything about development eh? A wise man once said, "He who knows everything, cannot be taught anything." This is such a profound statement. When it comes to learning, I attempt to look at the learning process as if I don't know any of the material (all things being equal of course). This allows me to see things I did not see in the past. It allows me to critically think about ways to solve problems with the new knowledge I have gained. Sometimes when a person asks questions, it is perceived that the person doesn't have a clue as to what is going on with the process. In my case, it is my acid or litmus test to locate a person; to see if they can articulate an answer that tells me if they are trying to help or build their ego. Nevertheless, whether a person is helping or building their ego, they are still helping with all types of insight. They just may not be aware of it. This is something we all may be guilty of in some form or another. But it just goes to show that we don't know everything. It also goes to show that we continue to teach and instruct when we think we know everything. This blog came about when I was going through a webcast that dealt with Delegates. I couldn't have said it better. ... I just hope that I'm not the guy who's cup is already full.
I found myself doing this, and I had all kinds of creepy-crawlies in the back of my mind. It's a VirtualPC instance of Windows XP, and I'm installing VMWare Infrastructure Client so I can connect to VMWare ESX, to test out VirtualCenter's features, etc... it just feels soooo wrong. I need to buy a copy of VMWare Workstation so I can get rid of this dirty feeling that I have. 
I've been learning a lot lately - reading up on Agile, Lean Manufacturing, Lean Software Development; experimenting with NHibernate, exploring UnitOfWork concepts and generally trying to become a better software developer. In this process of learning, discussion with others, and application of knowledge to my environment, I've found that knowledge is very distinctly different than understanding. Let's look at my use of NHibernate as an example. 2 years ago, I knew the basics of what NHibernate could do for me - I spent a few weeks learning the very basics to see how it worked and whether or not I wanted to use it. 1 year ago, I actually started using NHibernate for a project and my knowledge of it quickly grew. I knew how to create the appropriate mapping files, configure NHibernate, etc. As this knowledge grew, I became more and more interested in what NHibernate could do and how it could be applied to many different applications and situations. I knew a lot about how NHibernate was built, how it worked, and what it's capabilities were. However, all of this knowledge was not a substitute for a real understanding of NHibernate. My knowledge of how it worked led me to some conclusions that I don't think are correct anymore - trying to apply NHibernate in situations where it really was not the right answer. I've seen the same problem occur multiple times in the last 6 months, and in the last 11+ years of my career. There's almost a recognizable pattern to the learning process: - Learning curve to gain working knowledge
- Knowledge growth and intimate familiarity
- Assumption that knowledge gained is a substitute for experience and understanding
- Attempts to apply knowledge incorrectly / in wrong situation
- Realization that knowledge is not understanding or experience
- Stepping back from knowledge to gain understanding of how/when to apply the knowledge
I've done this with Agile/Lean software development as well, recently. I've gained a significant academic knowledge of agile and it's processes and practices. Some of my knowledge is directly backed up by experience, so I believe I do have some understanding of the agile engineering practices. However, I've let my limited understanding mix itself into my academic knowledge a little too much. I've found myself in situations recently where I'm arguing a logical conclusion to a situation and applying it to another situation incorrectly. One of my coworkers likes to apply this adage to situations like this: If a hammer is the only tool you have, everything looks like a nail. I need to remember to step back from my raw knowledge - be it academic or real world use - and let common sense and experience interweave into understanding or the realization that I don't understand. I need to understand that just because I am currently holding a hammer, and thinking about hammers, that doesn't mean that the problem in front of me is a nail that needs to be hammered. The realization that knowledge is not a substitute for understanding can be a very distressing and/or humbling experience. The reality of learning, knowledge and understanding, though, is that I can have every last bit of knowledge on a subject - but without experience to guide me, I can't always understand the where/when/why/how of applying that knowledge appropriately.
One of the primary goals of Lean Manufacturing in the elimination of waste. This may seem like an obvious goal - after all, who wants waste in their system? What's really interesting, though, is seeing where the term "waste" is actually applied and how Toyota redefined what waste really is. Muda, the concept of the seven wastes in the Toyota Production System, is a very different concept of waste than most of us would consider. It talks about not only physical waste (trash), but also logical, time, and effort waste. These seven wastes include (from Wikipedia): - Defects: Quality defects prevent the customers from accepting the product produced.
- Overproduction: Overproduction is the production or acquisition of items before they are actually required.
- Transportation: Each time a product is moved it stands the risk of being damaged, lost, delayed, etc. as well as being a cost for no added value.
- Waiting: Refers to both the time spent by the workers waiting for resources to arrive, the queue for their products to empty as well as the capital sunk in goods and services that are not yet delivered to the customer.
- Inventory: Inventory; be it in the form of Raw Materials, Work-In-Progress (WIP), or Finished Goods, represents a capital outlay that has not yet produced an income either by the producer or for the consumer.
- Motion: As compared to Transportation, Motion refers to the producer or worker or equipment.
- Overprocessing: Using a more expensive or otherwise valuable resource than is needed for the task or adding features that are designed in but unneeded by the customer.
In "Lean Software Development: An Agile Toolkit", Tom and Mary discuss The Seven Wastes and offer a great set of parallels in software development. Rather than copy & paste what they've already said, I wanted to offer my own interpretation of these wastes - some of which are the same as Tom and Mary's. Defects This is exactly what it sounds like - a bug, a piece of functionality that doesn't work right, or an exception that gets thrown in the system and causes problems. How many hours, days and weeks have you spent fixing defects in software, in your career? Personally, I can't even begin to accumulate the time spent - it's far too great. Part of the problem here, and what really makes it wasteful, is when defects are found and fixed in most software development cycles. In Code Complete 2, McConnell talks about the cost of defects in software, relative to when the defect is found and corrected (pages 472 & 473). If the cost of fixing a defect goes up over time, then the amount of waste also goes up. In other words, the higher the cost of fixing a defect, the more waste that defect has generated. With the increasing cost of defects in mind, we will want to reduce the time to find a defect so that the amount of waste generated can be mitigated. In Lean Manufacturing, this is achieved by only creating what is needed for an actual customer order, right now. If one part is produced with a defect, that one part is scrapped and a new part is created, correcting the defect - the waste is minimal. Imagine a mass-production system where parts are created in batches of ten thousand. What happens if there is a defect caused by the process? We end up with a significant amount of waste, because we will have to scrap the defective parts in batches of ten thousand - the waste here, is significant. The same principle holds true in software development. If we are writing code for extensive periods of time, and that code is not being tested until the end of that period, then the cost of finding a defect in that code goes up. If we have ten lines of code that rely on the defect working the way it does, it is significantly cheaper to fix than if we have ten thousand lines of code relying on the way the defect works. The easiest way of reducing the number of lines that rely on a defect is by working in small iterations. If that defect goes into test after two weeks, it will be much cheaper to fix than if it had gone in to test after two months. Additionally, if automated tests are done and can be run against the system on an even shorter schedule, then the cost of finding the defect may be even less. If the automated tests are run every twenty or thirty minutes, you may only have two or three lines of code that are affected by the defect. Overproduction There are several common terms for overproduction, in software development - Over-Engineering and Coding For The Future, for example. Both of these problems result in the same thing - too many features and more functionality than is actually needed right now. Additionally, overproduction can be called technical debt. The idea is that there is code in our system that will need change - when this code needs to be changed, how difficult is it to change; what is the cost of the change (how much debt are we in). If a developer is tasked with creating Feature-X, they should focus on the core business value of that feature when writing the code. It's very easy for that developer to think about "what-if" scenarios and "we may need to" future functionality. However, this type of thinking leads directly to overproduction. If the business has not identified the "what-if" scenario, then why should the developer assume that handling the scenario would add business value? If the business has not yet identified Feature-Y or specified any additional functionality in Feature-X, then why should the developer assume that coding for the possibility of Feature-Y is valuable? Take note of the pattern in those questions - assumption. Assumption on the developer's part leads directly to the overproduction of the system being built. So how do we prevent this overproduction? First and foremost - stop assuming you know what's coming down the line, or what will provide business value. If you believe that the specs you are currently working with are not accounting for an actual problem, then the responsible action is to discuss that issue with the customer / business analysts. Secondly, if you find yourself wanting to code for the feature that may be coming down the line - stop. Don't do it. Even if you know that this feature or functionality is coming down the line, it may not provide any business value for the current feature(s). You may be causing detriments to the business value of what is currently being built. If you truly believe that the feature you want to code is required for the feature that you are coding, then you need to go back to the customer / business analyst again, and discuss it with them. Let the customer tell you whether or not there is value in adding that feature now vs. later (vs. if at all). Transportation Think of transportation in the context of knowledge. No one knows everything about a particular domain or project, and possibly an individual feature. We have business analysts and customers precisely because of this. Eric Evans discusses knowledge crunching (the process of learning and gaining an understand of the domain in question, to create a model) in Domain Driven Design, in the first chapter. Tom and Mary talk about the process of learning all throughout the "Amplify Learning" chapter of Lean Software Development. There are countless other books on requirements gathering, model creation and other learning processes for software development, as well. The problem that we face in our learning is that the transportation of knowledge, from one person to another, will always introduce change. Every person in existence has their own unique way of understanding, based on their experience, existing knowledge and methods of knowledge retention. To illustrate this, look back at your childhood. Did you ever play the "telephone" game where one person whispers in the ear of the person next to them, then they whisper the same thing into the ear of the person next to them, and so-on until the last person in line? What are the typical results of this game? More often than not, the message had some fundamental change to it throughout the transmissions. As simple as the telephone game is, it's a perfect illustration for knowledge transportation that occurs in software development projects. How many times have your received a functional specification or requirement for a feature, and had no clue what it was trying to convey or what the functionality was supposed to be? This happens on a very regular basis. The problem may not be that the documentation is inadequate, but that the transportation of knowledge from one person's mind onto the paper and into your mind is inadequate - what makes sense to the document writer(s) may not make sense to you, because your contextual knowledge of the subject is different. This problem is exacerbated by design-up-front project methods. The knowledge is often crunched from the customer's mind into the BA's mind, and then trampled down into a linear document or subset of knowledge in a documentation set where the developer has no direct access to the customer - the source of knowledge - for clarification and discernment of the details. Even if the customer is on-site sitting next to the developer throughout the creation of the documentation, there is still a transportation problem in design up front projects. Whether or not the developer understands the information during the conversations, there is little chance that the developer will remember every detail of the information when they finally get down to coding. The solution for the transportation of knowledge is ensure that the knowledge is transported as little as possible. Rather than focusing the effort of documentation on every last possible detail - creating tomes of documentation that no one is really willing to read - we should focus on creating higher level guidance; enough knowledge to know the direction of the development effort and the features to be created, with the understanding that the final details will come from the customer just-in-time for the development effort. In the world of lean manufacturing, this is typically done through the Kanban system. In software development, we have adopted the same process through the use of User Stories being written on index cards. The stories are not the final word in the development effort - they are merely a placeholder for a conversation between the customer and the developer. Waiting This is likely the most obvious of the seven wastes, when applied to software development. Whether you are waiting for a customer or business analyst to be available for questions; waiting for a requirements document to be signed off; or waiting for your next assignment of work, the simple process of waiting creates lost time which directly translates to lost opportunity. In the extreme cases, the problem is compounded by context switching. If you are waiting for a question to be answered - whether this means waiting for a phone call, a document to be written, or just walking down the hallway - you can easily lose your focus or lose you place in the code or coding process. When this happens, most people take a while to restore that focus and get back into the mind set where the new knowledge is useful. In my experience (no real data, just my experience), the average time of context switching within the same project is as little as five to ten minutes for wind down, and at least ten or fifteen minutes for spin-up. If you are context switching between multiple projects, though, expect to spend much longer on the spin-up; hours, even days, depending on the project and time between wind down and spin-up. If we can ensure that we never wait longer than it takes for us to wind down, then we should be able to eliminate the spin-up period; thus reducing the effort required for reestablishing our focus on the feature(s) at hand. However, the solution for waiting may not be as obvious as the problem. If you are waiting for documentation, or if you are waiting for the customer to sign off on a feature or change, the way to eliminate the waiting is to eliminate the cause. Don't rely on heavy documentation or require customer sign-off on features. If we are working with the customer every hour of every day, eliminating the knowledge transportation issues, then we can also eliminate much of the waiting game by having the customer available. When the customer is available immediately, we have a much greater chance of the conversation beginning within the wind down period. When this occurs, we can stay focused on the problem at hand, and mitigate the spin-up period when we return to the code. Inventory Inventory in a manufacturing or supply context is typically a product or component of a product that is in storage and waiting to be used; or "a list of goods and materials held available in stock by a business" (Wikipedia). In software development, we only need to translate "good and materials" into "code and resources": A list of code and resources held available in stock by a business. Think of software inventory as unfinished code (as defined in Lean Software Development) or as overproduction of code. If we have unfinished code in our system, this is like having a physical component for a product - the component by itself is not useful until it is in the completed product. Similarly, the unfinished code provides no value to the software until it is finished. Even if the code is complete, if it is not being used in the software then it is dead code and is inventory for the software. Inventory, in software development, carries a significant technical debt - the unknown factor of whether or not the code actually needs to be in the system. The longer we let inventory live in our code, the more likely we are to forget whether or not that code needs to be there. This inventory also becomes a potential mine field for developers - what happens if a developer sees this dead code and assumes that it is still functional and valid? If we are lucky, the code will work as advertised. The longer the code sits in inventory, though, the more likely it is to be outdated, invalid and eventually non-functioning. Motion In addition to physical movement causing waste through waiting (walking down the hall to the BA's office), motion can also be applied to the processes of producing the executable software (not the source code and other resources). How much effort does it take for your team to compile the resources, create the executables, package it into an installation and deliver it to QA, the customer, etc? The goal should be to make this as simple as possible - as little movement as possible. Are you able to click a button and have the build, package, and delivery processes handled for you automatically? Or does it take a team of developers, build engineers and other persons with a manual process and a checklist of things to do? If your process involves people performing manual tasks - even if that task is simply the order in which multiple buttons get clicked - then you are at risk of creating waste through defects. Every manual motion in your build process is another point at which mistakes can be made, allowing defects to be built or causing the build to fail completely. Software production (again - speaking about production of executable software, not development of resources or code) is often a difficult, tedious chore, requiring many moving parts - there is no way around this. However, it does not have to be a manual process. Continuous Integration and Continuous Deployment practices are abundant in the world of software development, specifically to address this issue. If you can automate your build process and eliminate the manual movement involved, you can eliminate a huge source of potential waste. Overprocessing Overprocessing, or too much process, is abundant in software development. When a customer has a request for a feature, how much process does it take for that feature to become functionality? In design-up-front project life cycles, the process of adding or changing a feature can be very time consuming, involving many steps on both the requester and implementer side: request; acknowledgement and change management / approval; design and documentation by implementation staff (BA's, developers, etc); sign off of design and documentation by customer; implementation in software; scheduled for testing; tested; and if any issues are found, back to design or implementation for corrections, repeating several steps. Additionally, how much work does it take for you to get your job done, as a developer? Do you spend as much time updating task / issue management tickets and managing your manager, as you do coding? Too much process in software development is as bad, if not worse, than no process at all. Unfortunately, the failures of too much process are often seen as an indication of the need for more process, causing further delays and waste in the system. There are often situations where you cannot do anything about the process that is in place. Life-Critical systems (x-ray machines, air plane guidance systems, etc) are abundant with process for good reason - if anything fails, people could be injured or killed. In the world of business software, though, this is not usually the case. Most business has a level of fault tolerance built into it, and some waste is expected / accepted. This is not a get out of jail free card, though. The more significant the waste, the more repercussions there are - fix the defect; pay for lost revenue; lose your job; etc. If we want to eliminate waste through the simplification of process, then we need to ensure that defects are found and fixed as early as possible, to avoid creating waste for the business using the software. Process simplification can be done many different ways. Start with the creation of a process flow char, or value-stream chart. Find out how much time and effort is wasted in your processes and look for the waste that can be easily eliminated. Simplifying a single process by removal of waste can lead to a revolution in your process. You may find that the removal of one process negates the need for another process. You may also find that a simple change to one process does the same. If you are able to bring your customer into the work area with your team, and work in short iterations where defects are found and fixed quickly, you will likely see many of your old processes quickly become obsolete. Conclusions No one wants waste in their systems. Waste is money lost and revenue not earned. Waste management, though, can be a difficult proposition. Many company are willing to accept waste as the cost of doing business and are not willing to spend money eliminating waste because they do not see the waste or do not believe it can be eliminated. If we are truly going to revolutionize the business we work in, we must eliminate waste. Start where you have direct control or influence. You'll quickly find others wanting to know how you are so productive and soon the entire business will be in full waste reduction cycles.
I've been hearing this a lot lately, and finally started reading up on the roots of the Agile movement. It all goes back to Lean Manufacturing. Oddly enough, I've had exposure to Lean Manufacturing at a previous job. So the concepts and names are all very familiar to me. Back in those days, I had heard of the concept of Lean Software Development, but it never really made any impact on how I wrote software. These days, though, I'm diving into as much Agile as possible and the further down the road that I travel, the more and more parallels I see, to the lean manufacturing world. If you are at all interested in the roots of agile, here's some recommend reading (mostly Wikipedia) to get you started. Wikipedia: Books: I'm hoping to absorb more of this information, quickly. It seems the more I learn about lean manufacturing, the more I understand about software development. I certainly don't claim to be an expert on either subject... hopefully I can change that.
Way back in the day (somewhere around 1994 or 1995, I think), I saw the movie, "Search for Bobby Fischer". One of the lines that has always stuck in my head is from the teacher, Vinnie: He didn't teach you how to win, he taught you how not to lose. At the time, I didn't like this line - I didn't understand why playing "not to lose" was different than playing to win. Over the years, I've seen variations of this statement and had a little more understanding of what it actually means. Last night, though, I was involved in various philosophy-of-software discussions with a friend and this quote popped up in my mind again, in the context of project failure and the fear of failure. I think I finally understand what this quote is saying, now - and it all comes down to the fear of failure vs. embracing failure as an opportunity to learn and find new ways to succeed. Knowing Success Through Failure Looking back at my life, I have two very distinct memories of catastrophic failure - the kind of failure where I was so emotionally invested in the project or goal, that the failure was truly devastating to the point where I would have a complete breakdown and be entirely lost for a while. The first of these memories was back in College. I have an associates degree (AA) in music, from a junior college back in my hometown in Kansas. After graduating with that degree, I found another school in Denver that had a sound recording / engineering track in their music school and I signed up for it with all the passion and motivation that I now have for software development. When I moved on to campus at that school and started figuring out what classes I would be taking, etc., I found out that I had slipped through the cracks in the school of music. As it turns out, I was supposed to have interviewed for the school of music and done some performance in front of various professors, to be accepted. With that in mind, I worked with the director of the program and did my performances - and completely failed. As it turns out, I had a general skill with musical instruments and could play just about anything at a very mediocre level, but I was not terribly good at any instrument. The end is result is that I was told (in very kind, helpful terms) that I would need a few years of lessons before I could be accepted into the school of music. Needless to say, this was a very devastating experience for me. My goal and my dream, at the time, was to be a musician and work in a recording studio. Shortly after the realization that my goal was unattainable, I had various talks with various people close to me and some talks with the director of the music school. We quickly realized that I could still attain the primary goal in my dream - to work in a sound recording studio and be in the sound recording / engineering program at the school - but my specified major would not be music. I ended up in the Management Information System department, with that being my major, while still taking the sound recording / engineering classes. The second of these memories is significantly less important in the grand scheme of my life. A few years ago, I was attempting to install a new car stereo system in my car. I had done stereo and speaker installation before, but had never done an amp and subwoofer. Over a 4 day weekend, I ended up with a car that had no working speakers, a blown amp, and a subwoofer with holes punched in it. At the time, this was another very devastating outcome for me - I had a very specific goal in mind and had spent a significant amount of time and money on the project, with no usable results. Two days later, I had my car in a professional car audio shop with professional audio installation personnel fixing the problems and installing a new amp and subwoofer. The end result was that I had a great system in my car. Looking back at both of these experiences, I see a pattern: a project or goal, a significant personal investment, a catastrophic failure and finally, an outcome that still satisfied my criteria for success. There's an old cliche line that I've heard many times: You can't know true success unless you know true failure. I believe I've been as close to true failure as I can get, without giving up on a project or goal. True failure, though, can only come from giving up. Playing To Win vs. Playing Not To Lose My career as a software developer has been very interesting, so far. I've had a lot of great success and a few fairly large failures. What's really interesting to me, though, is looking back at those failures and seeing the risk that I was willing take. I've jumped into some very difficult, new, demanding situations with little or no knowledge and experience in those situations. Many times, I was able to find the experience quickly and succeed, but some times I was not able to find the experience quickly enough and I failed. These successes and failures are why I believe I understand the issue of playing to win vs. playing not to lose, now. As I said before, it all comes down to the fear of failure vs. embracing failure as an opportunity to learn and find new ways to succeed. With this in mind, I have some questions that may help you understand playing to win vs. playing not to lose. Are you willing to take risks in your project? Are you willing to put forth the effort involved in trying to create what could be a better you, or a better project, knowing that you could fail if you try? Are you willing to open yourself for failure so that you can learn, and have a greater chance of greater success? Are you playing to win? Or are you only willing to do the work that you are comfortable with now, and only willing to learn a little bit of something new, keeping a safety net around yourself? Are you willing to keep yourself from taking risk so that you don't have any significant chance of failure, and no significant growth? Are you afraid of change or afraid that you will fail? Are you playing not to lose? Good Judgement and Experience Another tired old cliche that I've heard a thousand times: Good judgement comes from experience. Experience comes from bad judgement. I make a dozen bad decisions every day. I also make a dozen good decisions every day, because I am willing to honestly look at the decisions I've made and admit that they were bad decisions. By allowing myself to understand that these decisions were bad decisions, and admitting that to not only myself, but to my managers and team members as well, I set myself up for success. I'm able to look at these decisions, understand why there wrong, and correct the mistakes. And by doing this on a daily basis, if not more often, I can mitigate the failure that any one decision may cause. Embracing Failure Without Fearing It One of the reasons I am so in love with Test Driven Development and Behavior Driven Development is that it accelerates the failure-to-success process. I'm not unit testing to prove that I have not failed. I'm unit testing to prove that I have succeeded and created the API that I want. I expect failure when I unit test. I expect to write horrible APIs that are unusable, ugly, stupid, and obnoxious. I WANT to realize that I am doing this, through my unit tests, because I can accelerate the process of realization and correction by using my unit tests as a design tool. And I challenge you to do the same - to stop fearing failure and not be afraid to make mistakes. If you believe you have made a mistake, expose it for peer review. Ask for others to validate or invalidate that mistake and learn from the experience. Find the tools, techniques, coworkers and peers that will help you accelerate the realization of failure so that you can correct the failure and succeed, faster. A Personal Rant: My Success As A Developer I believe I am a very successful software developer and leader. I have a lot of experience under my belt and a lot of knowledge that I want to share with others. So, why am I successful? Why was I responsible for the public face of a 300 million dollar multi-national corporation, through it's web sites, when I was 22 years old? Why was I made the lead developer in a team of 10, when I was the new guy in the office? Why am I now diving into the cutting edge of Behavior Driven Development and actively involved in the Agile community? Why am I making a name for myself not only in my office, but also in the development world outside of my office? Because I take risk and embrace my failures. I openly admit my failures at the first possible moment, so that I can learn. I actively seek the voice of dissent and the views that I don't agree with, so that I can be proven to be wrong and learn how to be right. Why am I successful? Because I play to win.
A few people have asked what my blog setup is, in respect to screen shots and code samples, so here's the answer for all to see. Blog system: dasBlog I love the simplicity of dasBlog. No extra fluff, no massive database or configuration system. It's just a blog with the features that I want, and it stores all of it's settings and content in XML files.  Be sure to change the web config so that the trust level is "full" and not "medium". Otherwise the blog posting API won't allow you to upload images and other attachments. Web Host: WebHost4Life A good .NET hosting company. I have the $10/month account type. There are plenty of other (and probably better) .NET hosting companies out there. Screen Shots: a custom app I wrote 4 years ago, called ScRap.NET It's easy to use. just hit the "PrtScn" (print screen) button on your keyboard, then click-n-drag with your mouse. The gray box that draws on your screen is where the screen shot will come from. There are professional options for this, though - such as SnagIt. The reality of it is that it doesn't matter what you use to create the screen shots. The reason mine look like they do is because of my post authoring tool. Post Authoring Tool: Windows Live Writer An off-line blog editing tool (which I am using to write this post). It supports most of the blogs out there - the major ones anyways; and has lots of nice little features to make post writing simple. It has it's limitations (not all HTML is supported or easy to do) but if you can live with the formatting limitations, it produces some high quality work in an offline, "draft"-able manner. It supports screen shots, file attachments and some other cool stuff. Check out the plugins for it, to add a lot more fun stuff. Code Format Tool: Code Snippet Plugin All the beauty of my code examples come from this plugin. Just paste some text into the plugin and set your formatting options. And that's it... a pretty simple setup that does exactly what I want in my blog.
As a kid, I was never part of the boy-scouts or anything; but my family and I went camping a lot, and I went camping with my youth group on several occasions. I remember hearing my parents and the various youth leaders talking about we should always leave the camp site cleaner than we found it. I always thought this was annoying - why should I clean up someone else's mess? If I clean up my own mess, isn't that good enough? Yesterday, while helping a coworker fix some bugs in an application that I wrote around a year ago, I was suggesting ways to improve various parts of the code; move this property to a parameter of that method, make this method private and only call it from here in the owning class, and items as simple as making an if-then statement easier to read. After a few of these suggestions, he asked me if I always clean up the code that I'm working with, even if the bug is not directly related to the code that we are cleaning up. My answer was emphatically, "yes". If I'm reading code, trying to find a bug and I'm having a hard time understand what's going on with the code, then it becomes much more difficult to find the actual bug. Even if this code does not end up being part of the bug I was looking for, by cleaning up the code I am making it more likely that I will be able to understand what this code is doing the next time I have to look at it. Here's my basic perspective that drives all of this: if you have a hard time reading the code and seeing what it is doing, chances are, you or someone you know will have to debug that code at some point. I don't want to debug hard to read code - that's annoying, at best. I want to debug code that is easy to read and easy to understand. And I certainly don't want to make any of my coworkers debug hard to read code. I try not to torture coworkers like that. So, if my motivation is to not debug hard to read code, then doesn't it make sense that I would want to clean up that ugly code? It makes sense to me... What does this really come down to, then? Two things: - Leave the code cleaner than when you arrived, by
- Micro-refactoring - make that one line of code easier to read
(By the way - there's no such thing as "micro-refactoring". Refactoring, by definition, is exactly what I described above. Stop trying to change the architecture and learn to change that one line of ugly code. By doing this, you'll find that the architecture does change, because you clean up more than you realize and change become natural.)
Have you ever: - had a problem that you were having a hard time solving?
- been in need of a design idea for a particular situation, and you don't know where to start?
- solved a problem that was nagging you for a while?
- come up with a good design for a common situation?
- written some code that you wanted to keep around, to remind yourself how you did something?
- wanted to find some code examples on how to do something with a specific technology?
- wanted to know how to do something for a specific project?
- wanted to share your knowledge on how to use a specific technology a specific way?
- wanted to learn how to use a specific feature of a project?
- wanted the world to know your opinion of a piece of software or technology, be it good or bad?
If you can answer "yes" to any one of these questions - you should be blogging. If you can answer "yes" to more than one of these questions and you are not blogging, then shame on you! Start blogging today! Don't think your opinion matters, or that you have anything worth saying? Stop fooling yourself. If you write code, you have opinions and preferences. If you have opinions and preferences, they are worth sharing. It's not possible to write code without opinions. Software development is not a mechanical process like building a house or a car - you can't sick a robot on a keyboard and write a functional piece of software. The worst case scenario: If you post code examples on issues that you have solved, you will have a history of code you have written and issues you have solved. You'll be able to go back to this history and re-use existing knowledge, rather than having to think through the problem again. The best case scenario: If you post your code examples, your thoughts on software development, your opinions and preferences; chances are that someone else in this wide world of ours has the same opinion or has had the same issues and will find the information you provide useful. Why should you blog? Because you're a person with ideas worth listening to. ... Get started now. Register a domain name and buy some web hosting so you can have a blog that is accessible to the world. I use dasBlog and WebHost4Life. There are thousands of options out there - find the one that works for you.
|