Tuesday, October 31, 2006

Another RSS Reader

Attensa has a free RSS Reader plugin for Outlook. There are some good and bad things about this tool. First, this is an awesome plugin for free. It does everything that I would want any RSS Feeder that plugs into outlook to do. Attensa is integrated very well into Outlook. When new posts arrive the information window pops up and lets you know, just like emails, and even MSN Messenger do. Most I like that intranet RSS feeds show up nicely in it. These feeds I only want to check when I'm at my work computer, at work.

I do have a few complaints. Personally, I would like an RSS feeder that integrates into outlook to make reading my feeds easy while I'm at work and that keeps in sync with a web version that let's me check on feeds from home. I really like how Google Reader is working for me right now. I am tagging and saving more posts than I had ever saved before. While using my previous RSS Readers, I would just read things and learn the new information, but I wouldn't save it for reference.

Generally my thinking is I read a ton of posts because if I know about something, then when a situation arises that I will need something like that, I'll remember having read it and can find it more easily. Otherwise, I fear that I'll spend too much time re-inventing the wheel to solve problems that someone else has solved, usually better than me.

Anyway, I really like Attensa for one reason. It integrates to outlook and can see my intranet RSS feeds. Currently there aren't a lot of these, but over the next year I expect the list of these to start growing. And I dont' want my intranet feeds on a reader that can't get to them, so Attensa is very nice to fill in this gap for me.

Monday, October 30, 2006

A beautiful thing.

There's a simple beauty to a pencil, especially mechanical pencils. Here's of why I love the pencil.
  1. I always know if it's about to run out on me.
  2. A pencil does not skip on paper over a spot that may have been touched by your finger.
  3. A pencil will write on an angle unlike a pen.
  4. I always know what color a pencil will write.
  5. I can buy lead refills and use the same pencil for years, which I have done. I even wrote the draft for this in a pencil that I've had for 3 years.
Ok, so it's geeky, but I love to write in pencil. Since I think everything should be stored electonically anyway, there's no point in having something writen in ink, so I can keep the paper forever. I don't want to keep paper forever, paper is temporary.

Friday, October 27, 2006

But they aren't agile.

Agile is sweeping the developing world. But it is not going without it's growing pains. I've not heard of anyplace that was able to switch to an agile process smoothly. We started switching almost a year ago, and we are still going through growing pains. However, Agile is designed to continually improve the process as well. The people who came up with agile just came up with a manifesto. What it means, is that there is no single way to be agile. Whatever works for you that fits with the idea in the manifesto, is agile. There are many processes that have become fairly common with agile, but none of them have to be used, because the Agile process stresses people not processes. Personally, many of my earliest complaints about agile were more that our Agile process is not Extreme Programming. Extreme programming is often viewed as Agile, and it's philosophies are very much the same, but it does stress certain processes. Anyway, the point I'm making is that Agile is an idea, not a process.

Recently, I heard a co-worker complaining that she needed help from another department by saying, "But they aren't on agile, I can't get them to do things as fast as we want." This caught me off guard. I fully support Agile. And being agile also means being flexible and communicating a lot. This incident felt a lot more like someone complaining about another group not dropping everything and jumping into action at the last minute. It's something that the complainer also would not have done if the situation was reversed, even though she's "agile". If you know that you will need help from someone, don't wait until the last minute to ask him for help. As soon as you have something that you know will need help, send an email with a heads up, "Hey in 5-10 days I have this thing that I'm going to need your help with". Then as you get closer and have a better defined list of what will need to be done send another email. "Hey in 3-5 days I need this thing done, it includes, X, Y, and Z. Please let me know if you will be able to get that done and when, so I can let my boss know." For a total of 3 sentences you no longer have a last minute issue. The person you need help from knows that something was coming and can make sure that their workload has some room for it. If they won't have room for it, they are able to tell you immediately. Finally, just because something is your number 1 priority, it doesn't mean that it's the other person's number 1 priority. Use this early and often communication both with the person you need help with and your boss/client to let them know what's going on and what issues may occur. And finally remain flexible. If the person who's helping you is not available, then let it push back. It's always better to get it right than to have to do it twice.

Getting Things Done

