Some more Refactoring

The code currently looks like this:

Public Function i2r(i As Integer) As String

Application.Volatile

i2r = ""

If i >= 50 Then

i2r = i2r + "L"

i = i - 50

End If

If i >= 40 Then

i2r = i2r + "XL"

i = i - 40

End If

While i >= 10

i2r = i2r + "X"

i = i - 10

Wend

If i = 9 Then

i2r = i2r + "IX"

i = i - 9

End If

If i >= 5 Then

i2r = i2r + "V"

i = i - 5

End If

If i = 4 Then

i2r = i2r + "IV"

i = i - 4

End If

While i >= 1

i2r = i2r + "I"

i = i - 1

Wend

End Function

I figure that I want to create a function where I feed in each roman numeral and if the current value of i > the decimal equivalent of the roman numeral then concatenate the roman numeral on the end of i2r and subtract the decimal equivalent from i.

The only thing that is stopping me is the mixture of whiles and if’s in the pattern above. The I’s and X’s are whiles, but the rest are if’s. Hmmm, I think. After a bit of contemplation I’m pretty sure that each of the if’s can simply be replaced with a while.

But, how can I be sure? The easiest way to be sure is to try it and see. I have the tests to save me if I make a mistake and I have undo to roll back if I need to. But, to be on the safe side I decide to try this from the bottom up. That is, I start with the I’s.

This is what I come up with, for the I’s (I couldn’t think of a good function name, so m it is):

i2r = i2r + m(i, "I", 1)

'While i >= 1

' i2r = i2r + "I"

' i = i - 1

'Wend

End Function

Public Function m(ByRef i As Integer, ByVal RomanCharacter As String, ByVal IntegerValue As Integer) As String

While i >= IntegerValue

m = m + RomanCharacter

i = i - IntegerValue

Wend

End Function

And it works.

  • So I try it on the 4 IF, replacing the if i = 4 with i2r = i2r + m(i, "IV", 4)

  • And it works.

  • So I try it on the 5. It works too.

  • So, I do all of the individual roman numerals. Recalculating the tests after each small change.

I end up with this.