Wednesday, October 6, 2021

Learning on Innovative Teams

I've been reading the book Failure is Not an Option by Gene Kranz. Gene Kranz was the flight director for the Apollo missions, and came up through the Mercury and Gemini missions.

I recently read about the start of the Gemini program. At that period in history, NASA was building out its command center in Houston, re-locating the staff from Langley to Houston, and advancing the space program. The Gemini program was introducing more computers and automation than the Mercury program, along with being two-astronaut missions that were lasting significantly longer than any Mercury flights. The ground crews were having to learn new capsule systems, new launch systems, new computer systems, new networking and communication systems, etc. There was a lot of change and growth happening at that time.

The statement that resonated with me was how the ground crews brought new information into the team. Each controller (or set of controllers) was sent to learn about their specific systems of specialty. Many of them travelled to the manufacturers or labs where equipment was being created. When they came back to mission control in Houston, they taught the other controllers what they learned! It struck me that one of the most innovative groups in history had a culture of continuous learning and making others great.

The lesson I took from this passage is that innovation comes from learning and sharing what one has learned. Gene Kranz is clear that there was nothing perfect about how they got things together, but the team's desire to grow and learn was able to drive some incredible advances!

Tuesday, September 22, 2020

Spot the Bug - FOR Loops

The next bug in the Spot the Bug series is one that is seen quite often from new programmers. Can you spot the bug?

This code contains a class that adds two 2x2 matrices together. The class also includes a print method for displaying the matrices in the console. The main program passes in two sample matrices to add together. The bug in this code is that the indices in the AddTwoMatrices method are flipped for the additionalResult object.

This bug is common with new programmers. Unfortunately there is no C# language construct to prevent us from creating this kind of bug. I've included it in this series because it presents a great conversation for a mentor to have with a new developer about programming techniques that can be employed to lessen the chances that a bug like this gets released.

The first thing I would highlight is that this code needs unit tests. Math operations are straightforward to test because they should be operations that have no side effects. The code doing the math operation should also be pure, meaning for the same set of inputs, it always produces the same output. These conditions make unit testing math methods straightforward and these methods should always have accompanying unit tests.

