This little test program has allot of user input validation.
About 10 years ago while working as a pipefitter I was called upon to figure out how to fit a riser pipe onto a reducer. Since the reducer is tapered there was no normal way to do it.
I had to calculate as a best guess as to what my dimensions would be based on what I already knew about fitting pipe to pipe. It didn’t turn out near as pretty as I would have hoped , but a grinder does wonders to finish getting it closer to where it needed to be.
While I’m currently laid off, even though I haven’t had to do one of these since then, I finally decided to set down and figure out all of the math involved to create the 8 points and lengths needed for half of the riser circle and to be able to add the differences in the taper of the reducer.It took about 3 days working on and off to complete the formula to do all of the calculations required.
Do to the massive amount of calculations required to output the final 8 lengths, I wanted to create a program that does all of the math for the user.
My first hurdle is the user input validation. I need to validate if the person is inputting a decimal, a fraction or some off the wall entry.
Since the normal user would input a fraction, I searched for a premade function on the internet for the fraction to decimal conversion. I found this one Here from a March 14, 2008 blog post. You find very few that go from fraction to decimal. Most samples go from decimal to fraction.
After removing an extra “EndIf”, the code worked fine for converting a fraction to a decimal. (see code below)
Private Function FractionToDecimal(ByVal frac As String) As String Dim decimalVal As String = "0" Dim upper As Decimal = 0 Dim lower As Decimal = 0 Dim remain As Decimal = 0 If frac.IndexOf("/") <> -1 Then 'End If < ----Extra End if If frac.IndexOf(" ") <> -1 Then remain = CType(frac.Substring(0, frac.IndexOf(" ")), Decimal) frac = frac.Substring(frac.IndexOf(" ")) End If upper = CType(frac.Substring(0, frac.IndexOf("/")), Decimal) lower = CType(frac.Substring(frac.IndexOf("/") + 1), Decimal) decimalVal = (remain + (upper / lower)).ToString End If Return decimalVal End Function
After getting the code to work I then started thinking about user input validation. I added validation for every type of malformed input I could think of and gave the ability to return an error or return the result of the conversion.
As you can see the first screen shot is a normal Conversion. The second screen shot shows the fraction with the enumerator larger than the denominator , I could have allowed this type of input, but in this case I am catching for when people swap the two numbers.
Now the Final Code:
Imports System.Text.RegularExpressions Public Class Form1 Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load Me.Text = "Convert Fraction to Decimal " & My.Application.Info.Version.ToString End Sub Private Sub btnConvert_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnConvert.Click Dim regx As New Regex("^[a-zA-Z]") 'Starts at the begining and checks for any upper or lower case letters. Dim inputNfo As String ' Regx class http://msdn.microsoft.com/en-us/library/system.text.regularexpressions.regex(v=vs.90).aspx ' The String from the input text box inputNfo = tbUserInput.Text Dim outputStr As String = Nothing 'Here we check if it is a reconised decimal number, if true then just return the decimal number If IsNumeric(inputNfo) = True Then outputStr = inputNfo tbOutput.ForeColor = Color.Green lblInputValidation.Text = "Input is Valid" lblInputValidation.ForeColor = Color.Green ' Verify user is not spelling out the number ElseIf regx.IsMatch(inputNfo) = True Then outputStr = "Please check you are not Spelling your whole number" lblInputValidation.Text = "Input is Not Valid" lblInputValidation.ForeColor = Color.Red ' if not a decimal, verify it is not a malformed fraction ElseIf inputNfo.Contains("/") And inputNfo.Contains(".") = False Then Dim ReturnString As String ReturnString = FractionToDecimal(inputNfo) 'this part checks in the function if the enumerator is larger than the denominator If ReturnString = "Error Please Check Fraction" Then outputStr = ReturnString tbOutput.ForeColor = Color.Red lblInputValidation.Text = "Input is Not Valid" lblInputValidation.ForeColor = Color.Red Else 'If all is good then return the converterd fraction as a decimal outputStr = ReturnString tbOutput.ForeColor = Color.Green lblInputValidation.Text = "Input is Valid" lblInputValidation.ForeColor = Color.Green End If 'this checks that the input in not blank ElseIf inputNfo = Nothing Or inputNfo = " " Then outputStr = "Nothing was input" tbOutput.ForeColor = Color.Red lblInputValidation.Text = "Nothing was input" lblInputValidation.ForeColor = Color.Red Else 'returns this if the input number is realy messed up. outputStr = "Input not reconised" tbOutput.ForeColor = Color.Red lblInputValidation.Text = "Input not reconised " lblInputValidation.ForeColor = Color.Red End If 'Returns the final output tbOutput.Text = outputStr.ToString End Sub Private Function FractionToDecimal(ByVal frac As String) As String 'Code from http://amrelgarhytech.blogspot.com/2008/03/fraction-to-decimal.html ,,Fixed error to get to work. Dim decimalVal As String = "0" Dim upper As Decimal = 0 Dim lower As Decimal = 0 Dim remain As Decimal = 0 If frac.IndexOf("/") <> -1 Then If frac.IndexOf(" ") <> -1 Then remain = CType(frac.Substring(0, frac.IndexOf(" ")), Decimal) frac = frac.Substring(frac.IndexOf(" ")) End If End If upper = CType(frac.Substring(0, frac.IndexOf("/")), Decimal) lower = CType(frac.Substring(frac.IndexOf("/") + 1), Decimal) If upper > lower Then Return "Error Please Check Fraction" Else decimalVal = (remain + (upper / lower)).ToString End If Return decimalVal End Function End Class
Starting from the top we need the “Imports System.Text.RegularExpressions” for checking user input in the second test.
Next we set inputNfo as a string and equal it to the input text.
Then we run the inputNfo thru the VB.Net built in “IsNumeric” function to see if it is a recognized decimal number, if it is , then just return that number to the output textbox. No Conversion needs to be done.
If inputNfo is not recognized as a number we then pass it to the regular expression test and make sure the user is not trying to spell out the number(three instead of 3), if they are, it returns an error, if not then it passes on to the next test.
The next test would be to find out if the character “/” is in the string and also to make sure the the character “.” is not in the string, if it is then the user input looks something like,
“22. 3/4” , with the decimal in place it will return an error.
We could add more code to handle that problem and fix it but, why baby the user, make them input the information correctly so they don’t get used to inputting the information incorrectly.
If it passes all of those test then the string / number gets passed to the actual function that does the conversion. While in the conversion function we verify that the fraction does not have a larger enumerator than a denominator. Our users should not need to input the fraction in this way.(For the final program that this sample app. was built to test.)
If it fails the test then it returns an error message, (as in the screen shot above) if it passes then it returns the result of the Conversion as a decimal.
Again, do to the massive amount of calculations my final program will require, I need to validate every possible way a user could input a number so the end result would be a decimal, and then I would be able to do the calculations on the input parameters.
If I catch all possible input errors then any output errors should be easier to trace and fix.
The output of the 8 lengths in my final application will then be converted back from a decimal to a fraction rounded to the nearest 1/16th of an Inch.