Thursday, May 30, 2013

Do you have a “Calling” or a “Job”?

I am almost done reading “The Happiness Advantage” by Shawn Achor. In it he talks a little bit about how people view their jobs. Regardless of the job, whether it is a janitor or a CEO, if you view your job as your “calling” then you have a tendency to be more successful at it (success is based on your own criteria).

So I started thinking about what I do and why I feel I am successful at it. First, what is success to me? Well, success to me is a combination of things. It is me looking forward to getting up and going to work everyday (well almost everyday), it is displayed to me as my customers (those folks inside Burt’s Bees at the moment) thankfulness for me solving a real problem, as my work having a positive financial impact to my company, as me being able to spend quality time with my family and enjoy a life outside of my work.  These are my primary criteria and indicators of success.

So lets match my criteria for success with the last year here at Burt’s.

As an Agile Software Development Coach and a Software Engineer my job is to guide others through a methodology that I am passionate about and to demonstrate to them its effectiveness by participating in it as an engineer. I love what I do! And I love the group of people I do it with! We really enjoy our work day. We laugh a lot and swear too much, but we get work done and our customers are generally pleased with our work.

The last year has seen two clear victories for the Agile methodology here at Burt’s. Two projects where the business came away happy and the application development group came away proud of what it produced. I credit the business for being open to Agile and the team for working hard at making it work.

We believe our work has a positive financial impact on the company (we have also been told this by those who would know). We can see the time saved in not having to discern certain data points, in being able to add data points to the ERP without much effort and using those points to make strategic decisions. Great indicators to the application development team that our efforts are paying off.

We also are able to work from home when we need to. When my daughter has a gymnastics meet out of town, I don’t have to beg and plead to get the time to go.  When my son has a soccer tryout at 5:30pm 45 minutes away through Raleigh traffic, I can leave early to get him there. When my wife and I want to spend time helping a refugee family during the day in Durham with our church group, I am given time to do that. So my life outside of Burt’s is a blessing and I am happy to be able to have one.

Do I feel my job is my “calling” as Achor talks about in his book? You bet! Do I think I am more successful as a result of my attitude or does my attitude stem from my success? Well, I believe my attitude contributes to my success more than my success contributes to my attitude but each case is true.

In my previous “job”, I felt I was successful to a certain extent but I did not see it as my “calling”.  It did not hit all of the criteria I outlined above. Some things were missing. Which is one reason why I left to find my “calling”.

What is your “calling” and are you doing it?

Till next time…

Technorati Tags: ,,,,,,

Wednesday, January 09, 2013

Iteration 2012, a Retrospective

Will 2013 bring more of the same or will it be something completely unexpected? Well, it will probably be both. Every year we ask ourselves these types of questions. And every year we reflect on the past year. As humans, we have this need to substantiate our existence. The end of one year and the beginning of another offers us the opportunity to reflect and make changes. A retrospective. In the Agile software development world the past year could be equated to an iteration or a sprint. A very long one.

At the end of each iteration in Agile Software Development we have a retrospective.  Where we answer 3 basic questions: What did I do well? What do I need to improve on? and What will I do specifically to address the items I need to improve on? Well for Iteration 2012, my retrospective looks something like this.
What did I do well?
I have successfully introduced Agile to a willing group of talented software engineers and management
I have successfully run Agile projects at both Farm Bureau and Burt’s Bees
I have successfully increased my knowledge of manufacturing processes and systems
What do I need to improve on?
I need to be more aware of and keep more up with technology changes in my core competencies
I need to be better at making networking a priority
I need to be less dependent on the status quo
What will I do specifically to address the items I need to improve on?
I will write a functional program in at least 2 new languages and publish those programs
I will contact at least one person in my linked in contacts at least ever other week
I will discuss my opportunities within Burt’s with my boss and actively work on career objectives whether at Burt's or not.
Short and sweet. An Agile approach to the year.  Maybe next I will have a Sprint Planning Meeting for the next Iteration: Iteration 2013. 

So another year has come and gone. There have been many changes in the world and all around us locally. 2012 brought significant change in my personal and professional career.

