Monday, November 17, 2014

Still More Smart Unit Tests (Preview): Exploring Exceptions

Last week I started an exploration of Smart Unit Tests (preview). The articles are collected here: Jeremy Bytes: Exploring Smart Unit Tests (Preview). In the last article, I added guard clauses to verify parameters to see how Smart Unit Tests reacts to it. I noted that the tests that generated the exceptions were still passing tests because they were annotated with the "ExpectedException" attribute.

I got a bit of clarification from Peli de Halleux (who is on the Pex team from Microsoft Research) about this behavior.
This makes sense. Since Smart Unit Tests creates tests based on parameters, it makes sense that it treats ArgumentException different from other exception types since ArgumentException is likely to be thrown by things like guard clauses and code contracts that verify parameters.

Let's explore this a bit more.

[Update: Smart Unit Tests has been released as IntelliTest with Visual Studio 2015 Enterprise. My experience with IntelliTest is largely the same as with the preview version as shown in this article.]

Something Other Than ArgumentException
I'll start by changing one of the guard clauses to a different exception type.


I changed the "ArgumentException" to "IndexOutOfRangeException". Now let's re-run Smart Unit Tests.


Now we see that we have a failing test. Test #7 uses "2" as the "currentState" (and as a reminder, this is outside the range of our enum).

And we can see that the test does throw an "IndexOutOfRangeException". But this time, it treats this as a failing test.

Here's the detail of the test when we click on it:


Notice the attributes: we have an attribute "PexRaisedException" which notes the exception that was raised, but we do not have an "ExpectedException" attribute in this case.

So what we can see here is that if the code throws something other than an ArgumentException (or something that inherits from it), the result is a failing test.

Now if we were not expecting this exception, this test gives us *great* information. It tells us we need to guard against the exception or catch it and make sure we handle it cleanly. So, this can give us some great insight into scenarios we may not have thought about.

But that's not what we have here. This exception is perfectly fine for this block of code.