It appears that I'm a Johny-come-lately to this whole Getting things done following. Over the past month or two I have had glimpses of different things with GTD popping up. Then a conversation with a friend of mine who has read the book and believes wholly in the system prompted me to find out more information.

If you haven't heard, in short, GTD is a system to organize your entire life to help you accomplish more things. I've started reading the book, and it's a good book so far (not yet 1/4 the way through it), the only problem that I have is that I keep having things that my mind thinks of that I need to do. It's almost as if reading a book about being organized has gotten my mind thinking of all sorts of tasks that have been buried in it for a long time. The good thing is that GTD says you need to get these all out of your head and into a system to organize them. I've been making sure I write them all down and I've been using the Tiddly Wiki, which I blogged about previously, to keep my notes in. Just this week I have also seen that there is an enhanced version of the Tiddly Wiki that is organized around GTD, and today I read that there is a Firefox plugin that can be used to help organize your GMail to work better with GTD. If you are a tech person and haven't heard about it before now, then you will, it will be gaining popularity.

If you are even more interested, here is a good posted about getting started with GTD.

Thursday, October 26, 2006

VB6 Example

Private Sub SetFormCaption(ByVal strcaption As String)
'**********************************************************************************************************
' PURPOSE:
' Sets the Child Form's caption property when this control is loaded.
'**********************************************************************************************************
On Error Resume Next

UserControl.Parent.Caption = strcaption

End Sub


I am working on an application currently, and one of the functions is the function above. With my great and wonderful refactoring skills I have been able to cut out 6 lines from this function. Please see the wonderfully updated version below.

Private Sub SetFormCaption(ByVal strcaption As String)
On Error Resume Next
UserControl.Parent.Caption = strcaption
End Sub

Monday, October 23, 2006

Something not to do in C# Part 2 My Code

Here is my C# code for this. I am no longer writing that the file opened in 0 minutes, and I am using built in tracing functionality. I am also loading more information from the config file than the application was previously. there is even more that could be moved, but I have let myself live with a few things.

using System;
using System.Xml;
using System.IO;
using System.Collections;
using System.Diagnostics;
using System.Data;

namespace AfniRemovalArchive
{
class Removal
{

private const string ConfigFile = "Archive.xml";
private TraceSwitch deleteTrace = new TraceSwitch("deleteTrace", "Trace deleted file information");

[STAThread]
static void Main(string[] args)
{
Removal rmv = new Removal();
try
{
ArrayList localDepartments = rmv.GetConfigurationSettings();
rmv.CheckDepartments(localDepartments);
}
catch(Exception ex)
{
Trace.WriteLine( ex.ToString() );
}
}



private ArrayList GetConfigurationSettings()
{
ArrayList localDepartments;
Trace.WriteLine("Get configuration settings Begin: " + DateTime.Now.ToString());
string configpath = Path.Combine(Path.GetDirectoryName(this.GetType().Assembly.Location.ToString()), ConfigFile);
DataSet configds = new DataSet("config");
try
{
configds.ReadXml(configpath);
}
catch(System.Exception ex)
{
Trace.WriteLine("Get configuration settings: " + ex.ToString());
throw new Exception("Error reading configuration information", ex);
}
Trace.WriteLine("Configuration file loaded from: " + configpath );
localDepartments = new ArrayList();
// Create a list of Department configuration objects.
foreach(DataRow currentRow in configds.Tables["localdepartment"].Rows)
{
Department currentDepartment = CreateDepartment(currentRow);
localDepartments.Add(currentDepartment);
}
Trace.WriteLine( "Get configuration settings End: " + System.DateTime.Now.ToString() );
return localDepartments;
}
private Department CreateDepartment(DataRow currentDepartmentRow)
{
Department currentDepartment = new Department();
currentDepartment.departmentName = currentDepartmentRow["ldepartment"].ToString();
currentDepartment.localLocation = currentDepartmentRow["locallocation"].ToString();
currentDepartment.numberOfDays = Int32.Parse(currentDepartmentRow["numberofdays"].ToString());
return currentDepartment;
}
private void CheckDepartments(ArrayList localDepartments)
{
try
{
foreach(Department currentDepartment in localDepartments)
{
Trace.WriteLine("RemoveArchive for department " + currentDepartment.departmentName);
RemoveArchive(currentDepartment);
}
}
catch( Exception ex )
{
// something bad happened, log it, there is no recovery until we can see these errors.
Trace.WriteLine( "Error in CheckDepartments\n" + ex.ToString() );
}
}



private void RemoveArchive(Department currentLocalDepartment)
{
string[] archiveDirecotries = Directory.GetDirectories(currentLocalDepartment.localLocation);

DateTime cutOffDate = new DateTime(DateTime.Today.Ticks);
cutOffDate = cutOffDate.AddDays(-currentLocalDepartment.numberOfDays);
Trace.WriteLine("CutOffDate is " + cutOffDate);
int batchCount = 0;
for( int barcodeDir = 0; barcodeDir < archiveDirecotries.Length; barcodeDir++ )
{
string[] dirLocalBatch = Directory.GetDirectories(archiveDirecotries[barcodeDir], "*.ARCHIVE");
for( int batchDir = 0; batchDir<dirLocalBatch.Length; batchDir++ )
{
// check to see if i need to delete this directory.
DateTime createTime = Directory.GetCreationTime(dirLocalBatch[batchDir]);
if( createTime < cutOffDate )
{
Trace.WriteLineIf(deleteTrace.TraceError, "Deleting batch " + dirLocalBatch[batchDir] + " created at " + createTime );
Directory.Delete(dirLocalBatch[batchDir], true);
batchCount++;
}
else
{
Trace.WriteLineIf(deleteTrace.TraceVerbose, "Keeping batch " + dirLocalBatch[batchDir] + " created " + createTime );
}
}
}
Trace.WriteLine("Deleted " + batchCount + " batches.");
}

}

}

