A Few Ideas Regarding SCRUM Process

We’ve been using SCRUM at work. It’s certainly been a learning process. During that process I’ve learned that I’m not a very big fan of SCRUM. I’ll write more on that later. That said, I’ve come up with a few ideas which I hope will make my time, and my teams time, with SCRUM a bit better.

  1. Start measuring stories on complexity not time.
    It’s very easy for a story to be under-estimated. If a story is not estimated correctly, it will take longer and you will most likely miss your Sprint. Don’t think about time when estimating, we like to think we can get things faster than we actually can. Think, instead, about how complex something is. The more complex it is, the higher point it should get.
  2. Use a 10 point scale in your head when estimating.
    Depending on what you are using, the SCRUM point scale skips numbers. Our numbers are:

    0, 0.5, 1, 2, 3, 5, 8, 13, 20, 40, 100, INFINITY

    When we see numbers like 13 we immediately think that they are “big” numbers. So when we estimate we tend to pick numbers under 13 even though the story being estimated might require a 13. So, I say pick a number between 1 and 10 in your head and then translate that to the SCRUM numbers.

    0.5 1
    1 2
    2 3
    3 4
    5 5
    8 6
    13 7
    20 8
    40 9
    100 10
  3. Take the larger of any numbers present.
    I’ve dubbed this Jeremy’s law. During the course of estimating you might find yourself wrestling between a 2 and a 3 in your head. Take the bigger number. If there is any doubt in your mind, you should just take the bigger number instead of committing to something that you are not sure of.
  4. Look back at similar stories points. Did we complete them or were they underestimated?
    Previous stories you have completed might be similar to the ones you now have to do. Or they might have a similar complexity. Rather than estimating a whole new estimate, use that information to your advantage. If, in the past a story like this took a long time, it will probably take a long time again.
  5. Forget about doing it right the first time.
    This will be the hardest for me. I like to do it right the first time. But when it comes to SCRUM the key is to get stuff done. Once you have something done you can then iterate on it. Now – I’m not saying that you shouldn’t program using SOLID principles. I am saying that it’s easy to spend a lot of time analyzing things. Just jump in there and start coding it up.Think of the story as not having to be totally complete. Think of it as a step towards being totally complete. Just get it done as fast as possible. Than pass to testing. Once it’s done we can reiterate on it to improve it. But the first goal should be to get something out the door.
  6. Do create follow up stories (discovery stories for what is wrong)
    During a SPRINT review a stakeholder might not approve the story to go live. We should create a discovery story then and there to figure out what further they need from the story. Create new stories based on the results of your discoveries.
  7. Once a story meets ac it is done
    As long as the original story meets the acceptance criteria we can consider it done. Anything that changes the AC should yield a new story with new AC. This will allow us to iterate on the first while keeping the first story in a “done” state.
  8. Be more pro active about sending too complex stories back to be broken up further.
    Big stories need to be broken up. It’s just how it is. Don’t feel bad about sending a story back to be broken up.
  9. Don’t take in a thirteen if possible.
    In our version of SCRUM, stories that are 13 points will take up the whole Sprint. And because we know that things usually take longer than we expect, a thirteen will definitely overflow the timebox. So, send it back to be broken up.
  10. Pull smaller bits more often into master.
    There are certain bits of code that we add during the course of a project that can be added to master. We split the stories up, but maybe we can also split the code up as well. Instead of pulling a huge change into master, let’s identify the things that can go to master as we go along.
  11. Push things out as frequently as possible.
    Avoid the big pushes and potential big breakages by pushing smaller bits of code out more often. We talk about this often and say it is a good idea, but we don’t do it. We don’t need to get stakeholder approval to fix a bug we find, so push the bug fix live. We don’t need stakeholder approval to fix performance issues – so push those live. We don’t need approval to repay technical debt – so push that live.I’d reccomend we push anything live that we can. The stakeholders like to bundle everything up into a gigantic push. We really need to let them know that a better way to do it is a little bit all of the time.
  12. Immediately create stories for what needs to be done as soon as it is known.
    I think we as developers should be more pro-active about creating stories. If we find something that needs to be done, create a story for it. It’s hard to prioritize these kinds of stories because they are not necessarily related to business initiatives. So, use your best judgment in when to pull it in. The key is, it’s not going to get done unless we remember to do it.
  13. Always be thinking of ways to improve the process.
    Don’t be afraid to get rid of waste. If we get rid of the “big” waste, it enables us to see the smaller waste. If something is wasteful, don’t be afraid to get rid of it or let someone know you think it is time for it to go.

I really hope these things help. Ideally I’d like to move away from SCRUM. However, if I’m going to have to use SCRUM then I might as well figure out how to make it better.

Do you have any ideas on how to improve the SCRUM process? What do you do? How did your teams make things better?

Deserializing JSON to a .NET Object