Allowing the Exception
So we have a problem: we really want to allow this exception. (Side note: in a real application, I would keep this as some subtype of ArgumentException, but we're just using this as a sample case for an exception that we expect in our code.)

Fortunately, Smart Unit Test allows for this. If we right-click on the failing test, we get a number of options:


These options are also available in the tool bar. Let's see what happens when we choose "Allow" and rerun Smart Unit Tests.


Now our test passes (Test #7). Here's what we see when we click on the details:


The attributes have been updated. Now we *do* have an "ExpectedException" attribute that says we are expecting an "IndexOutOfRangeException".

A New Test Project
When we choose "Allow" on our test, that setting needs to be saved somewhere (this is also true if we select one of the other options: Save, Fix, or Suppress). These end up in a new test project that gets added to our solution automatically.


The project is called "Conway.Library.Tests" (since it is based on the "Conway.Library" project). And the test class is "LifeRulesTest" since it is based on the "LifeRules" class.

Here's what the class looks like:


Since we chose "Allow", there are some attributes that reflect that.

Now, as Peli noted, "ArgumentException" is allowed by default. This is the first "PexAllowedExceptionFromTypeUnderTest" attribute. And based on the attribute, we can see that in addition to "ArgumentException" we also allow any exceptions that inherit from that exception (so things like "ArgumentOutOfRangeException" and "ArgumentNullException").

We also have a note that "InvalidOperationException" is allowed as well. We have the option of changing these attributes if we want to.

And then we move down to the test itself. Notice that it is attributed with "PexAllowedException" for "IndexOutOfRangeException". This means that we will no longer get a "fail" if that type of exception is thrown for this test.

Peli was also nice enough to point me to a wiki with more details from the Pex project (which is what Smart Unit Tests comes out of). You can a description of the various attributes here: Pex - Automated Whitebox Testing for .NET : Allowing Exceptions.

Wrap Up
So we can see that Smart Unit Tests gives us control over what exceptions we consider to be acceptable in our code.

I've been playing a bit with the other options that we have on the tests as well (Save, Fix, and Suppress). "Save" is pretty obvious -- it saves off a copy of the tests so that we can re-run them later and even modify them if we want. "Fix" allows us to add manual code to places where Smart Unit Tests may not have been able to generate a complete test case. I'm exploring this right now, so you can look forward to more info in the future. I haven't used "Suppress" yet, but I'll give that a try as I continue my exploration.

Look forward for more to come.

Happy Coding!

Friday, November 14, 2014

More Smart Unit Tests (Preview): Guard Clauses

Yesterday we looked at the new Smart Unit Tests feature that is part of Visual Studio 2015 Preview. I couldn't resist doing a few more updates to my code to see how Smart Unit Tests would react. As a reminder, this is based on preview versions of the technology (from 11/12/2014).

[You can get links to all of the articles in the series on my website.]

[Update: Smart Unit Tests has been released as IntelliTest with Visual Studio 2015 Enterprise. My experience with IntelliTest is largely the same as with the preview version as shown in this article.]

Adding Guard Clauses
One thing that I mentioned yesterday is that we could add code contracts to put limitations on the parameter ranges, and Smart Unit Tests would pick up on that. So, I actually tried it.

Now I didn't use the "Contract" class/methods because I'm still a bit wary -- the classes are built in to the .NET Framework, but you need to download an IL re-writer from Microsoft Research in order for it to work. I'm hoping the re-writer shows up "in the box" one of these days (or gets integrated into the Roslyn compiler).

So instead of using code contracts, I added a couple of guard clauses to the method:


The first statement checks to make sure that the "liveNeighbors" parameter is within the valid range of 0 to 8 (inclusive). Otherwise, we throw an argument out-of-range exception.

The next statement checks to make sure that the value of the "currentState" parameter is valid for the enum. As a reminder, enums are just integers underneath, so the compiler will accept any value for them. Because of this, we really should verify that we're getting a valid value.

And we saw this yesterday. When we did *not* have the guard clauses, Smart Unit Tests created a test to see what would happen with a variable that was out of range:

Tests *before* the guard clauses were added

Test #5 shows uses a "currentState" of "2". The valid values are "0" (Alive) and "1" (Dead). And because we didn't have any checks in our code, this returns a valid result (actually, an invalid result from a business perspective, but a valid result as far as the compiler is concerned).

Updated Smart Unit Tests
When we run Smart Unit Tests against the new method with the guard clauses, we end up with a different set of tests:

Tests *with* the guard clauses

We still have the same tests (in a slightly different order), but we also have some new tests (and one test with a new result).

Just like we talked about yesterday, Smart Unit Tests goes through every code branch and generates tests with parameters to exercise those branches. The same is true for the guard clauses.

So, if we look at Test #3, we see a test with "8" as the "liveNeighbors" parameter. This is edge of the range for our first guard clause.

Then in Test #5, we see a test with "9" as the "liveNeighbors" parameter -- outside of the range of the guard clause. And notice the result: we get an ArgumentOutOfRangeException, and the error message matches what is generated by the method.

Is throwing an exception really considered a "passing" test? Absolutely. This is the behavior that we expect for an invalid parameter. Here's the actual test method that was generated:


Notice that there is an "ExpectedException" attribute. Normally a test that throws an exception results in a failure. But if we tell the testing framework that we expect to get an exception, then it becomes a "pass" -- in fact, it will fail if no exception is thrown.

Test #8 tests the other end of the first guard clause. It uses "int.MinValue" for the "less than 0" condition. And this generates the same exception we just looked at.

Finally, Test #7 looks at the value of our enum parameter. Before we added a guard clause, Smart Unit Tests did generate a test for this case -- "currentState = 2", but our method was not set up to catch this and returned a valid value.

But with the guard clause in place, this test now throws an exception.

Verifying Expectations
So it's interesting to see how Smart Unit Tests handles guard clauses. Just like our other code, it generates tests to exercise those code paths. And if there are exceptions, then it generates a test that assumes the exception is expected.

Again, these tests tell us what our code *actually* does not what it is *expected* to do. After generating these tests, it is vitally important that we analyze all of the generated tests and results. What we may find is that there is a test that throws an exception where we do *not* want an exception to be thrown. Smart Unit Tests does not know the intent of our code -- only what it actually does.

So, if our tests throw exceptions, we need to double check to make sure that it is the behavior that we want. Otherwise, we need to update our code and try again.

[Update 11/17/2014: Peli de Halleux from Microsoft Research was nice enough to send some clarification on how exceptions are handled by default. We explore this in the next article: Smart Unit Tests (Preview): Exploring Exceptions.]

Smart Unit Tests and Legacy Code
As I mentioned yesterday, I'm still trying to figure out how (or if) this technology fits into my workflow. There is one place where Smart Unit Tests is very compelling: working with legacy code.

If I walk up to an existing code base that does not have unit tests in place, I can run Smart Unit Tests against the code to generate an expected baseline behavior -- this is what the code does today. Then I can save off those tests and run them regularly as I make updates or refactor the code. These tests would let me know if I inadvertently changed existing behavior.

That is a very compelling use case for this technology.

Now there are also some questions when thinking about this scenario. If a legacy code base does not have tests (and maybe it's a bit of a mess as well), then it may be difficult to create tests due to dependencies between classes.

The example method that we've been using to generate tests is *extremely* simple. And it lends itself well to unit testing. It does not have dependencies on any external objects or methods. It only acts on the parameters being passed in. And it does not modify any shared state that affects other parts of the code. Because of this, it is very easy to test.

But when we get to more complex situations that may require dependency injection or mocking, it's not quite as easy to generate tests -- especially if the code is not loosely-coupled. (It looks like I'll be running Smart Unit Tests against different types of code to see how it reacts.)

Wrap Up
It will be very interesting to see how this technology evolves. We saw here that we can add guard clauses to our method and appropriate tests are added to exercise those code paths. I'm going to keep thinking about ways that I can integrate this technology into my programming workflow. It seems like there are a lot of possibilities out there.

Happy Coding!

Thursday, November 13, 2014

Smart Unit Tests (Preview) and Conway's Game of Life

I have a love/hate relationship with automated test generation. Visual Studio 2015 Preview has a new built-in feature: Smart Unit Tests. This is one of the features that we got a sneak peak of at the Microsoft MVP Summit last week and was announced publicly at the Connect(); event this week.

Smart Unit Tests came out of the Pex project from Microsoft Research. And it works by going through the code, finding all of the possible code paths, and generating unit tests for each scenario it finds. I want to emphasize that this is currently a preview. So, we aren't looking at final functionality here.

I downloaded the latest Visual Studio 2015 Preview yesterday (11/12/2014) so that I could give this a try. Let's see how it works with our Conway's Game of Life implementation.

[Update: This exploration of Smart Unit Tests has turned into a series. Get all the articles here: Exploring Smart Unit Tests (Preview).]

[Update: Smart Unit Tests has been released as IntelliTest with Visual Studio 2015 Enterprise. My experience with IntelliTest is largely the same as with the preview version as shown in this article.]

Generating Tests
A couple weeks ago, we implemented the rules for Conway's Game of Life using TDD and MSTest (and then we looked at parameterized tests with NUnit). We'll work with that same method.

Here's the code we ended up with:


Generating Smart Unit Tests is really simple: just right-click on the method (or class) and choose "Smart Unit Tests".

The result for this method is 5 tests:


Let's walk through how these are generated (this is the cool part about the technology). Here's how it figures out how to generate the tests.

Test #1
For the first test, it provides the default values for the parameters. Since "CellState" is a enum (which is actually an integer underneath), it uses the "0" value which happens to be "Alive". Since the "liveNeighbors" parameter is an integer, it just supplies "0".

The result when following this path is that it hits the "CellState.Alive" in the switch statement and then the "if" statement evaluates to "True" (since 0 is less than 2), so the result is "CellState.Dead".

Here's the actual test that was generated:


Other test methods look similar, so I'll let you use your imagination for those.

Test #2
For the next test, Smart Unit Tests recognized that we hit the "True" branch of the first "if" statement, so it supplies a parameter that would cause it to hit the "False" branch. In this case, it chooses "2" because the conditional includes "liveNeighbors < 2".

The result when following this path is that it just drops through to the "return" statement, so the value is unchanged: "Alive".

Test #3
For the next test, we take the next "case" in the "switch" statement. So, a test is created to check "CellState.Dead" and goes back to the default "0" value for number of live neighbors. The "if" statement evaluates to "False" (since it is not equal to "3").

The result from this path is that the value is unchanged: "Dead".

Test #4
For the next test, Smart Unit Tests figures out that the "liveNeighbors" parameter needs to be "3" so that it hits the other branch of the "if" statement. This way it will evaluate to "True".

The result from this path is that the value is updated to "Alive".

Test #5
The final test passes in a value for the CellState enum that will not be caught by the "switch" statement. This value is "2" (which is an invalid value for the enum, but still allowed since it is really just an integer). This does not hit any branches, and so the value is returned unchanged: "2".

Pretty Cool
So this technology is pretty cool. It is not just passing in random values for the parameters of the tests. It is actually walking through the code and keeping track of which branches are hit or not hit. Then it generates parameters to exercise each branch of the code.

Now, I wish that this had generated at least one more test with the parameters "Alive" and "4". This would catch the "liveNeighbors > 3" condition. I'm hoping that this will be updated in a future release (again, remember we are dealing with preview code here). Regardless, each code path *is* exercised.

These tests are dynamically generated, but we can save them off as regular MSTest methods that we run with our standard test runner. This is good because none of these tests show what the code is *expected* to do; this shows what the code *actually* does. So, it's really up to us to analyze the tests that are generated to see if the results are what we expect.

Once we have these tests saved off, then we'll be able to tell if code updates change the functionality because they would fail (just like our other tests). This reminds me of a similar workflow that we have with Approval Tests, where we say "yes, this is a valid result" and then are warned if we don't get that expected result.

I'm a Bit Cautious
Even though this technology is really cool, I still have some misgivings about it -- mainly based on my experience with various teams.

Not Good for TDD
Obviously, we're generating tests *after* we have the code, so it's not possible to use this technology in a TDD environment. As I've mentioned previously, I'm not quite at TDD in my own coding practices -- I'm more of a "test along side" person. This means that I write some code and then immediately write some unit tests to exercise the code. (This is much different from people who build their tests days or weeks after the code is written.)

Not Quite Exhaustive
Even though we are exercising all of the code paths, we aren't actually testing all of the valid values. Remember from our parameterized testing, we added test cases for both CellStates (Alive and Dead) and for the valid range of live neighbors (which is from 0 to 8). The result was 18 test cases:


This more closely matches our actual business case for this method.

Now, if we add code contracts, we can add valid ranges for our parameters. In this case, Smart Unit Tests would provide some tests for parameters outside of the range to make sure that it behaves as expected (such as by throwing an ArgumentOutOfRangeException). But it won't generate tests for all of the values in the valid range (again, this may change in future releases).

[Note: I experiment with guard clauses in the next article: More Smart Unit Tests (Preview): Guard Clauses.]

Developers Who Don't Understand Unit Testing
My biggest misgiving about auto-generated tests is more of a developer problem than a technical problem. I've worked with groups who consider success as having 100% code coverage in their tests. So a tool like this would simply encourage them to auto-generate tests and say that they are done.

It's easy to get a tool to report 100% code coverage, but it's much harder to actually have 100% coverage. For example, our generated tests above do give us 100% coverage, but they don't deal with 100% of the scenarios. For example, we really should put in a parameter check to make sure that "liveNeighbors" is between 0 and 8 (inclusive). But there's no way for the computer to know about that requirement that is missing from our code.

So I'm a bit wary of tools that make it easy for these types of teams to simply "right-click and done". This is great as a helper tool, but it should not replace our normal testing processes.

The Best Thing
The best thing about auto-generated tests is that we can use them to help fill in the gaps in our testing. In our scenario above, there was a test generated for a "CellState" of "2". This is out of range for our enum, but it is still valid code since the enum is ultimately just an integer.

I could use a test like this to say, "Whoah! No one should be passing in a '2' for that value." And then I could immediately add a range check to my method. The test would still be generated, but instead of the method returning normally, it would throw an exception -- which is exactly what we want.

Wrap Up
So like I said, I have a love/hate relationship with auto-generated testing. It is an extremely cool technology. And I really like how Smart Unit Tests is really smart -- it traverses the code to find all of the valid code paths. I'm going to be running this against a bunch of my other code to see what it comes up with.

But I am a bit wary as well. I'm afraid that some developers will use it to auto-generate the tests and then think nothing more about testing. That really scares me.

I'm going to be following this technology closely. And I expect to use it quite a bit to fill in the gaps in my testing. It will be interesting to see where this goes.

Happy Coding!

Wednesday, November 12, 2014

Visual Studio Community 2013 -- Available Today!

There have been a lot of announcements so far at today's Visual Studio Connect event (and there will be a lot more). Much is coming soon or being released in preview today, but what I'm most happy about is something that is available today: Visual Studio Community 2013.

Goodbye Fragmentation
The reason I'm so excited about this is because the Visual Studio Express editions have been causing me problems -- well, not me personally (since I have access to Visual Studio Ultimate) but to the people who want to follow along with my code samples.

I have a lot of demos -- whether from my blog articles, live presentations, or Pluralsight courses (check out my website if you don't believe me). And I tend to use the same type of applications for my demos. Here are some typical solutions:

From "Clean Code: Homicidal Maniacs Read Code, Too!"

From "IEnumerable, ISaveable, IDontGetIt: Understanding .NET Interfaces"
Most of my applications are written with WPF (because I love XAML -- and there were some great announcements regarding The Roadmap for WPF today, too). But I use a WCF SOAP service (or WebAPI service) as a sample data store. This means that I have a web application as part of the solution as well.

Unfortunately, it's not possible to open this solution successfully with a single version of Visual Studio Express. The Desktop edition would open the WPF project just fine, but not the Web application. And the Web edition would open the Web application just fine, but not the WPF project. This meant that I had to steer people toward a free trial of Visual Studio Professional to open the solution without doing anything special.

Unified Development Environment
The great news is that Visual Studio Community 2013 (available now) works with *any* project type.

This means that people who want to try out .NET and Visual Studio (and maybe aren't doing this as their day-to-day work) can now run my sample code without modification. Whoo-hoo!

I was actually looking into how I could make my demo code easier to run based on the state of the Express editions (maybe changing to self-hosting projects or hosting web services online). But I really like to have the sample code run out-of-the-box without needing a network connection. So, I'm very happy about this new edition of Visual Studio.

Other Features
Another big change is that Visual Studio Community 2013 supports Visual Studio extensions (something that was not available in Visual Studio Express). This makes the IDE a much more powerful environment.

So, lots of cool stuff is being shown (Scott Hanselman is showing more cool stuff as I write this). But I'm very excited about what is available right now to give developers (and aspiring developers) and easy on-ramp into the world of .NET through Visual Studio -- one of the best development environments out there.

Happy Coding!

Monday, November 10, 2014

Optimizing Conway's Game of Life with Parallel.For

I've been continuing my coding practice with Conway's Game of Life. Last time, we added a simple UI (just a console application). This time, we'll look at seeing if we can get our calculations to run faster.

As a reminder, you can get to the other articles and download the code from here: http://www.jeremybytes.com/Downloads.aspx#ConwayTDD.

Ready to be Parallelized
When I wrote the game rule method (in our first article), I kept in mind that I may want to parallelize the code at some point. Here's the method we created:


So what makes this conducive to running in parallel? First, I created this as a static method. This means that the method does not belong to a particular instance of a class; it stands on its own.

Next, the method itself does not modify any state or instance data. The method takes in 2 values (the current state and the number of live neighbors) and returns a new value (the new state of the cell). Since "CellState" is an enum (a value type), this means that the return value is a separate value even if we return the parameter unmodified.

Because this method is an atomic operation that does not modify shared state, we can call this method at the same time on different threads without worry.

The Serial Call
When we process our grid, our current method call processes all of the operations serially -- that is, only one call runs at a time. Here's that code:


I mentioned that I wasn't a big fan of having the nested "for" loops here; and that remains true. But we need the indexers into the multi-dimensional array, so we don't have much of a choice with the way things are set up right now.

The outer "for" loop deals with the rows of our array, and the inner "for" loop deals with the columns. Inside the loop, we get the number of live neighbors for a cell and then get the new state for that cell. Once we have that, we assign it to the same X-Y position in the new grid.

Adding a Parallel.For
My first idea was to take the "for" loops and simply change them to "Parallel.For" loops. This didn't feel right, but I wasn't sure where else to start.

The Parallel.For method takes 3 parameters: the start index, the end index, and a delegate that represents the action to be performed. Since I love lambdas, I used a lambda expression for the delegate.

Here's the code:


This is a bit confusing since we have nested Parallel.For loops. The outer loop goes from "0" to the height of the grid, and we use the variable "i" for the indexer (just like our original outer "for" loop).

The body of the lambda expression is the nested Parallel.For loop. This loop goes from "0" to the width of the grid, and we use the variable "j" for the indexer (just like our original inner "for" loop).

Then inside the body of that lambda expression, we call the code to get the number of live neighbors, calculate the new cell state, and update our new grid.

This Smells Bad
I knew when I was writing this that it was not the right way to go. But let's run some metrics to verify that.

There's no way that we would be able to see the difference by simply running our console UI application. To see noticeable differences, we'll need to call the calculations lots of times. So, I created a new project (called "Conway.PerformanceTest") with a console application to do just that.


This application creates a new LifeGrid using the same dimensions as our UI application. The difference is that instead of displaying results, we call the "UpdateState" method many times in a row (based on the "iterations" variable). And we've added a stopwatch so that we can see how long each of these takes.

The first block has our original nested for loop; the last block has our new nested Parallel.For loop. Here are the results of the run:


(Note: even though the source code says "10,000" iterations, this output shows a run of "1,000" iterations.)

What we can see is that I really screwed up the performance. Instead of taking 285 milliseconds to process 1,000 iterations, the "optimized" version took 485 milliseconds -- almost twice as long.

And I'm not very surprised by this result. The nested parallel loops would end up spinning up a lot of threads. I'm sure that the application spends more time managing threads than doing the actual calculation.

So, we've over-parallelized this. Let's try again.

A Bit Less Parallel
For the next try, I decided that I would only use Parallel.For for *one* of the loops -- not for both. Here's the code for that:


This shows that we have a "Parallel.For" for our rows (the "i" dimension), but we have a normal "for" loop for the columns (the "j" dimension). The result is that we will process multiple rows at one time even though we're processing the columns sequentially within each row.

The results of this are much better:


Now we can see that our original nested "for" loop was 287 milliseconds, and our updated single-level "Parallel.For" loop is 192 milliseconds. So we actually cut off some of the processing time here.

More Iterations
But what happens if we add more iterations? Will we see the same performance difference? Let's give it a try with 10,000 iterations.


The results show us that things pretty much scale. When we do 10 times more iterations, our durations are 10 times longer.

Considerations
What we've seen is that we don't just want to tack "parallel" on to any loop that we have. We have to balance the time it takes to do the calculations with the time required to manage the threads. In this case, since our calculation was quick and easy, we ended up spending more time dealing with threading than we did with our calculations. If our calculation had been more complex (such as finding prime numbers), then it might have made sense to keep the nested parallel loops. But not this code.

Additionally, this code will perform differently based on the "shape" of our grid. We set this up for 25 x 70. This means we have 25 rows and 70 columns. If we to reverse this, then it may be better to set up the "parallel" on the columns rather than the rows.

Finally, we need to look at the other things we are doing inside our parallel loops -- we need to verify that we aren't risking updating the same shared state or risking race conditions.

Inside our loop, we call "GetLiveNeighbors". This deals with instance data: we're looking at the grid to find the neighbors of a particular cell. Then we're counting how many of these neighbors are alive. But we are only reading data here (no updates), so we don't need to worry about race conditions with the data.

Next, we're calling "GetNewState". As we've already seen, this does not deal with any instance data.

Finally, we are setting the cell state in the new grid -- this is where we set "nextState[i, j]". This is potentially dangerous. We are dealing with a shared object here (the "nextState" grid). But since we have the indexers from our loop, we know that we will only update each cell 1 time -- so we don't need to worry about 2 threads trying to update the same array value.

Wrap Up
We need to be careful when we're trying to parallelize our applications. If we're not careful, we may end up making performance worse. One way that we can avoid these problems is to look at the different patterns for parallelizing code. A good resource for this is Parallel Programming with .NET (Jeremy's review). This covers a number of different problem spaces and the techniques that we can use.

This is all just programming by experimentation. And I'm doing this mainly for coding practice -- part of this is exploration, part of this is to try new things, part of this is to find out what doesn't work. This process helps us get a better understanding of how different techniques work so that we can be more effective in our day-to-day programming.

Happy Coding!

Microsoft MVP Summit -- A Great Opportunity

It's no secret that I'm a Microsoft MVP. One of the great benefits of this is the chance to attend the Microsoft MVP Summit in Redmond, WA -- and that's exactly what I did last week.

For non-MVPs, you may have seen tweets and photos of MVPs having a lot of fun, but it doesn't seem like a very substantive event. This is a false impression. The reason is that much of what goes on at the Summit falls under NDA (which is the "non-disclosure agreement" that we all sign), so we're not allowed to talk about it.

What I can say is that there is a lot of cool stuff coming. Fortunately, we'll get to hear about some big things this week (Nov 12 & 13): http://www.visualstudio.com/en-us/connect-event-vs.aspx. This is definitely something to look forward to (and I can't wait to talk more about my favorite stuff after it's announced).

[Update 11/14/2014: If you missed the live event, you can still experience it. The link will take you to recordings from both days. So you can still get in on the announcements and demos.]

What I Like About the Summit
There's a lot of stuff going on at the MVP Summit. MVPs from all over the world converge in one spot for a week. Here are the things that I find most useful about the event.

Talking to Other MVPs
I spend as much time as possible talking to other MVPs. It's great to have breakfast with new people and talk to people from other disciplines. I'm a Visual C# MVP, but I had a chance to talk to folks who specialize in Excel, Access, and Office 365. Hearing about how some people are using Office 365 and Azure to get businesses running in the cloud is really cool.

Also, the MVP community is like a family. There are a couple of folks who I haven't seen since the last summit (mainly people from overseas). And we continued conversations like we were old friends. In addition, I met a lot of new people. And you never know who you might end up hanging out with. I started up a conversation with someone on Monday, and ended up talking again at lunch, dinner, and game nights throughout the week.

(I won't list all of the people I talked to because I'm afraid of leaving someone out. I had good conversations with probably about 30 people and had shorter encounters with about a dozen more.)

Talking to Microsoft Folks
Another great part of the event is talking to people from the various product groups at Microsoft. One of my MVP friends set up time to talk to people from product groups that he doesn't normally interact with. He did this because he had some concerns about particular behavior in a product. Since everyone is all in one spot, people from the product teams are open and willing to meet with you.

And this is very interactive. The people from the product groups really want to hear what the MVPs have to say. They see us as a primary conduit to the community at large, so they value our opinions -- whether it is talking about new language syntax, how a new feature is exposed in Visual Studio, or concerns about a proposed technology.

I won't give any specific examples because I'm not exactly sure what's under NDA and what's not at this point, and I tend to error on the side of caution.

Hearing About New Stuff
And speaking of NDA, we also get to see a lot of preview stuff at the Summit. These are the things that you might hear MVPs get excited about but can't say anything. (You might have seen a lot of people recommending the Microsoft Connect event on Nov 12 & 13 -- http://www.visualstudio.com/en-us/connect-event-vs.aspx -- There's a reason for this.)

There's big stuff coming, and Microsoft gives us a "head start" so that we can be ready to start blogging, shipping code samples, and talking about the new stuff as soon as it is publicly announced.

Wrap Up
I'm honored to be a Microsoft MVP. It's awesome that Microsoft has this program to recognize the people who are active in the community (for me, it's the developer community, but there are communities around other products as well).

The MVP Summit has given me access to meet MVPs from around the world, make a lot of new friends, talk to the folks at Microsoft who are making decisions on the next versions of products, and learn about what's coming soon.

And even though you only see the "family reunion" parts on the public side, there's a lot more going on that we're not allowed to talk about. For MVPs, it's an opportunity not to be missed.

Happy Coding!

Sunday, November 2, 2014

Adding a Simple UI for Conway's Game of Life

In a previous article, we created a rules library for Conway's Game of Life (code download). This was just the rules for whether a cell lives or dies based on its neighbors. But we did not implement any type of UI. That's what we'll do here.

The Rules
As a reminder, our rules engine consisted of a single method:


This takes the current state of a cell and the number of live neighbors that it has. But this doesn't tell us anything about the grid of cells or the state of that grid. For that, we'll need to create a new object.

The Grid
So, I added a new class to the Conway.Library project called "LifeGrid". Here are the fields and constructor:


I made some tough decisions here. I don't like the idea of dealing with a multi-dimensional array (If you know anything about me, you know that I love generic lists). To make things easier to start out with, I hard-coded the dimensions of the grid to 5 x 5.

The reason that I have a "current state" and "next state" is to make it easier to run the rules. When we get the rules for a single cell, it depends on the current state of all of it's neighbors (8 neighbors in our case). That means we can't change the state of any of our cells until after we've processed the rules for all of the cells. We could do this by taking a snapshot, but I decided to create "current" and "next". You can think of this as similar to the way that we used to double-buffer graphic animations to make them faster to load.

After instantiating both of our states, I initialize the current state to all "Dead". (An easier way might have been to flip the enum so that "Dead" comes first (i.e. position 0). That way it would automatically be in that state when it's instantiated. I expect to do a lot of refactoring of this code, so I might end up doing that later.)

Running the Rules
With the grid in place, we need to run the rules on all of the cells. Here's our method for UpdateState:


For this, we loop through both dimentions of our array. This is one of the reasons I don't like dealing with them. The nested "for" loops rub me the wrong way. Inside the loop, we get the number of live neighbors for the current cell (we'll look at this method in just a bit). Once we have that, we can call our GetNewState method that we created before. Once we have that result, we can assign it to the same position in the "next state" grid.

After completing the loops, we assign the "next state" to the CurrentState property. This replaces the old values with the new values. Then we create a new instance for the nextState variable.

Getting the number of live neighbors for each cell is an interesting problem.


I'll admit that I haven't looked up other implementations of Conway's Game of Life for this coding session. That's because I wanted to try to figure things out and then optimize as needed.

There are a lot of nasty conditionals here. The method takes the X-Y coordinates of the current cell. Then it has nested "for" loops to go through the cells to the left, right, top, bottom, and diagonals. It does this by subtracting 1 and adding 1 to the current position.

But we have a problem. These "for" loops will hit the current cell. We want to skip this, which is why we check for "i == 0 && j == 0".

The next trick is that we need to make sure that the neighbor cell is still on the grid. So we check to make sure that the X-Y values are greater than 0 and less than 5 (our current grid size).

Once we've validated that we're looking at a cell that is a neighbor of the current cell and not off the grid, we check to see if it is alive. If so, we increment our liveNeighbors count. Then we just return the total when we're done.

This completes the implementation of our grid. We'll make a few adjustments to it so that we can have an arbitrary size, but this is enough for us to hook this up to a UI.

Creating a Console UI
We're going to start out pretty simple: we're just going to hook up a console application to our grid. This will output the cell state as dots or Os. To create this, I just added a new project to our solution called "Conway.ConsoleUI". As you might imagine, this is a console application. Then we just need to add a reference to our Conway.Library project.

Here's our console application:

For this, we create an instance of our LifeGrid class. Then we set some cells to a live state (since they default to all dead).

After that, we show the grid (and we'll see this method in just a bit). Then we have a while loop hooked up so that we can update the grid every time we press the Enter key.

Here's how we show the grid:


I was able to get away with not using nested "for" loops. This is because we don't care about the position of the cells, we just need to print them out. We're going to output a character for each cell, and then we just need to put in a line break when we reach the end of the row.

I did brute force this. The "x" variable keeps track of our current column. When we reach the end, I reset "x" and then output a line break.

Visual Verification
Up to this point, we really don't know if anything will work. Let's run the application to see what we get:


And when we press "Enter":


And if we keep pressing "Enter", we'll see these states alternate. That's good. This is a "Blinker" (Conway's Patterns).

Arbitrary Grid Size
Our next step will be to allow for an arbitrary grid size. This isn't all that difficult. For our LifeGrid class, we just need to add some field to hold the state. Then we update anywhere we have a "5" to the appropriate field.

Here are the basics:


The constructor now takes parameters for the height and width. These values are used to initialize the grid.

And these values are used in the UpdateState method as well:


So, not a whole lot of work.

The console application takes a little more work. First, we update the Main method to pass in the grid size (we'll stick with 5x5 for now):


And then we need to update our ShowGrid method:


This is little more interesting because we need to know the length of the row (to put in our line break). Instead of using "5", we check the array. We get the upper bound of the array and add 1. This is because our 5x5 grid would have an upper bound of "4", and we want to have the same row length value that we had before.

When we run the application, we see the same output:



So let's make a bigger grid.

A Bigger Grid
Since we have an arbitrary grid size, we can make it bigger by just changing our Main method:


And here's the output:


It looks like we have a problem. Our grid is going the wrong way. It turns out that there's a problem with our "ShowGrid" method. Here's the fix:


Before, we were checking the upper bound of dimension "0" (which happens to be our height). Instead, we should be checking the upper bound of dimension "1" (the width). We didn't run into this problem earlier because we were using a square grid -- both dimensions were the same.

With this update, we get the output we expect:



Adding Randomization
Making a bigger grid isn't really all that interesting. If we have to manually set the initial state, it could get pretty tedious. What we'll do instead is create a randomization method that we can run on our grid.

To make this easy to call, I added this to the LifeGrid class:


This loops through our grid and sets Alive/Dead values based on an random number.

Here's our updated Main method:


We just call "Randomize" after we create our grid. And here's the output:


And here's Generation 2:


And Generation 5:


And Generation 15:


Eventually this settles down into one of the static states: items that don't move or patterns that repeat.

Output Optimization
Let's try this with a larger value. Let's try 25 x 65. Here's the output after several generations:


The output is interesting, but there's a problem. This is slow. For small grids (like our 5 x 5), the display was instant. When we press the Enter key, there's no delay when the new grid shows up.

But on the larger grid, there's a definite re-draw that is apparent. And this ruins the illusion of watching Conway's Game of Life. The fun part is to watch generations go by quickly and seeing the patterns evolve. When the screen redraws from top to bottom, there's a break in that flow.

But we can fix this by changing the way that we're displaying our grid. As a reminder, here's our current ShowGrid method:


This calls "Console.Write" a lot -- once for each character. For a 5 x 5, that's only 30 times (including the new lines). But for a 25 x 65 grid, that's 1,650 calls.

So we'll minimize the number of times that we call "Console.Write". In fact, we'll only call it once:


All we've done is add a StringBuilder. Instead of directly writing to the console, we add the characters to the StringBuilder. Then at the very end, we call Console.Write one time.

This makes our display much faster. When pressing the Enter key quickly, there's no perceptible redraw (at least on my i7 laptop). If we hold the Enter key down, then there is some flicker, but this is definitely acceptable for what we have.

More to Add
Now we have a working application that displays Conway's Game of Life in action. But we're not done yet.

Back when I created the original rule method (GetNewState), I was thinking that this problem (recalculating all of the states) would be a good candidate for parallelization. And that's why I wrote the method the way that I did:


I created this as a static method: that means that we're not allowed to interact with any instance objects that are part of the class. The result is that we don't modify any shared state in this method (good). Next, since CellState (the type of our return value) is a value type, I don't have to worry about accidentally modifying state of the parameters. We will always get a new copy of the value (even if we don't change it in the method).

This means that if we run this method on different threads with different parameters, we don't have to worry about them interacting with each other.

But to take advantage of this, we'll need to make some changes to how we are updating the state in our LifeGrid class. We'll explore this in a future article.

In addition, I'd like to support some different UIs (like a WPF or Windows Phone application) that we could make a bit prettier.

Wrap Up
In implementing the UI for Conway's Game of Life, we had to take a look at how we are storing the grid data, how we update it, and how we display it on the screen. As mentioned, I'm not a big fan of having the nested "for" loops in so many methods, but we may be able to take care of that as we look at things further.

It's always good to practice our craft. Sometimes that means taking a well-known problem and implementing our own solutions (even when there are lots of implementations already). This lets us focus on things that we care about (such as parallelization) and also work our way out of problems that we might create for ourselves.

Practice is how we get better.

Happy Coding!