I'll also include my App.exe.config information. I leave a standard comment in my config files to make it easier for others to maintain later. I like to use Autoflush = true on the logging, this forces every write to actually write to the file. If you don't do this, you have to be particularly careful in your code to flush before ending due to an error, or you could lose the valuable tracing information that you need. I've never been comfortable with that, and always choose to set autoflush to true.
<?xml version="1.0" encoding="utf-8" ?>
<configuration>

<system.diagnostics>

<!-- Note that all listeners are used all of the time. When logging
at an information level you may want to turn off email, or you will get overwhelmed. -->
<switches>
<!-- value = 0 = Logging off. -->
<!-- value = 1 = Log Errors. -->
<!-- value = 2 = Log Errors and Warnings. -->

<!-- value = 3 = Log Errors and Warnings and Information. -->
<!-- value = 4 = Log Errors and Warnings and Information and Verbose. -->
<!-- value > 4 is assumed to be 4. value < 0 is assumed to be 0 -->
<add name="deleteTrace" value="1" />
</switches>

<trace autoflush="true" indentsize="0">
<listeners>
<add name="TextListener" type="System.Diagnostics.TextWriterTraceListener" initializeData="\archiveTracing.txt" />
</listeners>
</trace>

</system.diagnostics>


</configuration>

Something not to do in C# Part 2 Bad Code

After I posted the other day, I got into looking at the rest of that class. The entire applicaiton was a single class, but there were things all over that were just annoying to me. Rather than rant too much about the code, I'll let it stand on it's own merits.

I will however point out a few of the things I found the most annoying.
1. The WriteTraceLine function writes elapsed time. The way that is called everywhere writes the number of minutes that it takes t oopen the tracing file. Even a slow process takes less than a minute so this writes a zero on every line.
2. DateTime.Now is passed in to WriteTraceLine everywhere, but not before being assigned to another variable the line before it.
3. Although this code reads a config file, the location of the trace file is hard coded. This is a problem when the application is deployed to a server and runs on the C drive, while the log should be written to the larger partition of the D drive.
4. CheckDepartments has a catch and finally that do nothing.

using System;
using System.Xml;
using System.IO;
using System.Collections;