In my professional life I have had setbacks and success, closure and new beginnings, disappointment and inspiration. I left Farm Bureau Insurance for Burt's Bees. And at Burt's I have had great success. I introduced Agile and have had a very successful Agile project complete and in the books. We shall see what Burt’s has to offer me in 2013.

Till next time…

Thursday, July 26, 2012

Auditing ExtendedProperties

So yesterday I was coding a User Story about reporting audit information for the project I am working on.  This project basically extends the ERP application called Macola (don’t get me started). What we are building is an extended properties application and we are auditing each change to an extended property for SOX compliance.

So we are using a class called (funny enough) ExtendedProperty. We have a collection of these objects to fill our grid using a List(of ExtendedProperty).  We were auditing each save in the Save method of each individual ExtendProperty.  This created a ton of audit entries in the database. We decided to combine these into a batch audit at the collection level to mitigate the number of entries and use the xml data type in SQL Server.

So our Audit objects began to take shape and now look like this:


An AuditEntry has a one to many relationship to an AuditChange. And an AuditChange has a many to many relationship to AuditColumn as well as AuditKey. Each of the objects overrides the .ToString function to return xml to be stored in the database.

The metadata in AuditEntry is in separate columns in the database and AuditChange, AuditColumn and AuditKey are all stored in a single xml column.  This gives us great flexibility in what we can audit and how much space it takes up.

How this relates to an Extended Property is that each property is responsible for its own audit unless it is in a collection of changes.  So we had to change how we accessed the List(of ExtendedProperty) in the containing class. We could not have a List anymore because it became difficult to act on that list as a whole. This caused us to create an ExtendedProperties collection class that inherits from List(of ExtendedProperty). This class gives us the ability to act on the collection as a whole but still allows us the functionality of a List(of T).

The results of this audit can be returned flattened using xquery in SQL Server.  It can be a little complicated when trying to compare values (sql:parameter(“parametername”) is your friend in xquery). But it makes life easier when batching audit entries.

Cool Visual Studio 2010 feature

As an aside, while I was coding the audit classes above I discovered a GREAT feature in VS2010. First I created a file for the class, then I started coding the public properties of the class. I did not create the constructor of the class yet.  I went to a calling class and instantiated this new class and put the arguments in the call.  There appeared a blue squiggly line below the code with the little red block in the bottom right.


When I click on the little red block it tells me it can create the constructor in the class.


So I tell it to go ahead and do that by clicking on the link. Now keep in mind I had already created the public properties for this class that will expose the arguments in the constructor.  So what did Visual Studio do?  It knew which arguments to assign to the private class variables automatically and wrote the constructor for me and assigned the arguments to the variables.

Sub New(ByVal userName As String, ByVal propertyName As String, ByVal operation As String, ByVal originalValue As String, ByVal newValue As String, ByVal timeStamp As Date)

' TODO: Complete member initialization
_userName = userName
_propertyName = propertyName
_operation = operation
_originalValue = originalValue
_newValue = newValue
_timeStamp = timeStamp

End Sub


till next time…

Technorati Tags: ,,

Monday, May 14, 2012

T-SQL Conditional WHERE Clause

I started the day today with great ambition. I am tasked with removing hard coded SQL and change to use stored procedures. I made it through several stored procedures and was fat, dumb, and happy. Until… I was stumped with a problem I was unprepared to solve. The problem occurred in converting a bunch of case statements in the hard coded SQL.  The code looked something like this (changed for brevity)

