# Friday, 30 August 2013

I limited my travel during July and August because it was the last months I would have my sons at home before they moved out of state for college. But the coming months will be very busy and filled with a  lot of travel. I started this hectic schedule last week with a presentation on Strategies for Refactoring and Testing Legacy Code at the Northwest Ohio .NET User Group and this pace only accelerates into the fal.

Date Event Location Topic  
Sep 14 Code Camp NYC New York, NY HTML5 is the Future of the Web Link
Sep 21 Vermont Code Camp Burlington, VT TBD Link
Aug 30 CloudDevelop Columbus, OH Cloud and Azure and Rock and Roll Link
Oct 1 DevConnections Las Vegas, NV Strategies for Refactoring and Testing Legacy Code Link
Oct 2 DevConnections Las Vegas, NV Connecting the Dots: Using HTML5, jQuery, and Web API Together Link
Oct 16 Great Lakes Area .NET User Group Southfield, MI Connecting the Dots: Using HTML5, jQuery, and Web API Together Link
Friday, 30 August 2013 10:02:00 (GMT Daylight Time, UTC+01:00)
# Thursday, 29 August 2013

I limited my travel during July and August because it was the last months I would have my sons at home before they moved out of state for college. But the coming months will be very busy and filled with a  lot of travel. I started this hectic schedule last week with a presentation on Strategies for Refactoring and Testing Legacy Code at the Northwest Ohio .NET User Group and this pace only accelerates into the fall.

Date Event Location Topic  
Aug 30 CloudDevelop Columbus, OHn Cloud and Azure and Rock and Roll Link
Sep 14 Code Camp NYC New York, NY HTML5 is the Future of the Web Link
Sep 21 Vermont Code Camp Burlington, VT Effective Data Visualization Link
Sep 28 Tampa Bar/Code Camp Tampa, FL TBD Link
Oct 1 DevConnections Las Vegas, NV Strategies for Refactoring and Testing Legacy Code Link
Oct 2 DevConnections Las Vegas, NV Connecting the Dots: Using HTML5, jQuery, and Web API Together Link
Oct 16 Great Lakes Area .NET User Group Southfield, MI Connecting the Dots: Using HTML5, jQuery, and Web API Together Link
Oct 17 Southwest Fox Gilbert, AZ HTML5 is the Future of the Web Link
Oct 18 Southwest Fox Gilbert, AZ How I Learned to Stop Worrying and Love jQuery Link
Thursday, 29 August 2013 18:39:00 (GMT Daylight Time, UTC+01:00)
# Wednesday, 28 August 2013

A “greenfield” application is one that is just getting started. It is named "greenfield" because it is reminiscent of a new building going up on a vacant lot that contains nothing but green grass prior to the start of construction.