Generally in .NET MVC you would use the default model binders to deserialize JSON to a .NET object. However, there are some cases, involving “complex” collections, where this becomes a bit tedious to do. Microsoft provides a few ways around this, but none are satisfactory. Unlike the default model binders, the JavaScriptSerializer provides support for deserializing JSON to a .NET object with complex collections.

Take the following simple class and method signature for example:

// simple class
public class SaveInformation
{
    public string Name { get; set; }
    public Dictionary<string, List<SaveItem>> Components { get; set; }
}

// method signature
public ActionResult Save(SaveInformation saveInformation)

Below I’ve included some simple JSON that we will pass to .NET via AJAX:

{"SaveToSession":false,"Name":"My Stupendous Thing","Components":{"Component1":[{"ProductId":"1234"}]}}

We are passing the JSON to .NET using AJAX with the “application/json” contentType. Because we are using the “application/json” contentType, .NET will automatically call the JsonValueProviderFactory and map the information over to our SaveInformation model. It seems pretty straight forward, the Save method will receive a SaveInformation object when it is called.

Not so straightforward unfortunately, the Save method does receive a SaveInformation object. If we inspect our SaveInformation object we see the Name is populated perfectly fine, but the Components dictionary ends up being null.

The reason for this? It seems that the JsonValueProviderFactory doesn’t fully support pure JSON syntax. In order for .NET to properly parse a complex collection, you actually have to give it a numerical index.

From http://msdn.microsoft.com/en-us/magazine/hh781022.aspx:

Though it’s somewhat counterintuitive, JSON requests have the same requirements—they, too, must adhere to the form post naming syntax. Take, for example, the JSON payload for the previous UnitPrice collection. The pure JSON array syntax for this data would be represented as:

[
    { "Code": "USD", "Amount": 100.00 },
    { "Code": "EUR", "Amount": 73.64 }
]

However, the default value providers and model binders require the data to be represented as a JSON form post:

{
    "UnitPrice[0].Code": "USD",
    "UnitPrice[0].Amount": 100.00,

    "UnitPrice[1].Code": "EUR",
    "UnitPrice[1].Amount": 73.64
}

I know right? It was hard for me to read this as well due to the anime-sized tears in my normal-sized eyes. The problem is, no browser I know of has a JSON.serializeForDotNet function. So this leaves us with two options, make our own JSON serializer, or make our own ValueProvider/ModelBinder. Neither of these options sounded very appealing to me, so I went with the hidden third option. Pass in a string 🙂

You can use the JavaScriptSerializer class, located in System.Web.Script.Serialization, to deserialize JSON information and, as an added bonus, it actually handles properly formatted pure JSON!

So, the new method looks like this. We pass in a string value and deserialize it using the JavaScriptSerializer. Now we receive a SaveInformation object with a fully populated Components dictionary.

