Tuesday, April 25, 2017

Implementing a Fibonacci Sequence with Value Tuples in C# 7

I decided to do some experimentation with the Fibonacci Sequence. I wanted to see if I could implement it with value tuples in C# similar to the way that I had previously done with F#. And I wanted to see how similar or different they are.

Previously, I implemented a Fibonacci Sequence in C# by TDDing into the code. The code is pretty imperative, but the readability is okay (it could be better):


Even better, we have a set of passing unit tests. So we can safely do experimentation and know when we've messed something up.

Note: you can grab the code for this article on GitHub: jeremybytes/fibonacci-tdd. Both the TDD and value tuple steps are included as branches.

The Idea (from F#)
Here's the idea: last year I worked through the first 10 Euler problems to learn F# a bit better. In particular, Euler #2 uses the Fibonacci Sequence. The implementation that I ended up with used tuples, and I wondered if I could use the C# 7 value tuples to create something similar.

Here's the code from the F# implementation (you can see the whole thing here: Functional Practice: Euler Problem #2 in F#):


This uses a "fold" which runs the specified function for each item in the list and hangs on to an accumulator value. In this case, the accumulator is a tuple that is initialized to "(0,1)". Then for each item in the list, it will create a new tuple consisting of the second value of the original ("b") and the sum of the first and second values ("a + b"). For a deeper dive, check out that article.

My implementation in C# will be a little bit different from this. First, this function gets the "nth" Fibonacci value. So if I call this function "fibonacci 4", it will give me the single value of "3". Instead of returning the "nth" value, we want to create a sequence that iterates through all the values (and yes, the F# article does describe that a little later, but we'll take things one step at a time).

Switching to Value Tuples
Rather than using a "fold" (or the LINQ version "Aggregate"), we'll stick with the "while" loop to return the values as they are requested. But we still want to use the same type of tuple for the accumulator.

So the first step is to create a tuple variable that we can initialize to "(0,1)":


As mentioned in a prior article, we cannot simply use a value tuple out of the box (even though we're using Visual Studio 2017 and C# 7). The feature has to be brought in through a NuGet package. I'm still not happy about how this works today. As Thomas Levesque pointed out in the comments, the release order is kind of out of whack. Welcome to the new world.

Anyway, we just need to bring in the "System.ValueTuple" package:


And everything works:


One slight difference is that we have the initial values noted as "0L" and "1L". This tells the compiler that we want to use the "long" integer type, and it will create the correct tuple with 2 long values.

Now we just need to do the same math as in the F# function and return the result:


Just like the F# "fold" function above, we create a new tuple where the first element is the second element of the previous value, and the second element is the sum of the first and second elements.

Then we return the first element of the tuple (which is what the "fst" function does in the F# code).

The good news is that all of the tests still pass:


Great! That means we have a working implementation.

Improving Readability
The readability of this is not great. One thing we can do is give our tuple elements names. We'll use "current" and "next":


This makes it a little bit easier to keep track of the elements in our tuple. And it's also clear that we're returning the correct value "current".

And importantly, all of our tests still pass:


Is This Better?
It's great that I got to experiment some with value tuples (and sad that I ran into the issue trying to use them initially). But is this a better implementation?

Let's look at them side-by-side:

Original Implementation

With Tuples

Neither of these implementations is particularly readable. The original version suffers because we're using the previous, current, and next variables and swapping them from place to place. It's a bit confusing to figure out exactly what's happening.

The tuple version has kind of the same problem. We have eliminated one of the variables so now we only have two (current and next), but we're still doing a swap and math that isn't real clear.

Wrap Up
The fun thing about experimenting is that you're never quite sure what you'll find. In this case, it's interesting that we can implement the Fibonacci Sequence fairly easily using value tuples. But I don't think we've improved readability much. Less code is often good, but not if it obfuscates things.

I think I'd have to call these implementations a "draw" in their current state. They both have similar readability issues. But that just means that we can do some more experimentation to see what we can come up with.

Happy Coding!

Thank You, Linda Rising

I recently looked back at the impact that Linda Rising has had on my career and life, and I wanted to express my gratitude for that.

I first heard Linda on the Hanselminutes podcast back in 2013: The Agile Mindset with Linda Rising. Listening to her describe the agile mindset compared to the fixed mindset really opened my eyes. I immediately watched a recorded keynote called "The Power of the Agile Mindset" (the link I had to that is sadly no longer working).

The short version: With the fixed mindset, we have a certain potential that we can reach for any particular area. This leads to "I'm good at this; I'm not good at that." With the agile (or growth) mindset, we can get better at whatever we put effort into. This leads to "I can learn to be better at this."

This clarified some of my observations and led to quite a bit of self-reflection. (Here's the long version if you're interested: Fixed vs. Agile Mindset.)

Initial Realizations about Others
When I heard this concept, certain things immediately started to make sense. For example, there was a development team where the managers refused to invest in the developers. Instead, they were constantly looking for the process or tool that would make the team successful. This always frustrated me to watch, but I realized that the management had a fixed mindset toward their team: "Our developers are as good as they are going to be, so we need to look for solutions elsewhere."

I've always had the opposite opinion about developers. And fortunately the team that I joined when I was a brand new developer believed that as well. With the agile mindset, there wasn't anything that we couldn't learn. We were constantly building each other up and making each other better. I know that my situation was fairly unique, but I really wish that all junior developers could have such a productive environment.

And since I'm a speaker, coach, educator, Developer Betterer, I obviously have this mindset toward the developers that I'm teaching. And I don't think of it as teaching most of the time, I think of it as helping people past the hurdles that I had trouble with when I was learning a particular topic.

Initial Realizations about Myself
The real eye-opening moment, though, was when I started to reflect on myself. I found that I had the agile mindset in some areas and the fixed mindset in others. For example, when it came to technology, I was pretty confident that I could learn whatever I put my mind to. But that wasn't true of all areas of my life.

When it came to things like music, I thought of myself as "not a musical person". On reflection, I came to realize that I had never put any real effort into it.

I had a few more realizations that you can read about in my original article: Fixed Mindset vs. Agile Mindset.

Changing My World
I decided to get over my hurdle with music. So, I bought a banjo in January 2015. And I set about to learn to play it. And I made progress.

But more importantly, I was able to use the banjo as an object lesson for others.

Learning Something New
First, I did something I never would have done before: I played a musical instrument badly in front of other people. There was a time in my life when I would never think about playing for others unless I knew the piece perfectly. But now I'm okay with showing that I'm not an expert and that learning takes time: You Aren't Instantly Awesome, and That's Okay.

This has been a great way to talk about learning in our industry. As developers, we're constantly having to learn new things. And it's really easy to feel inadequate when there are so many people who already know this new thing. But we all have to start somewhere, and everyone has to go through that same learning process.

Getting Better
The good news is that I tracked my progress with the banjo. And I did see actual progress: You Aren't Instantly Awesome, But You Can Get Better with Practice.

What this proved to me is that I am a musical person. And I can get better when I put the effort into it.

Getting Help
Another thing I learned is that once I dropped the fear of being imperfect, I was no longer afraid of asking for help from the experts. Again, specifically with the banjo, I was able to get help from a former professional player and from a professional music instructor. (Read more about that here: Don't Be Afraid to Show What You Don't Know.)

In the technical world, I've never been afraid to ask for help. But by going through this experience, it reinforced the idea that there's nothing to be ashamed of when you don't know something. I like to try to figure things out on my own, but I have no trouble asking for help when I get stuck. And this has led to some great learning experiences (particularly from the functional programming community which is so willing to help out).

Unfortunately, our industry has a general fear of showing weakness. I'm trying to promote the fact that no one knows everything, we all have our strengths and weaknesses, and we all have to start somewhere. I would love to see that fear disappear.

Giving Help
The extension of this is that I'm not afraid of giving help when asked. I don't think that I've ever really had this problem personally, but there are some known problems with this in our industry.

So I encourage other people to help the people they can. And there is always someone who knows less than we do, someone who has not had the same experiences that we've had, someone who has not yet struggled through the things we've struggled through. So whatever level we're at, we have something to share. Please, Help Those Behind You.

Thank You, Linda
I can trace a lot of this back to hearing Linda Rising talk about the ability that we all have to learn and improve when we put effort into it.

Thank you, Linda, for opening my eyes to a topic that I've been able to use to better myself and better those around me. I knew that this had an impact on me, but looking back, I see just how much of an impact it has had. Over the course of 3-1/2 years, the idea of learning and getting better at whatever I put my mind and energy into has given me opportunities and helped me make the world a better place.

Monday, April 24, 2017

TDDing into a Fibonacci Sequence in C#

A few days ago, I mentioned how I wanted to do a bit of experimentation with a Fibonacci Sequence implementation. Before I did my experimentation, I wanted a working sequence and a set of tests to validate that. This way I would know if my refactoring broke something. [Update: here's some of that experimentation.]

So let's TDD into a Fibonacci Sequence. You can grab the code from GitHub: jeremybytes/fibonacci-tdd. There are branches to go along with each step.

Initial Project
For the initial project, I created a console application and a class library to hold my tests. I figured that I could put my Fibonacci sequence class in the console application and then move it to its own project if needed.

We'll basically be looking at 2 files. The first is "FibonacciSequence.cs", and (as mentioned) this is in the console application:


Then we have the test, "FibonacciSequenceTests.cs":


Since we're going to be writing tests to make sure we've got the sequence right, I included the first 12 Fibonacci numbers. If you're not familiar with the Fibonacci sequence, each value is determined by adding the previous 2 values. So the 6th value (8) is determined by adding the previous values of 3 and 5.

The First Test
So let's write a test for the first element in the sequence. But before we do that, I'm going to do a bit of setup.

Since I want this to be a sequence (which means IEnumerable in the C# world), I'm going to stub out the interface in our production class:


I know that this is writing code before tests. But since we know we want a sequence, it makes sense to give ourselves a framework to hang our code on. Notice that even though I've added the code for the "IEnumerable<int>" interface, we haven't included any implementation. We'll write our test first.

And here's the first test:


This creates an instance of the sequence, pulls the first value, and then checks to see that it's "1".

This tests fails (as expected):


The reason for the failure is the "NotImplementedException" that gets thrown by our class.

So let's write the very simplest code possible to get this to pass:


The "yield return" will create an enumerator for us in the background so we don't have to deal with it explicitly. For more information on IEnumerable, you can check out this article series: Next, Please! A Closer Look at IEnumerable.

This code is a bit too simple. We know that it doesn't really fulfill our sequence needs. But it does get our first test to pass:


So let's move on to the next test.

Testing the 2nd Element
Now that we've got things set up, it should be easier to write additional tests. Lets set up a test for the 2nd element in the Fibonacci Sequence:


Testing the first element of a sequence is easy. Testing the second element is a bit trickier. What I did here was use the "Take" method (one of the awesome LINQ methods) to grab the first 2 items of the sequence. Then I take the "Last" value.

But there's a problem with this test. It passes:


Yikes. That's not good. When doing TDD, I expect the test to fail until I add proper implementation code. So what's the problem?

The "Take" method will grab up to the number of values requested. In our case, the sequence only returns a single item. But "Take" doesn't care; it grabs as much as it can. Then when we ask for the "Last" value, we end up getting the only one that's there, which is the first value.

Correcting the Test
When we have a test that passes when we expect it to fail, we've either got a problem with our code or a problem with our test. In this case, the problem is with our test. "Take" is not the appropriate LINQ method to use here. Fortunately, there's another LINQ method we can use: "ElementAt":


One thing to keep in mind is that "ElementAt" uses a 0-based index. So using "1" will get us the 2nd item in the sequence.

Now our test fails:


This is better. The reason for the failure is that there is no 2nd item so "ElementAt" throws an exception.

For this implementation, we'll do something very simple:


I'm feeling like this is too simple still. But I'm also thinking that we can get a little more info to let the method take shape a little more naturally before we think about refactoring.

This is enough to get the test to pass:


So let's keep moving.

Testing the 3rd Element
Next we'll write a test for the 3rd element, which we expect will be "2":


This test fails (as expected), so let's write a bit more code:


This gets our test to pass, but it's kind of stupid to keep writing the method this way. So, I'm going to to a bit of refactoring.

Refactoring to Something a Bit More Useful
Since I see a little bit of a pattern forming here, I'm going to add a "for" loop to the implementation:


I know that this won't work for the entire sequence. But it works for the tests that we have in place right now. We'll worry about fixing this in a bit, but not until our test cases call for it.

Parameterizing the Tests
It looks like we're writing the same test over and over again. This is where I look to see if we can parameterize the test. In this case, I think it will work pretty well.

Here's a new test:


I'm using NUnit, so I can set up test cases that get passed in as parameters. For more information, take a look at this article: Parameterized Tests with NUnit.

This will plug the values of the TestCases into the parameters of the test. So in the first case, it will use "0" for the "ElementAt" call (which is the first item in the sequence) and it will use "1" as the "expected" value in the assertion.

This lets us test the first 3 elements of the sequence with a single test. And our results show the tests are passing:


Notice that the results show the parameter values plugged in. This is really useful when one (or more) of these test cases fail.

Testing the 4th Element
Testing the 4th element of the sequence is as simple as adding another test case:


This test passes without any changes to our code. And that's okay. We expect the 4th element is "3", and that's what our code returns.

It's interesting to see that the simple "for" loop that we built in the code works for 3 elements in the sequence. But we'll see it break down with the next element.

Testing the 5th Element
Adding the test case for the 5th element creates a failing test. I won't show a screen shot, but the test just has "TestCase(4,5)" added.

Now we have to do a bit of math to really implement the Fibonacci Sequence:


Like the description of the Fibonacci Sequence, I add together the previous two values. A couple of local variable hang on to those values so they can be used to calculate the next item.

With this in place, all of our tests pass.

Refactoring
The tests are passing, but I see some dead code in the implementation. We are no longer using the indexer of the "for" loop. Since we don't need the indexer, we can swap the "for" loop for a "while" loop:


I'm never a huge fan of "while(true)", but it is a good way to create an infinite sequence.

The First 12 Elements
Since we've implemented the definition of the Fibonacci Sequence, we would expect that additional tests would pass. I set up the test cases for the first 12 elements:


And all of the tests pass:


Yay!

But there's a problem.

Overflow!
I've done a lot of experimentation with the Fibonacci Sequence. (I'm not sure why it intrigues me so much.) One thing I know about it is that it will overflow a 32-bit integer pretty quickly. How quickly?

Let's set up the console application to find out. We'll add code to our console application to print out the first 50 values of the Fibonacci Sequence.


And here's the output:


As we can see, something weird starts to happen at item #47. We overflow the standard integer and end up with a negative number (since the default 32-bit integer is signed).

Testing for Overflow
Now that we know where our problem is, we can create a test for it.


This test grabs elements #46 and #47 (remember, "ElementAt" is 0-based). Then we check to make sure that #47 is greater than #46.

Since this is the pivot-point of the 32-bit integer, element #47 give us a negative value, so it is *not* greater. This means our test fails.

Fixing Overflow
To fix the overflow, we'll change from using "int" (a 32-bit integer) to using a "long" (a 64-bit integer). The code is fairly easy to update at this point.


There's also one change we need to make in our tests. The "expected" parameter type needs to be changed to "long".


With this in place, we now have all of our tests passing (including the one that checks for overflow):


And we can see our console application is behaving as expected as well:


Wrap Up
This code isn't perfect. Our implementation returns an infinite sequence (because of the "while(true)"). But even our updated code isn't infinite. After a while we'll overflow the 64-bit integer as well. So we should probably add some checks in the code for overflow and end the sequence. But I'll leave that as an exercise for you.

We've reached our goal which is to have an implementation of the Fibonacci Sequence with a set of valid tests. Now that we have this in place, we can do some experimentation with the implementation.

And with the tests in place, we'll know immediately if our experimentation breaks something. In an upcoming article, we'll look at those experiments. [Update: here's a bit of that experimentation.]

Happy Coding!

Thursday, April 20, 2017

Recordings from NDC London

I had a great time speaking at NDC London back in January. I wrote a bit about it soon after the event.

The good news is that the recordings of my presentations are now available. So if you missed the event (or just want to experience the talk again), here's your chance.

And if you'd like to see more from NDC London, keep an eye on their YouTube channel playlist: Playlist: NDC London.

Get Func-y: Delegates in .NET
Watch it on YouTube, or watch it here:



Focus on the User: Making the World a Better Place
Watch it on YouTube, or watch it here:



My schedule is filling up for the rest of the year. I'm looking forward to lots of events and meeting lots of great people.

Happy Coding!

Wednesday, April 19, 2017

Value Tuples in C# 7: Please Tell Me I'm Doing This Wrong

I really need someone to tell me that I'm doing this wrong. Because what I found is that I need to install a NuGet package in order to use a C# language feature.

The Discovery
I was doing some experimentation last night, and I decided that I would try to use value tuples, a new feature in C# 7. (Long story short, I was trying to implement a Fibonacci sequence in C# using a more declarative approach (similar to what I did in F# last year).)

So I fired up Visual Studio 2017, got a working implementation going with TDD (I'll write about that in a future article here: TDDing into a Fibonacci Sequence), then I went to refactor it to use a value tuple.

As a first step, I created a local variable:


That's when I ran into a problem. Red squigglies? I double checked the docs online to make sure I was using the right syntax. Yep.

Here's the build error:


Great. Now what? "System.ValueTuple" doesn't show up in my available assembly references (and yet, somehow the compiler knows about it).

Looking at the Microsoft docs (https://docs.microsoft.com/en-us/dotnet/articles/csharp/whats-new/csharp-7#tuples), I came across this note:


But I'm not using a Preview. I have the release version of Visual Studio 2017 (Version 15.1 (26403.7) Release). Surely I don't need a NuGet package.

But the only way I could get this to work was to install the NuGet package:


After installing this, my tuple started working fine:


The Environment
  • Visual Studio 2017 Enterprise (Version 15.1 Release)
  • .NET Version 4.6.2
  • Windows 10 (who knows what actual version, not the Creator's Update)
Please, Please, Please
I really need someone to tell me that I'm doing this wrong. Do I really need to install a NuGet package to use a language feature?

If I need to install a package, is it really a language feature? Or is it just another library.

[Update: The package is not needed with .NET 4.7. But as of today, .NET 4.7 (and the ability to target it in Visual Studio) is *only* available for Windows 10 Creator's Update.]

I am not connected to the internet 24 hours a day. And when I am, I don't always have a high speed connection. I already find myself going back to Visual Studio 2015 periodically just because I have local help installed there.

[Update: As of 4/19, local help is available for VS 2017: New Offline Books for Visual Studio 2017, although I've had a few curious issues with it so far.]

Visual Studio has been a really awesome development environment. But I find it harder and harder to develop with Visual Studio 2017.

So, please tell me that I'm doing something wrong. I want my peace of mind back.