The other thing I would highlight here is that better variable naming may make it easier to see the bug when it does get introduced. (Generally speaking, I don't mind simple counter variables like these in FOR loops being single-letter variables.) More descriptive variable names for the loop counters will make it easier to read the code and reason about the code, making it easier for a developer to see a problem as it is being introduced.

Here is the code with the bug corrected and more descriptive variables to make it more readable.

Even though C# doesn't provide mechanisms to prevent this type of bug, there are some good programming techniques that can be taught and discussed when bugs like this arise.

Friday, September 11, 2020

Spot the Bug - File Globbing

The bug in this post comes from the world of scripting. Powershell is used for the code below, but this bug could be introduced in any scripting language that is commonly used for task automation. Can you spot the bug?

The code above is a fairly straightforward script. It gets a list of files from fileDir, iterates over each file moving it to two different locations. After looping through the files, it removes the files from fileDir.

The bug in this script is that the removal of the files is done using a wildcard to locate the files to delete. If the number and size of the files being moved is large, the iteration over each file will take some time. New files can be placed in fileDir and those files will be deleted by the final script line using the wildcard. If that scenario happens, data can be lost!

In the code above, the bug is fixed by deleting files by file name as a part of iterating over the list. This approach ensures that you only affect files discovered in the first line of the script, and newly arriving files can't be accidentally deleted.

This example had to be done in Powershell because the C# libraries for working with files and directories don't allow the use of wildcards, therefore preventing a developer from creating this bug. This is another example of the language construct preventing developers from introducing bugs.

Friday, September 4, 2020

Spot the Bug - Using Statement Part 2

I introduced the "Spot the Bug" exercise previously. This is the next bug in the series.

Below is a class named DataWriter. This class is responsible for opening a file, closing a file, and writing data to a file. Below that class is a console program that exercises the DataWriter class. Can you spot the bug?

In the console program, I forgot to call the method to close the file. This is another example of the using statement in C# protecting us from creating code like this example. In the previous example, we saw a similar bug where it is very easy for the developer to forget to close a connection or file handle, using up precious resources. The using statement isn't a perfect solution, but it does push the developer to keep responsibilities grouped appropriately and it ensures that the garbage collector can do some amount of cleanup in the system when resources are no longer needed.

Below is code that represents a better solution.

The code above uses the using statement to handle the opening of the file. The developer is still responsible for closing the file, but the using statement will make sure that the StreamWriter object is disposed.

The other thing to notice in the better code example is that the DataWriter class was completely eliminated. Because the DataWriter class split up the file writing responsibilities too granularly, once those responsibilities were merged back together, the class was no longer necessary. This example highlights the fact that sometimes our designs aren't quite right, and we shouldn't be afraid to remove classes if they aren't necessary.

Monday, August 31, 2020

Accessing Config Data in Azure Functions with F#

I've been building an application using Azure Functions with F# as the API backend. The Azure Functions access data in Azure Storage to return to a single page web application. For development purposes, I've had the connection string hard-coded in the F# files that needed it. I'm at a point where I need to start deploying this app in a production manner, so I need to get the connection strings out of my code. The documentation for Azure Functions recommends using environment variables in production, and the local.settings.json file for development. Reading these values should have been trivial, but wasn't. This post documents how I was finally able to read data from environment variables.

Most of the documentation that I was able to find online pointed to using the Environment.GetEnvironmentVariable("myData") syntax. I was absolutely unable to get this call to work for me in my F# function. Fortunately I'm a member of the F# Slack community. I reached out for help on this issue, and Zaid Ajaj gave me a few things to try. This experimentation led to the solution below:

In the function above, I create a new ConfigurationBuilder instance and configure it for my app. To properly configure it, I needed to include another parameter for the function call, (context: ExecutionContext). This parameter gives me access to the runtime directory with the property context.FunctionAppDirectory. This allows me to then inject the local.settings.json file. (Note the boolean value true in the call to AddJsonFile. This true indicates that this file is optional, which is necessary in a production setting when this file will not exist.). Once I build the ConfigurationBuilder, I'm able to access local settings and environment variables using the array accessor syntax, config.["BoogyMan"].

I'm not sure if this is the "approved" Microsoft way or the best way to read environment values in an F# Azure Function, but it does work. If there is a better way to to this, I would love to see it.

Friday, August 28, 2020

Spot the Bug - Using Statement Part 1

Several months ago, I was reviewing some C# code of one of my teammates when I realized there was a subtle bug in the program. The bug was not easy to see right away. I realized that C# had certain constructs in place to make it difficult to create bugs like this. These constructs are great, but they mask certain design principles and make it possible to learn programming without learning the underlying design principles. I reviewed the bug in question with my team during a code review and made it kind of a game to find the bug and talk about the underlying design principles.

I did a talk titled "Spot the Bug" for the Code PaLOUsa conference last week. The talk was geared for two primary audiences. The first audience is developers that are earlier in their career. This audience benefited from this talk in seeing common coding mistakes and learning some common design principles. The other audience for this talk was developers later in their career or developers in positions to mentor others. This audience was shown an approach for highlighting some of these common mistakes and seeing ways to address them with their creators.

This is the first topic that I covered in the talk.

Below is a class to access a database. It has methods to open and close the database connection as well as a method to work with the data. Can you spot the bug?

Most C# developers are looking at the code above and thinking to themselves, "Why didn't he do this with a using statement?" These developers are absolutely right. The bug in the code above is that the DataGatherer class separates the responsibility of managing the database connection between two different methods, effectively forcing the developer that uses this class to be responsible for doing things correctly.

The using block in C# forces a developer to keep the responsibility of opening and closing database connections in the same code block, mostly ensuring that the right things are done in regards to the database connection. (It is still possible for a developer to forget to close the database connection within a using block, but the using block will force the connection closed and dispose of the connection. It just may take the garbage collector longer to get to it.)

The better code is below:

You'll notice in the better code that there is a lot less code! Keeping the opening and closing responsibilities together inside the using block, reduces the amount of code in the class and creates a much better program.

This subtle bug is easy to overlook if you learned to work with a database after the creation of the using construct. The using construct is a way to talk to new developers about class and method responsibilities and the need to keep similarly oriented responsibilities together.

Tuesday, August 11, 2020

Moving to Functional Thinking

I've been working on an educational-based site to help teachers evaluate students. I'm using F# for the backend API, and the regular use of a functional programming language has me thinking differently about how I code.

I recently needed to test a value to see if it is a GUID. If the value is a GUID, I want to use it. If the value isn't a valid GUID, I want to create a new GUID. In C#, this would be done like this:

if(Guid.TryParse(maybeGuidValue, out validGuidValue)
{
 myObject.ID = validGuidValue;
}
else
{
 myObject.ID = Guid.NewGuid();
}

This code is fairly straightforward, but a little problematic. First, the TryParse() method takes a string to test, maybeGuidValue, and an out parameter. If the method succeeds, meaning, the value is a valid GUID, the method returns true and the value validGuidValue is populated with the value in a GUID data type. If the value passed in is not a GUID, the method returns false and the out parameter should be ignored.

This code is tried and true in the C# world, but it isn't great. First, I'm not a fan of out parameters. This code construct is not pure or immutable since the method is returning one value as part of the method call and mutating another value by sending back an out parameter. Code like this requires special attention and is difficult to wrap in good unit tests.

In contrast, F# handles the same concept in a more intuitive manner. The code to TryParse a GUID looks like this:

let didParse, validGuidValue = Guid.TryParse maybeGuidValue
let ID = if didParse then validGuidValue else Guid.NewGuid()

This code calls the same TryParse method that is used in the C# code (F# shares the .NET libraries). Instead of having a single return value and an out parameter, this function returns a tuple with the boolean result of the parse operation along with the possibly populated GUID value. This construct is easier to see and much easier to unit test! The other obvious difference in the F# code is that it is only two lines! One line parses the value and the other line makes the assignment.

The F# code seems easier and much more intuitive, but it requires a change in thinking. The first change in thinking is embracing the power of tuples. Since tuples are relatively new in C#, it takes a mental effort to remember they are critical to F# and truly powerful. The second change in thinking is that if statements are expressions in F# as opposed to blocks in C#. An expression results in a value, allowing the assignment of ID, no matter how it is generated, to be made in a single line of code. The block construct in C# allows for branching, but the assignment code needs to be implemented in each logic branch. The block approach results in more code that can lead to ambiguity in how a value is assigned.

As I get more practice using F#, I am really enjoying the simplicity of code and the power the language has for me.