namespace AfniRemovalArchive
{

class Removal
{
Department currentLocalDepartment;
string tracing;
ArrayList localDepartments;
StreamWriter traceFile;

[STAThread]
static void Main(string[] args)
{
Removal rmv = new Removal();
rmv.GetXmlSettings();
rmv.CheckDepartments();
}

private void GetXmlSettings()
{
DateTime begintime = DateTime.Now;
WriteTraceLine("Get xml settings Begin: ", begintime);

string path;
XmlDocument doc;
XmlNode root;

//the path of the MailWatcher xml will be the location
//of the service EXE itself.
path = Path.GetDirectoryName(this.GetType().Assembly.Location.ToString());
path += @"\Archive.xml";
doc = new XmlDocument();

try
{
doc.Load(path);
}
catch(System.Exception ex)
{
begintime = DateTime.Now;
WriteTraceLine("Get xml settings: " + ex.ToString(), begintime);
}
begintime = DateTime.Now;
WriteTraceLine("Get xml settings path: " + path, begintime);

root = doc.SelectSingleNode("/Archive/localdepartments");
localDepartments = new ArrayList();
Department departmentObject;


foreach(XmlNode department in root.ChildNodes)
{
departmentObject = new Department();
foreach(XmlNode depart in department.ChildNodes)
{
if(depart.Name == "ldepartment")
{
departmentObject.departmentName = depart.InnerText;
}

if(depart.Name == "locallocation")
{
departmentObject.localLocation = depart.InnerText;
}
}
localDepartments.Add(departmentObject);

}


try
{
root = doc.SelectSingleNode("/Archive");
}
catch(Exception ex)
{
begintime = DateTime.Now;
WriteTraceLine("Get xml settings: " + ex.ToString(), begintime);
}
tracing = root.Attributes["Tracing"].Value;

begintime = DateTime.Now;
WriteTraceLine("Get xml settings End: ", begintime);

}

private void WriteTraceLine(string txt, DateTime btime)
{
if(tracing == "On")
{

try
{
traceFile = new StreamWriter(@"c:\archiveTracing.txt", true);
}
catch
{
traceFile = new StreamWriter(@"c:\archiveTracing1.txt", true);
}
DateTime endtime = DateTime.Now;
TimeSpan elaspedtime = endtime - btime;
traceFile.WriteLine(txt + elaspedtime.Minutes.ToString() + " seconds: " + elaspedtime.Seconds.ToString() + " Date: " + DateTime.Now.ToString());
traceFile.Close();
}
else
{
if(traceFile != null)
{
traceFile.Close();
}
}
}



private void CheckDepartments()
{
try
{
foreach(Department department in localDepartments)
{
currentLocalDepartment = department;
RemoveArchive();
}
}
catch
{
}
finally
{
}

}


private void RemoveArchive()
{

string localPath = currentLocalDepartment.localLocation;

DirectoryInfo objLocalDirectory = new DirectoryInfo(localPath);
DirectoryInfo[] objLocalDirectories = objLocalDirectory.GetDirectories();

for(int a=0; a < objLocalDirectories.Length; a++)
{
DirectoryInfo[] objLocalBatches = objLocalDirectories[a].GetDirectories("*.ARCHIVE");
for(int l=0; l < objLocalBatches.Length; l++)
{
Directory.Delete(objLocalBatches[l].FullName,true);
}
}
}
}
}

Thursday, October 19, 2006

Something not to do in C#

private void WriteTraceLine(string txt, DateTime btime)
{
if(tracing == "On")
{
try
{
traceFile = new StreamWriter(@"c:\archiveTracing.txt", true);
}
catch
{
traceFile = new StreamWriter(@"c:\archiveTracing1.txt", true);
}
DateTime endtime = DateTime.Now;
TimeSpan elaspedtime = endtime - btime;
traceFile.WriteLine(txt + elaspedtime.Minutes.ToString() + " seconds: " + elaspedtime.Seconds.ToString() + " Date: " + DateTime.Now.ToString());
traceFile.Close();
}
else
{
if(traceFile != null)
{
traceFile.Close();
}
}
}


Don't do the same thing in a catch that you do in the try. The chances that it works the second time are slim. Besides, if there was enough of a chance for the first one to fail, this should at the least be in another try catch block. I know the two are opening different files, but that's not enough of an issue. It does cause problems of it's own when trying to track down issues. Even when logging is on I have to have both files open and go back and forth looking for specific issues.

