|
|
Title | Answer: Choose |
Keywords | quick question answer, quiz answer, answer, Switch |
Categories | |
|
|
1. What does this code do?
The seldom used Choose statement takes as its first parameter a 1-based index. It returns one of the following parameters based on that index. If the first parameter is 1, Choose returns its second parameter. If the first parameter is 2, Choose returns the third parameter, and so forth.
This code returns the following values:
Index | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
Result | 1 | 2 | 6 | 24 | 120 | 720 | 5040 | 40320 | 362880 | 3628800 | 39916800 | 479001600 |
The result is the factorial of the index parameter.
2. What's wrong with this technique (aside from the function's name which is intentionally obscure so it's not too obvious what the code is doing)?
Well, there's nothing spectacularly wrong with this approach, although there are a few minor points worth mentioning. First, the code is a bit obscure because Choose is such a rarely used function. A good comment (and a better function name) would make this clear.
Second, and much more importantly, this function doesn't check that its parameter is valid. If you pass this function any value less than 1 or greater than 12, the program crashes. Ideally the function should return F(0) = 1 because the factorial of 0 is defined as 1. For the other values, this is less serious because limits on Long integers prevent the function from evaluating a result. You could easily allow this function to calculate F(0) using an If statement.
On the other hand, if the function used Doubles instead of Longs, it could calculate approximate values for up to F(170) = 7.26E+306. If you wanted to do this using Choose, you would need use a very long parameter list.
That's probably the biggest problem with this approach. You need to enter a series of precomputed values. If there are only a few values, that's no big deal. If there are many values, entering them by hand will be inconvenient and error prone. A longer parameter list also slows down Choose. In one test, a 156 item parameter list (not counting the index parameter) took about 4 times as long as the normal 12 item parameter list.
3. Can you think of an alternative approach that's also easy to understand?
One approach is to make a global or form-global array (called a lookup table) and initialize it with the function's values when the program starts. Then the program can simply look up values when it needs them later. This approach has the advantage that you can use code to initialize the array instead of hand-coding the the values in. That makes it easier and less error-prone to initialize a lot of values.
|
|
Private Factorial() As Double
Private Sub Form_Load()
Dim i As Long
ReDim Factorial(0 To 170)
Factorial(0) = 1
For i = 1 To 170
Factorial(i) = Factorial(i - 1) * i
Next i
End Sub
|
|
Later the program can use the array as in:
f = Factorial(i)
This version also defines a value for Factorial(0), although you still need to watch out for index values less than 0 or greater than 170.
4. Which version is better?
Both of these versions are effective and relatively easy to understand. I prefer the second method because it lets me use code to initialize a potentially large number of values without risking typos.
Note also that accessing an entry in an array is much faster than building and using the Choose parameter list. In one test, Choose took about 12 times longer than the array solution.
|
|
|
|
|