public ActionResult Save(string saveInformation)
{
    // instantiate a JavaScriptSerializer
    JavaScriptSerializer serializer = new JavaScriptSerializer();

    // use the JavaScriptSerializer to deserialize our json into the expected object
    SaveInformation saveInformationObject = serializer.Deserialize<SaveInformation>(saveInformation);

Use a JSON Parser to Visualize a JSON String

Just noting this here for future reference.

Whenever I am working with JSON I find it useful to be able to parse it. Now I can certainly parse it with Chrome’s inspector and see it in the console… but it’s nice to have an easy online tool to use as well.

The tool I use, and the tool that has helped me find several issues in the past, is JSON Parser Online. It’s really nice to be able to see the JSON string on the left and the parsed object on the right.

The Case of the Disappearing Cookie

If you are working on a site that doesn’t have a proper TLD (i.e. http://localhost:8013) you will notice that setting cookies on the browser doesn’t seem to work the way it should. Sometimes your cookie, which works perfectly fine on a site with a TLD, will not show up on your local site.

For example, this code will work perfectly fine on a site with a TLD but not on your local site.

newCookie = New HttpCookie(ConfigurationManager.AppSettings("YOUR_SPECIAL_COOKIE_NAME"))
newCookie.Domain = ConfigurationManager.AppSettings("BASE_DOMAIN")
HttpContext.Current.Response.Cookies.Add(newCookie)

At this point you might be thinking, ‘I did everything right, where did my cookie go?‘.

This comes down to how the browser handles setting cookies that have a specified domain. The browser prepends a ‘.’ (that’s a dot) to the beginning of any domain specified for a cookie. On normal domains this basically just says that this cookie is valid for this domain and any subdomains. The following non-doctored image proves it:

Set two cookies, one with a specified domain and one without.

Setting Test Cookies
JavaScript to set test cookies for the superfrogadventures.com domain.

This results in the following two cookies

Shows the results of the first cookie set.
Shows the results of the first cookie set.
The Second Test Cookie
Shows that the domain does not have a dot.

You will notice that the domains are a bit different. One has a ‘.’ while the other does not.

So. All this to say, if you are developing locally (or on a site without a TLD) then you will need to save your cookies without a “domain”. This will ensure that the cookie is accessible. Otherwise you will probably need to create yourself some sort of domain with a TLD.

Finding a Column with a Specific Name in TSQL

I just recently ran into a situation where I needed to find a table that contained a specific column in the database. I’m not looking for a column value, I’m looking for the name of the column. So, like any good programmer would do, I spent some time Googling…

There were a number of unhelpful articles and answers on the subject. I sifted through everything and finally landed upon an answer that worked! Unfortunately I forgot where it came from, so if any of you know where this little trick came from feel free to let me know.

In order to find a column with a specific name in TSQL you can use the following query:

USE [YOUR_DATABASE_NAME]
GO
SELECT t.name AS table_name,
SCHEMA_NAME(schema_id) AS schema_name,
c.name AS column_name
FROM sys.tables AS t
INNER JOIN sys.columns c ON t.OBJECT_ID = c.OBJECT_ID
WHERE c.name LIKE '%[WHAT YOU ARE LOOKING FOR]%'
ORDER BY schema_name, table_name;

Just replace [YOUR_DATABASE_NAME] with the name of the database you are using and [WHAT YOU ARE LOOKING FOR] with the full column name or a part of the column name you are looking for.

Alternative to Eval() and Casting in Databound Control

Some of you might already know this, however I found it interesting and helpful. For the case of this example let’s say you have a Person object defined somewhere in your ASP.NET code.

Public Class Person
	Public Property FirstName As String
	Public Property MiddleName As String
	Public Property LastName As String

	Public ReadOnly Property FullName As String
		Get
			Return String.Join(" ", FirstName, MiddleName, LastName)
		End Get
	End Property
End Class

Say for example you have a collection of Persons that you’ve assigned to a webforms repeater. In your ItemTemplate you would like to access the properties of whatever object you’ve bound to the repeater. .NET 4.5 introduced some new options that allow you to strongly type your ASP.NET data controls.

First let’s go through the way it used to be done…

.aspx.vb File (CodeBehind)

'// declare a list for our repeater to use
Dim persons As List(Of Models.Person)

'// populate the list with persons (returned by this random function, who cares what it does)
persons = _personDAO.GetPersons()

'// assign the list to the repeater and bind 'em up
repPeople.DataSource = persons
repPeople.DataBind()

.aspx File

<asp:Repeater ID="repPeople" runat="server">
	<HeaderTemplate><ul class="people"></HeaderTemplate>
	<ItemTemplate>
		<li class="col_12 peopleWrap">
			FullName: <%# Eval("FullName")%>
		</li>
	</ItemTemplate>
	<FooterTemplate></ul></FooterTemplate>
</asp:Repeater>

You can use Eval to evaluate a string and output the related value like is done in the example above. This uses reflection to figure out what the current object is and outputs whatever property that you’ve specified in your string. This is just a string so you don’t get any intellisense and you have to remember (ugghhh – remembering what’s that?) what properties you have access to.

You can also cast the object to the type you know that it should be. This is nice because it avoids expensive reflection and it also gives us intellisense. After casting you can access the properties normally with intellisense help. (Not to mention warnings and errors should a property on the source object ever change). I.E. Full Name: <%# CType(Container.DataItem, Models.Person).FullName%>
Casting is nice and all, but it can get a bit tedious and messy, especially if you have to cast every time you want to access a property.

Using .NET 4.5 — Strongly Typed Repeaters
However, thankfully, .NET 4.5 decided to help us out and allow us to strongly type our repeaters. This gives us the best of both worlds, we get intellisense, avoid expensive reflection, and also can easily access properties without extensive use of CType. All you have to do is set the ItemType attribute on the repeater itself.

<asp:Repeater ID="repPeople" runat="server" ItemType="Models.Person">
	<HeaderTemplate><ul class="people"></HeaderTemplate>
	<ItemTemplate>
		<li class="col_12 peopleWrap">
			FullName: <%# Item.FullName%>
		</li>
	</ItemTemplate>
	<FooterTemplate></ul></FooterTemplate>
</asp:Repeater>

Dig Web Interface ftw!

Ok. I guess because this is my first post on here I should say something like, “Hi Reader, thanks for stopping by and reading my blog.” So I guess I will.

Hi Reader, thanks for stopping by and reading my blog.

I just wanted to mention really quick how awesome digwebinterface.com is. I’ve used it so many times to find DNS information about different domain names out there. For example, I just now confirmed the DNS information was correct for this blog, jeremysawesome.com.

Confirming DNS with digwebinterface.com
Yep, the DNS for jeremysawesome.com looks correct.

DNS confirmed, jeremysawesome.com is ready to rock!