Furthermore the function WriteTraceLine that this is in, is the only place that the variable traceFile is used, but it is declared to be at the class level. Finally, this ignores all built in tracing functionality in C# and relies solely on tracing off or on.

The filenames are not configurable, even though the application is using a custom config file. At the least that would allow us to relocate the files to a folder that could be shared out on the server, without having to recompile code.

Finally the Elapsed time that is being logged, is how long the function took to open the trace file. This is not an important issue, and is something completely separate from the actual informatoin that was sent to be logged in the first place.

Monday, October 16, 2006

Goals and Metrics.

I think a lot about goals and measuring them. For myself either I complete something or I don't.
Company goals and department goals are also different than personal goals.

For example, if I'm in charge of a department I have a department goal of x units to produce per day. What's being produced won't matter, widgits, phone calls, sales made, it's irrelevant. At my company I know specifically what it is that my goal is and making x of it is what I want. If I want to ensure that I make x, then I have to set up goals that each person needs to do their part to reach that goal, so each person needs to do x/person. Pretty simple math. If each person reaches 100% of their individual goal, then I meet my department goal and everyone is happy. If the group averages 100% then we are also all happy.

I know of a situation where this is not how it's being done. Instead the supervisors are watching their employees and figuring out how many each can do a day and then coming up with the goal in reverse. In essence, with total disregard for the amount of work that may be profitable for the department we are finding out how much work our users are actually showing us they can get done. We've done this in the past, but amazingly after coming up with how much can be accomplished on average, the department always exceeds 120%. An average day should be around 100%.

I have several major philosophical issues with this. First the average amount of work a day is the amount that we get when we are currently hitting 120%. Our numbers should be shifted to make this amount the 100% amount. Second, the amount of work that we are doing is not tied in any way to the amount of work that we need to be doing. I don't know what those numbers are, but it's conceivable that even 200% is not enough. If we are getting w amount of work done and it's only 50% of what we need to be getting done it should be reported as only 50%. Currently we are rewarding our employees for getting more work done on a normal work day than they did when they were being timed and knew it. Of course they all worked slower during the timing phase because they knew it would make it easier for them to acheive their goals. By reward I mean we are actually paying out bonuses for people who are able to meet more than 100% of the easy goals that they set for themselves. This is wrong.

Goals are simple and straightforward. Getting x done earns us money, our goal is x. Getting more than x done earns us more money and we offer bonuses. I sometimes wish I could just slap the manager that came up with this way of measuring performance.

Tuesday, October 10, 2006

Commenting Code

I was recently asked my opinion on commenting code and if there were any standards that I follow. I have been a big believer in commenting code as long as I've been programming. I used to add comments to my own Basic code that I wrote on the Commodore 64 even. It's always been strange to me to go into a very complex piece of code and not see any comments. I would pick it apart and come out with a dialog that commonly goes like this.

Me: "This code is doing thing A exactly.
Other: That code is supposed to be doing A and B.
Me: Ok, but I didn't know that. I can only tell you what the code tells me. It does thing A.
Other: Why wasn't this caught sooner.

When things like this happen it's always the same. Even if I've been working on a piece of code for a long time, I cannot notice and change the problem in a function like this. I can possibly refactor the code to make it do A more efficiently or easier, but I can't make it do both A and B because there are no comments.

I believe that there should be a comment stating what the purpose of something is. Especially in the agile process where the requirements are small pieces that generally do not generate much in the way of design. Having a comment in the code that says what the process is supposed to do, is a good way to help other developers with understanding the code.

Unit testing is a good "What the code does" documentation, but it's not used everywhere. Having good unit tests could prevent the need for needing the documentation, however, unit tests are not written in clear English. When I write unit tests, I like to document the "What" in my unit test class. However, I'm not consistent enough with my unit testing.

Ultimately, having documented what is supposed to happen somewhere is very important. It allows others later to come in and see if the code is working properly.

Wednesday, October 04, 2006

Podcasting

