Input validation so far
Earlier, Klaus and Jeremy wrote a program to convert pounds and ounces into kilos.
Much of their code was validating user input:
There are two problems with this method.
First, once users click OK, the error message is gone. When they start fixing errors, there's no reminder of what the errors were. No big deal, but at work people get interrupted all the time. Even a one minute interruption will make someone lose track.
The second problem: users might have made more than one mistake. Say a user got both pounds and ounces wrong. S/he gets an error message about the first problem, then the program stops. The user fixes that problem, only to get another error message. It might be more helpful to show both errors at one time.
Better error reporting
Here's what we want to happen when both pounds and ounces have bad input:
Differences from before:
- Both errors are reported.
- The error messages stay on the screen.
We should make other changes, too. A human might have two conversions to make, not just one. Here's a human, to remind you what they are.
Two eyes, one to three noses, you get the idea.
Here's what might happen. The human does the first conversion, without any typing mistakes.
She starts on the second task. She makes a typing mistake in ounces. She meant to type 5, but missed a little, and also hit the R key, just below 5:
The program shows an error, and also erased the output from the previous task – 1.588. Leave it there, and there's a small chance that a human who gets interrupted might think that 1.588 was the right answer. Erase the output cell when the Convert button is pressed, and that won't be an issue.
So that's one change: erase the output each time the program runs.
OK, now the human corrects the mistake and hits Convert:
The program erased the error message. Leave it there, and the human might think she hadn't fixed the mistake.
So, each time the program runs:
- Erase the output.
- Erase error messages.
The two erasures are done every time the program runs. Geeks call that initializing, or initing, the program.
The flag pattern
Here's what we want to do. Suppose that
Check input 1 is a sub that will show an error.
Check input 1 Check input 2 Check input 3 if nothing went wrong then process output end if
Check input 1 Check input 2 Check input 3 if anything went wrong then end end if process output
The flag pattern helps. A flag is a variable that shows whether something happened. It's usually a Boolean, a data type. Booleans are either
False, and nothing else. Instead of using booleans for flags, you could use
Strings ("yes" or "no"),
Integers (1 or 0), whatevs. Booleans happen to be convenient for flags, but use what you want.
Here's the original validation code for pounds and ounces. The differences between validating pounds and validating ounces are marked.
Sub." The differences are:
- The cell to check.
- The label to use for the variable in the error messages ("pounds" or "ounces").
Those differences become params for the
Sub. Here's one way to do it.
Sub, explaining each param. That's common. Human programmers often work in groups. One human might write
checkCellValue, and the other humans use it. Documenting the params helps those other humans.
Notice the first two params. They're the differences betwixt uses of the sub. To use it to check pounds:
checkCellValue 3, "pounds", poundsOK
To check ounces:
checkCellValue 4, "ounces", ouncesOK
The third param is the result of the check.
message variable. Why does it exist? Another way to write the code:
With this code…
With this code…
Calling the input validation routine
The weight conversion program is IPO: input, processing, output.
The main program should reflect that:
checkCellValue directly. Instead, the main program calls the sub
getInput, which does all the input validation, and returns a flag showing whether the input was all OK, or if there were any errors. The main program checks that flag to decide whether to continue.
getInput twice, once for each input cell. If both are OK, then it grabs data from the cells into the variables
ounces, and sets the flag
Subs is common.
Some questions for the class.
Subis to make a chunk. It makes your program easier to understand, easier to test, and easier to change. It also makes it easier to have different people write different parts of the program.
So that's why they created a sub called
Why did they create the sub
Subto do all of the input validation.
Argh! The names!
Here are the calls to
checkCellValue 3, "pounds", poundsOK checkCellValue 4, "ounces", ouncesOK
Here's the sub's signature:
Sub checkCellValue(row As Integer, dataLabel As String, dataOK As Boolean)
The first param. It's 3, or 4, or
dataOK. Which is it?
It's different values at different times.
Params can make a sub behave differently each time it's called. The first time
checkCellValue is called, it messes with row 3. The next time, row 4.
That's one reason to add params. To make a sub do different things at different times.
Also, remember that it's the positions of the parameters that matters, not their names.
Suppose we had this code:
j are reversed. So here's how the variables in the main program map to the params in the sub:
So you'd see:
Params map to data in the caller.
jswitcheroo, in RL?
It's asking for bugs.
Rewrite it, adding error checking and Subs. It should work like this:
Some of the code has been written for you. Download the workbook. You'll see code like this:
Upload your solution.
In the text part of the submission form, please answer the question: What did you learn from this exercise?
(If you were logged in as a student, you could submit an exercise solution, and get some feedback.)