Dim strSQL As New StringBuilder
strSQL.Append("SELECT TOP 300 cus_no ,cus_name, search_name, slspsn_no")
strSQL.Append("FROM MyTable")
If myValue1 IsNot Nothing Then
strSQL.AppendFormat("WHERE value1 = '{0}' ", myValue1)
ElseIf myValue2 Nothing Then
strSQL.AppendFormat("WHERE value2 = '{0}' ", myValue2)
ElseIf myValue3 IsNot Nothing Then
strSQL.AppendFormat("WHERE value3 LIKE '{0}%' ", myValue2)
End If
If accountType > 0 Then
strSQL.AppendFormat("AND value1 {0} IN (SELECT thisValue FROM MySecondTable", IIf(accountType = 1, "", "NOT"))
End If
So I decided to tackle the first if block first. I googled the hell out of conditional where clauses in T-SQL. After a little bit of reading and experimenting I finally decided to go with the COALESCE solution.  this was tricky because if a field is NULL and the parameter is NULL then COALESCE will not equal each other so for the three conditions in the first if block I came up with the following:
WHERE COALESCE(value1,' ') = COALESCE(@myValue1, COALESCE(value1,' '))
AND COALESCE(value2,' ') = COALESCE(@myValue2, COALESCE(value2,' '))
AND COALESCE(value3,' ') LIKE COALESCE(@myValue3, COALESCE(value3,' '))
This had the desired affect. Notice the first and third COALESCE in each line has the space.  This is how you account for the NULL = NULL situation.
Now on to what I consider the harder of the two types of conditional where clauses represented here. If accountType is supplied and it is equal to one then check to see if it is IN the list returned from the SELECT. If accountType is supplied and is greater than one then it should not be IN the SELECT statement. if accountType is not supplied then don’t bother adding it to the where clause. I found some great examples of bit comparisons in the google search but they all used equals instead of IN and I couldn’t get IN to work with the case statements but I combined a couple of good items into this solution:
AND ((@AccountType=1 AND value1 IN (SELECT thisValue FROM mySecondTable))
OR (@AccountType>1 AND value1 NOT IN(SELECT thisValue FROM mySecondTable))
OR (@AccountType<1 AND value1 = value1))
This covers all possible scenarios. Let me know if you have another way to accomplish this.

Till next time…
Technorati Tags: ,,,,

Friday, April 13, 2012

Back In Time: NUnit Again

So I have been tasked with implementing unit testing in some legacy code that uses Visual Studio 2005.  For various reasons this code base is not ready to be converted to the newest version of .Net.  That being said, it is a sizable chunk of code and really needs to be refactored and tested.

There are no unit tests for this codebase. So now is the time to add them.  Since we are past the Test Driven Development option we are now going to try Defect Driven Testing.  Every time a defect is found or reported, we will write a test that proves it is a defect and then green the test to fix the defect. We will also try to refactor areas around the code in which the defect was found. But before we refactor we will write tests so we are assured not to have changed what the code was doing.

Visual Studio 2005 does not have the MS Testing framework unless you have purchased the "Test" version of Visual Studio.  VS 2008 and forward included the testing framework by default.  So I downloaded Nunit.

Now I haven't used Nunit since 2008 so I wanted to make sure I had everything working.  I tried running the sample tests that were downloaded with the installer. I opened the samples solution and keyed ctrl-shft-b to build the solution. Fail.

I thought, what? This should work out of the box.  Well, it didn't.  The nunit.framework reference in the project had the little yellow warning triangle  because it couldn't find the assembly.  So I removed the reverence and added it again. Voila! It compiled.  Great, moving on.

Then I added Nunit as an external tool like I remembered I had to do to get a quick link in Visual Studio.  So I clicked Tools/External Tools menu and it brought up the External Tools form.  I clicked Add to add a new tool and added the path and the name of the tool.  Then I forgot what to put in the Arguments and Initial Directory fields so a quick Google search gave me the answer. Or so I thought. 

Several links on Google said to set Arguments to $(TargetPath) and Initial Directory to $(TargetDir).  This did not work.  So what does a guy do who can’t get a software package to work? Look at the documentation, of course!

Well right there in from of my eyes, the Nunit documentation says:

Running From Within Visual Studio

The most convenient way to do this is to set up a custom tool entry specifying the path to NUnit as the command. For a VS2003 C# project, you can use $(TargetPath) for the arguments and $(TargetDir) for the initial directory.

With Visual Studio VS2005 this becomes a bit harder, because that release changed the meaning of the 'Target' macros so they now point to the intermediate 'obj' directories rather than the final output in one of the 'bin' directories. Here are some alternatives that work in both versions:

  • $(ProjectDir)$(ProjectFileName) to open the VS Project rather than the assembly. If you use this approach, be sure to rename your config file accordingly and put it in the same directory as the VS project file.

So I did changed the Argument and Initial Directory settings to be $(ProjectDir)$(ProjectFileName) and it all worked!

Interesting how things get remembered.  Someone else must have figured this out at my place of employment back in 2008.

Till next time...

Technorati Tags: ,,,