Podcasting is easier now than it has been in the past. There are a lot of people out there that do it, and even more that listen. My friend Joel using podcasting as his method of delivering the piano music he plays. Many others just talk about things going on in their life. I remember growing up when I would receive a cassette tape in the mail from a friend who had recorded herself talking to me instead of writing me. That was the coolest thing ever. I thought at the time, "It will be so awesome if someday this can be done faster than using the mail". Obviously even then telephones were an option, but long distance was not as cheap as it is now. Now I can talk forever on my phone and it will only cost me 30$ a month. I can't even imagine what my life would have been like if I had that option when I was in high school. I could have easily paid for our phone and talked almost my entire life away. Looking back I'm glad that was not an option for me. Really, with as much dead time as there is on the phone, I sometimes wouldn't mind if people would just record their thoughts and send them to me all at once, then I don't have to worry about them getting off topic because of a question I ask. I can just hear what they want me to hear and move on.

Anyway, podcasting is big. There's lots of good reasons to do it, and just as many good reasons to listen. I compiled a few small lists of reasons of what I think about podcasts. In general. Specifically, I think there is a lot of potential in podcasting, and I think that a very small group will be able to fully take advantage of it for what it can be used for. I also feel the same way about the TV. I'll leave that for another time though.

3 Reasons Why I don't podcast.
1. I don't like to hear my own voice.
2. I like being able to proof what I'm doing and organize and coordinate it.
3. I don't have a good quiet place that I could record my voice other than my car ride to and from work, at which point my focus is driving.

3 Reasons you should podcast.
1. It's faster to talk than it is to type.
2. Posting a podcast is as easy posting a blog (link to podcast posting instructions)
3. A podcast can be listened to from the computer without having to look at it. Busy people only need the time to start the podcast, then they can continue taking care of their kids or making dinner while listening.

3 Reasons I don't listen to podcasts
1. Podcasts are generally too long. I can tolerate a 20 minute podcast, but some of the technology sites I go to have 1 hour plus podcasts.
2. I hate commercials. Some of the podcasts I've heard have a 5 minute commercial introduction, I understand your have a need to earn money from advertisers, but this is annoying.
3. I hate rambling. Some of the podcasts I have heard are from people who have never had a public speaking course in their life. I understand being nervous in front of an audience, but this is in the privacy of your own home. It's like singing in the shower, you just do it and don't care if anyone is listening.

3 Things that would make me listen to podcasts.
1. If a podcast is short and downloadable, then I can listen on my short 30 minute car ride home.
2. Don't ramble. Try to organize your thoughts before you start talking, think about public speaking, please don't say "um" 600 times.
3. Be dynamic and excited. Some podcasts are just people talking, very monotone, "Buehler, Buehler" C'mon, you wanted to say this, so say it.

Tuesday, October 03, 2006

Google reader

There is a new RSS Reader available. I'm sure a new one is released practically daily, however, this one has been released from the behemoth Google.

Check out more information about it at the Google Reader Blog.

I have not decided yet if I like it better than NewsGator or not. I have imported all of my feeds, which was an easy task.

From NewsGator I had to select My Settings, then view the Edit Locations tab. The OPML link was at the top. I was able to open it and save it to my PC. Then I could upload it into Google. This is fine for me, but it's a bit more complicated for anyone not as technical.

There are some things that I like with the Google reader.
1. I like the ListView. It lets me read just the heading. For my sports feeds, that is all that they have anyway, so being able to get them all in a smaller space is nice. I can pick the ones that I want to go to the site and read, and which to ignore a lot faster.
2. I like the folder organization. It is a nice clean look.
3. I like being able to select veiw all and get back to something that I've marked as read.
4. I think I will like being able to star the articles that I find particularly interesting, especially the technical articles. I haven't used this yet, but I am guessing that it will work similar to Clippings in Newsgator.
5. Keyboard shortcuts. I hate the mouse, and wish every website that existed would spend a ton of time creating keyboard shortcuts.