By contrast, a “brownfield” application is one that has been going for some time (similar to an unfinished building surrounded by brown dirt where the grass used to be. Often, the code in a brownfield application is in a fragile state, contains excessive dependencies, unnecessary complexities and no automated tests. This describes most of the projects on which I find myself working.

Getting such code to a manageable state can be a challenge. One needs to understand the code, refactor methods and classes, break dependencies, and create automated tests.

Brownfield Application Development in .NET by Kyle Baley and Donald Belcham describes techniques for doing just that.

Baley and Belcham begin by introducing general concepts of the software development process (Unit Testing, Source Control), as well as some of the technical and non-technical challenges working with a brownfield project.

Each chapter begins with a set of pain points, then continues with ways to address that pain.

They focus on how to work with the code, describing algorithms for breaking dependencies and samples for using dependency injection and mock object frameworks.

Although not quite as comprehensive as Michael Feathers's excellent "Working Effectively with Legacy Code", this book focuses on the .NET languages, which makes it more relevant to my projects. In fact it addresses the current project on which I am working.

Brownfield Application Development in .NET is a good book for anyone who finds themselves working with code developed by someone else.

Wednesday, 28 August 2013 19:51:00 (GMT Daylight Time, UTC+01:00)
# Tuesday, 27 August 2013

Recently, I gave a talk to some new college hires about how to manage your career. Here are the main points from that talk:

Set Measurable Goals

Everyone should have goals. I set both long-term and short-term goals in my personal and professional life and I write these down and I look at them often. You will do better if your goals are tangible and can be measured because this allows you to determine how successful you are in meeting those goals and adjust your actions, if necessary.

Track your accomplishments

Most companies have a review process and it’s not uncommon for evaluations to take place once a year. Start thinking about your review early in the year. Every time you do something awesome, write this down. I keep a  spreadsheet with my accomplishment and bring this out during review time. Don’t rely on your manager to remember this for you. He may forget and he may leave the company before your review. And don’t rely on your own flawed memory.

Talk with your counselor

If your company has a mentoring program, take advantage of it. If your mentor is communicating enough, you should drive the conversation. Pick her brain and ask for advice. She was once where you are now.

Know the people in your unit

Get to know who your colleagues are and what their strengths are. You may need to draw on those at some point. Attend social gatherings and company meetings and establish connections in your local office.

Learn the basics of software development

There are some basic skills in this industry that every developer should know – data access; creating an interactive application; role-based security are a few. Know the fundamentals of the language in which you work. You can apply these skill to many types of projects.

Cultivate a specialty

To advance in the technology world, it helps to have deep knowledge of a topic. It’s not reasonable to assume you  can learn everything about everything. But you can dive deep into SharePoint or Windows Azure or Application Lifecycle Management and become the go-to person for this topic. This will increase your demand.

Understand and manage your online identity

Almost every new hire I encounter has a presence in social media, such as Facebook and Twitter. What you post there is a reflection of you and your company, so consider this before you hit the SUBMIT button. What is the online image I want to project? Will this post harm that image. Once something is on the Internet, it is very difficult to remove it. The Internet can be a powerful tool for promoting your brand, but it can just as easily damage your career if you are careless.

Learn something new every day

This is a challenge I made to myself years ago and I think of it as I drive home each night. Point to something new that you learned today. Over the months and years, it will add up because you will develop a habit of learning and improving.

Get certified

There is some controversy around the value of certification but for a young person with little practical experience, it can be a difference maker. I have some more thoughts on the topic at http://www.davidgiard.com/2010/05/18/AreCertificationsWorthwhile.aspx

Get involved in the local community

If you live in a large metropolitan area, you should be able to find user groups and technical conferences nearby. You can search for user groups at http://ineta.org/UserGroups/FindUserGroups.aspx and you can find conferences at http://tekconf.com/. These events are a great way to learn technology and to network with other developers in the area.

Own your career

Don’t wait for your company to train your or provide you with opportunities. Look for opportunities to contribute and succeed. Learn new skills on your own. This will not go unnoticed. s

Tuesday, 27 August 2013 21:00:00 (GMT Daylight Time, UTC+01:00)
# Monday, 26 August 2013
Monday, 26 August 2013 20:34:00 (GMT Daylight Time, UTC+01:00)
# Sunday, 25 August 2013

I think I’ll post my daily gratitudes here on the last Sunday of the month.

8/25
Today I am grateful I was able to cross off some items from my To-Do list that have been there for months.

8/24
Today, I am grateful that my father and I became closer during his final years. I feel as close to my Dad today as we ever were.

8/23
Today I am grateful that my mother made it home safely after 3 weeks in Michigan. When I asked her how she enjoyed the trip, she told me "I stayed too long."

8/22
Today I am grateful that Nick Giard drove out to Southfield yesterday to join me for lunch.
But mostly, I'm grateful for the fine man that he has become and for the joy of being his father these past 22 years.

8/21
Today I am grateful for the opportunity to premiere my "Refactoring Legacy Code" presentation at the Northwest Ohio .NET User Group and for all the good feedback I received.

8/20
Today I am grateful I have had the opportunity to raise Tim Giard these past 19 years and to see the fine young man he has become.

8/19
Today I am grateful for our family tradition begun during the last millennium of going to lunch with my 2 sons every Sunday - a tradition that continued almost without exception for over 15 years. A tradition that ended yesterday as my sons will move out of state this week and begin the next phase of their lives.

8/18
Today I am grateful for the continued good health of my 2 sons and myself.

8/17
Today I am grateful for a chance to teach at my first Sogeti Boot Camp.

8/16
Today I am grateful that my son Nick completed his undergraduate requirements yesterday, earning a BBA from Michigan State University. #proudddad

8/15
Today I am grateful for the chance to hang out with Michael Wood. It has been too long.

8/14
Today I am grateful for a visit from an old friend.

8/13
Today I am grateful that my son stopped by for dinner last night and the chicken fried rice I made turned out great!

8/12
Today I am grateful for a rare and much-needed Sunday afternoon nap.

8/11
Today I am grateful for a dinner of fresh Maryland blue crabs with my brothers and sisters and nieces and nephews and mother.

8/10
Today I am grateful for my brothers and sisters and my nieces and nephews and my mother. I am looking forward to seeing them this evening.

8/9
Today I am grateful for all these great podcasts that ease my long commute.

8/8
Today I am grateful for Elizabeth Naramore, who inspired me to think about the positive things in my life, even when things are going poorly.

8/7
Today I am grateful for a Daily Gratitude and a New Attitude
8/6
Today I am grateful for the Mud Hens game last night with Kevin Gill and Tim Giard.

8/5
Today I am grateful for a tasty pulled pork meal at Slow's Barbecue on a Sunday afternoon.

8/4
Today I am grateful for
1. Having my family over for a cookout yesterday
2. Seeing my mother for the first time since my father's funeral
3. An excellent Chris Hillman & Herb Pedersen concert last night.

8/3
Today I am grateful for
1. An unexpected Greektown dinner last night with my cousin, sister, brother, and sister-in-law.
2. Today's barbecue that will bring most of my family to my house.

8/2
Today I am grateful that I found a couple $20 bills in a jacket I haven't worn for months.

Sunday, 25 August 2013 13:32:12 (GMT Daylight Time, UTC+01:00)
# Monday, 19 August 2013
Monday, 19 August 2013 23:41:00 (GMT Daylight Time, UTC+01:00)
# Monday, 12 August 2013
Monday, 12 August 2013 11:50:20 (GMT Daylight Time, UTC+01:00)
# Saturday, 10 August 2013

According to Michael Feathers, legacy code is any code that is not currently under test. This is often the code I end up working with.

To make matters worse, dependencies within a code base often make it difficult to get that code under test. In order to write an automated test, one must recreate all those dependencies within the test systems - a daunting task if those dependencies are external systems, such as databases or web services.

In "Working Effectively with Legacy Code", Feathers describes ways to attack "untestable" code.

He suggests using "sensing variables" to determine what the code is doing within a method and writing an automated test specifically to document the current behavior of a method.

He also recommends some ways to refactor code to break dependencies or replace them with fake objects inside your test. One effective technique is to identify a problem method you want to test; make it protected; subclass the class; override the problem method, replacing the dependencies with fake objects; then call the subclass from your test.

The book focuses mostly on object-oriented languages, such as C++, Java, Visual Basic, and C#; but there are a few examples in procedural languages, such as C. The examples are simple enough that I was able to follow them and mentally translate the concepts to C# (my language of choice), despite having no practical experience with the other languages.

Feathers ends the "Working Effectively with Legacy Code" with a set of refactoring patterns designed to apply the principles of the book. In each case, he identifies the specific challenge the pattern addresses and some of the tradeoffs you will encounter when implementing this pattern.

"Working Effectively with Legacy Code" provides an excellent foundation for anyone who finds themselves maintaining someone else's code (or their own code from years before). I have used it as a model on my current project - a mass of spaghetti code with database calls within the UI layer.

I recommend it for anyone who finds themselves maintaining a legacy code base.

Saturday, 10 August 2013 21:34:36 (GMT Daylight Time, UTC+01:00)
# Friday, 09 August 2013

Spatial data types were introduced in SQL Server 2008. These data types allow you to store location information directly in your data rows and quickly query that information to create shapes and to determine locations, distances, and points within a given shape.

SQL Server defines two types of spatial data - Geography and Geometry. Both data types track locations as x, y coordinates. The difference is that the Geography data type takes into account the curve of the Earth, while the Geometry data type does not. Because of this, Geography data is often best suited for mapping locations by Latitude and Longitude and computing distances between locations that are far apart. With Geometry data, you can define your own coordinate (such as location in a warehouse) and you should focus on locations that are close enough that the Earths' curve is inconsequential (for example, the distance between storage bins in a warehouse or stations on a shop floor).

Both data types store x, y coordinates in a binary format and each can be used to query locations. A couple advantages of these data types are

  1. We can define database columns with these data types
  2. Built-in functions exist to do things like draw shapes and compute distances. We can call these functions within a SQL SELECT statement.
  3. These columns can be indexed, making calculations very fast.

Imagine a table with the following structure.

CREATE TABLE [dbo].[CustomerAddresses](
    [id] [int] IDENTITY(1,1) NOT NULL,
    [CompanyName] [varchar](250) NOT NULL,
    [StreetAddress] [varchar](250) NOT NULL,
    [City] [varchar](250) NOT NULL,
    [State] [varchar](20) NOT NULL,
    [PostalCode] [char](25) NOT NULL,
    [Geo] [geography] NULL,
    [Latitude] [decimal](18, 14) NULL,
    [Longitude] [decimal](18, 14) NULL
 CONSTRAINT [PK_CustomerAddress] PRIMARY KEY CLUSTERED 
(
    [id] ASC
) WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY] 

The Geo column of this table is a Geography data type and is designed to store binary information about the location coordinates.

We can index this column with the following command:

CREATE SPATIAL INDEX SIndx_CustomerAddress_geo_col1 
   ON dbo.CustomerAddress(Geo); 

If we have a table populated with latitude and longitude data (Fig 1), we can easily convert this data to the Geography data type using the Geography::Point function static extension method.

Fig1-SampleLatLongData[1]

Fig. 1 - Latitude and Longitude data

We convert x and y coordinates to the Geography data type using the Geography::Point function static extension method. The Geography::Point function takes 3 parameters: longitude, latitude, and a code representing the SRID, which is a well-known coordinate system. The most popular system is represented by 4326 and defines 0 latitude at the equator and 0 longitude at a line passing through Greenwich, England. It’s worth pointing out that the Geography::Point parameters list Longitude before Latitude, even though most coordinate systems list Latitude first. This can be confusing, but it’s something you will want to be aware of.
For this table, the SQL statement is

UPDATE GeoDemo.dbo.CustomerAddress
    SET Geo = Geography::Point(Latitude,Longitude, 4326)
    WHERE Latitude IS NOT NULL AND Longitude IS NOT NULL 

The SQL above populates a column of type Geography with point data representing latitude and longitude, as shown in Fig. 2.

Fig2-SampleDataWithGeoPoints[1]

One very useful extension method of a Geography Data Type is Distance, which accepts a parameter of another Geography point and returns the distance in meters between the 2 points.
The following code calculates the distance (in miles) between 2 points in our table.

DECLARE @GeoLocation1 GEOGRAPHY,
    @GeoLocation2 GEOGRAPHY,
    @MetersPerMile DECIMAL,
    @Distance DECIMAL (18,14)
SET @MetersPerMile = 1609.344
SET @GeoLocation1 = (SELECT Geo FROM dbo.CustomerAddress WHERE Id = 1)
SET @GeoLocation2 = (SELECT Geo FROM dbo.CustomerAddress WHERE Id = 2)
SET @Distance =     
    (SELECT @GeoLocation1.STDistance(@GeoLocation2)/@MetersPerMile)
PRINT @Distance 
PRINT 'miles between Point 1 and Point 2' 

Finally, we can use the STDistance extension method from within a SQL SELECT statement to calculate all points within a certain radius of a given point. Below is an example listing all addresses within 100 miles of Address #1

DECLARE @CustomerGeoLocation GEOGRAPHY,
        @RadiusInMiles INT,
        @MetersPerMile DECIMAL,
        @RadiusInMeters DECIMAL (22,14),
        @CenterId INT 

SET @CenterId = 1
SET @CustomerGeoLocation = (SELECT Geo FROM dbo.CustomerAddress WHERE Id = @CenterId)
SET @RadiusInMiles = 100
SET @MetersPerMile = 1609.344
SET @RadiusInMeters = @RadiusInMiles * @MetersPerMile
SELECT 
@CustomerGeoLocation.STDistance(c.Geo)/@MetersPerMile AS DistanceInMiles,
c.*
    FROM dbo.CustomerAddress c
    WHERE c.Geo.STDistance(@CustomerGeoLocation) <= @RadiusInMeters
    AND c.id <> @CenterId
    ORDER BY DistanceInMiles 

In this article, we introduced the SQL Server Spatial data types and showed how to use the Geography extension methods to calculate distance and find nearby locations.

Friday, 09 August 2013 10:33:00 (GMT Daylight Time, UTC+01:00)
# Wednesday, 07 August 2013

A few months ago, I discovered that I was doing way too much public whining on social media outlets. I used Facebook and Twitter as an outlet for my frustrations- real, imagined, and overemphasized. After I made this unflattering discovery, I decided two tings:
1. This was not the image I wanted to project to the world via my online presence.
2. This was not the attitude I wanted to permeate my life.

I've always believed that a good way to start changing one's attitude is by changing one's behavior. So I made a commitment to focus on the good things in my life - to wake up each morning and think of something in my life for which I am grateful.

I was inspired to do so by a couple talks I heard recently - one by Layla Driscoll at KalamazooX, titled "Find Your Happy; and one by Elizabeth Naramore at Stir Trek, titled "Stop Drinking Spoiled Milk". Layla and Elizabeth each keep a daily log of things for which they are grateful. They each shared some entries from their own logs and pointed out how this helped keep them focused on the important things in life. I decided to make a similar commitment to focusing on gratitude and to make my gratitudes public in the hope that others would be inspired as I was. I started on Facebook, posting a new gratitude each morning and later began cross-posting these on Twitter as well.

I find myself grateful for a variety of things. Sometimes, I think of something good that happened yesterday; sometimes about the anticipation of something coming today; and sometimes it's about a larger something that affects my life for years.

The results has been extremely positive. Although I still occasionally get down and I sometimes whine about the bad parts of my life, I find that my daily focus on gratitude has helped to counteract any lasting effects of depressing circumstances.

In addition, many people have responded to these posts - online and in person - and told me they enjoyed them. I've even seen others doing the same. I don't know if they were inspired by me or by the people who inspired me but I don't care. When I'm reading the thoughts of friends on social media, I'd much rather hear about how they are focused on the positives of their life than be overwhelmed with negativity.

And for that I am grateful.


Below is a partial list of gratitudes I have posted to date.:

Today I am grateful for the Mud Hens game last night with Kevin and Tim.

Today I am grateful for a tasty pulled pork meal at Slow's Barbecue on a Sunday afternoon.

Today I am grateful for
1. Having my family over for a cookout yesterday
2. Seeing my mother for the first time since my father's funeral
3. An excellent Chris Hillman & Herb Pedersen concert last night.

1. An unexpected Greektown dinner last night with my cousin, sister, brother, and sister-in-law.
2. Today's barbecue that will bring most of my family to my house.

Today I am grateful that I found a couple $20 bills in a jacket I haven't worn for months.

Today I am grateful that my mother and cousin are coming to town for the first time in years.

Today I am grateful for a delicious sushi dinner last night with my son and my final visit to East Lansing while he is a student there.

Today I am grateful for my cameras, which have allowed me to preserve moments of my life better than my own memory could.

Today I am grateful to read the tweets of @nprscottsimon as he chronicles his last days with his dying mother.

Today I am grateful I had the chance to catch up with Mike and Toni yesterday at lunch. It has been too long.

Today I am grateful for a long walk from one end of the runway to another yesterday afternoon with a sunny sky above me and a light breeze at my back.

Today I'm grateful that I made it to LearnSomething at Fanzoo Technology last night for the first time in a long time and that I made significant progress on a demo for my next presentation.

Today I am grateful for a great time last night with family and friends at the screenings for the Detroit 48 Hour Film Project.

Today I am grateful I didn't wake up with the hangover I deserve.

Today I am grateful to awaken to the sound of gently-falling rain on my bedroom window.

Today I am grateful for the time spent with my sister Denise, who passed away 4 years ago today. She has inspired me in so many ways.

Today I am grateful that Microsoft named me an MVP for the 4th consecutive year.

Today I am grateful that, for nearly 2 decades, my boys and I have maintained a tradition of going out to lunch together after church each Sunday.

Today I am grateful for this:
IMG_4721-S[1] IMG_5207-S[1]

Today I am grateful that my brother is staying with me. It's a rare visit, since he lives near Sydney, Australia.

Today I am grateful for the opportunity to deliver a eulogy at my father's funeral.

Today I am grateful that my mother, who has been through a very rough time these past 5 years, is now as strong as I have ever known her.

Today I am grateful that, years ago, I stumbled into a career that encourages me to learn every day.

Wednesday, 07 August 2013 02:46:38 (GMT Daylight Time, UTC+01:00)
# Tuesday, 06 August 2013