Even Google is not perfect. There are some things that I do not like.
1. Google still does not use Ajax style functionality. The important toolbar type of links at the top of the page scroll off when I am looking down the page.
2. I cannot drag a feed into a folder. Sometimes I'm lazy when I add a feed. I'll add it in my general aread because I don't know if I want to keep it or not. Then after I've been reading it for a while I like to move it to a folder that it's related to to keep things organized. As it is now I cannot drag the feed to a folder. This functionality does exist for me in NewsGator. Google's solution involves opening the "Manage Subscriptions" page, selecting which folder to put it into and then going back to Google Reader to see the updated structure.
3. Google Reader does not refresh as rapidly as NewsGator. I have dug around and cannot find a setting that would affect this. Basically, during the writing of this post NewsGator found 5 new articles, Google Reader didn't find any of them. How much longer am I going to have to wait with Google to be able to read what is already available?

Monday, October 02, 2006

Change slow in coming.

It sometimes seems as if change only happens when a major crisis occurs. However, I think more often a mental attitude adjustment which coincidentally corresponds to a major crisis, is the actual cause of the change.

For example. I've been trying for quite some time to get people that I work with to use a Wiki to document things. I am in love with the Wiki. It's so open and honest. If I make a mistake in my documentation, it can quickly be corrected by someone who knows better, or learns better. I've been using is for over a year. That's about the time at which I realized that everything should be documented, everywhere. I started blogging about a month after I started using the wiki at work. It's taken over a year to get my fellow employees to start documenting also. The thing that held them back was twofold. First, all people resist change. Second, telling that resisting change makes them suck will not help them change.

Ok, on the second one I didn't specifically ever say it like that, but the meaning can often come across when not intended. I would tell people that they could make it so much easier on someone else if they would just add some documentation out there. For the cost of a few minutes or an hour one time, you can say something that's out there and able to be accessed by everyone forever. This is the greatest thing EVER!!!! This did not work. Granted, maybe the change didn't come solely from my own change in encouragement. There was a policy change at work that all of the sudden helped people see the same thing that I had been saying.

It started with me saying. If someone else spends a few minutes documenting, it can help you out dramatically when you need to do that. This was not enough. It was good, it was the right kind of change in phrasing, but it was not enough. At the same time, work changed their policy. Whomever was on production support had to do everything possible to resolve the problem before involving someone that is working on new development. At first, almost nobody knew about any other system. So when person A had a problem come in, a lot of research had to be done to find a resolution. It was not documented anywhere, it was in person Cs head. Finally person A would ask person C and get the answer. The real bonus came when I was person A. I documented a bunch of solutions on the wiki. The next person A saw the documentation and was amazed (a little self flattery here). Suddenly the other people were able to see the real benefit to themselves. It was no longer an imaginary possible future benefit, but something that was tangible and could be used right now.

I am still standing here shouting from the cube-tops. Use the wiki. Document anything that you had to learn to do this, it will be something that someone else has to learn in the future. If you are each doing it then you will each benefit. The full support for the additional documentation is not there yet. Maybe it will require another change in department policy. Maybe I'll be able to win over just one or two more people and then it will snowball. A leader is only a leader if others follow. It doesn't even make him a leader to be doing the right thing. If nobody is following, he's just doing the right thing alone.

Through most of my life I've thought that change only happened in a "Change or Die" type of situation. After a heart attack a previously lazy lifestyle is thrown away and replaced with a healthy active lifestyle type of thing. That's wrong. Over the past several years I've seen too many instances where a wake-up call and slap in the face came, and yet the receiver didn't do anything. Alcoholics who hurt themselves and others, but refuse to go to AA. People who have bipass surgery and contniue to behave exactly as they have before. Diabetics who are told that they will not only have a shortened life, but could have body parts amputated; they still do nothing. I'm not sure why this would be. Are we just so convinced we are invincible that we choose not to change? Are we just stuck in the mindset that, "If I'm a live I'm going to live like I want"? Why don't these people see that changing their habits does not mean that they are living less of a life, in many cases they could be livin more of a life if they changed. I don't know any of the answers to my questions. I have asked a lot and now sit and wonder how it is that we as a race can become more open to change. Is there a teacher that can lead us into an open-minded lifestyle?

I I found this great article on the psychology of change, I hope you enjoy it. I found it strange that after I started this post I searched for articles, and potentially a solution., that this article seemed in tune with some of my own thinking. This was by far the best article I found. There doesn't appear to be enough solutions in this area.