Input Functions On The VIC
John Ging
The "dynamic keyboard" technique can solve many kinds of programming problems: it's a way to make a program change itself during execution. One use of dynamic keyboard is illustrated here with a program which lets you enter a function, while a program is RUNning. There's also information on the DEF FN command itself.
If you use the DEF FN instruction much in your programming, you may have wondered if you can make this instruction "user friendly" by entering the function into the program via an INPUT statement. The obvious way to do this would be to begin your program with:
10 INPUT "PROMPT"; A$
and to follow this instruction with:
20 DEF FNA(X) = A$.
Unfortunately, this won't work. If you RUN the program, the computer prints PROMPT on the screen and waits for you to type in the string representing the function. Suppose you type in X ↑ 2 + 7 * X and then hit RETURN. The action of the computer is to fill the string variable A$ with the string you just typed in, namely, with X ↑ 2 + 7 * X. Then when the program execution continues with instruction 20, the string X ↑ 2 + 7 * X is substituted for A$ in the DEF FNA(X) = A$ statement. Right? Wrong.
If you follow instruction 20 with:
30 PRINT FNA(2)
you will get a
? TYPE MISMATCH ERROR IN 30
Evidently, the computer has done nothing with the string you just typed in. It still thinks that FNA(X) is literally equal to the string variable name A$ rather than equal to the string represented by A$.
A Way Out
The only solution would seem to be to LIST instruction 20 and alter the string after "DEF FNA = " by directly typing it in every time you want to change the function represented by FNA(X), and that's not very "user friendly."
Fortunately, on the VIC, there is a way out: the "dynamic keyboard" feature. If you LIST an instruction, alter it from the keyboard, and then hit RETURN while the cursor is on the instruction line, the altered instruction is entered into memory. The trick is to force your program to alter its own instructions by causing them to be printed to the screen and RETURNs to be forced over them. This makes it possible for the computer to simulate the INPUT of a function.
The program at the end of this article shows how it works. The essential part of the program is contained in lines 10-40. Line 10 causes
F(X) = ?
to be printed on the screen and waits for the string representation of the function FNA(X) to be typed in. Line 20 prints
60 DEF FNA(X) = "string" (represented by A$) GO TO 50
invisibly (in white) beginning on the second line of the screen. Line 30 POKEs the keyboard buffer with "HOME" and "CURSOR DOWN." Line 40 POKEs the keyboard buffer with two RETURNs, POKEs location 198 with the number of characters in the keyboard buffer (four), and then ENDs the program. When the program ENDs, it skips a line and prints "READY" (also in white) on the screen; then the RETURNs are executed. The execution continues at line 50, which skips down under the INPUT line and returns the character color to the normal blue.
The purpose of the program is to find the area under the graph of the function FNA(X) from X = X1 to X = X2 with N subdivisions (N should be an even number). As an example, RUN the program and type in 4/(1 + X ↑ 2) after the prompt
F(X) = ?.
Then type in 0 and 1, respectively after the prompts
XI = ? X2 = ?
and type in 100 after N = ?.
Using DEF FN A function is a BASIC word that takes a number within parentheses, performs some operation on it, and gives you a result. For example, some common functions are INT(X), which removes the fractional part of a number, or ABS(X), which makes negative numbers positive. With the DEF FN command, you can create your own functions. Here's one way: to round X to the nearest cent you might type in: X = INT(X * 100 + .5)/100. If you want to round off in this way many times throughout a program, you could define a function to do it for you. Just type: 10 DEF FNROUND(X) = INT(X * 100 + .5)/100. Notice that you give it a name, just like you do with variables. You have just created a function, whose name is ROUND. You can use ROUND just like any other function. From now on, you can round numbers to the nearest cent without having to type in the whole equation. For example, if you type: PRINT FNROUND(7.3628) the result will be 7.36. Some other possibilities are: PROFIT = FNROUND(GROSS) -FNROUND (OVERHEAD) or PROFIT = FNROUND(GROSS-OVERHEAD) You cannot make functions that use strings (words), and you cannot type DEF FN directly like a PRINT; it must be inside a program. When using ROUND, any number between the parentheses will be used as X in the equation INT(X * 100 + .5)/100. If we now write: 20 DEF FNTEST(B) = B*A B will be whatever number we put between parentheses, and A will have the same value it does everywhere else in the program. For example: A = 3 PRINT FNTEST(5) will give 15, since FNTEST will multiply whatever is in the brackets by A. |
The result will be given by INTEGRAL =, and the answer is a good approximation to π.
Input Functions
2 REM : FINDS THE AREA{2 SPACES}UNDER THE GRAPH OF A{2 SPACES} FUNCTION FROM X1 T O X2WITH N SUBDIVISIONS. 5 PRINT "{CLR}{3 SPACES}INPUT A FUNCTION" 10 PRINT "{HOME}{9 DOWN}" : INPUT"F(X) = ";A$ 20 PRINT"{HOME}{DOWN}{WHT}60 DEFFNA(X) = " ;A$ : PRINT"GOTO 50" 30 POKE 631, 19 : POKE 632, 17 40 FOR I = 633 TO 634 : POKE I, 13 : NEXT : POKE 198, 4 : END 50 PRINT" {7 DOWNHBLU}" 70 INPUT"Xl = ";X1 80 INPUT"X2 = ";X2 90 INPUT"N = ";N 100 D = (X2 - X1)/N 110 S = 0 120 FOR I = 1 TO N - l STEP 2 130 S = S + FNA(X1 + I * D) : NEXT:S = S * 2 140 FOR I = 2 TO N - 2 STEP 2 150 S = S + FNA(X1 + I * D) : NEXT 160 S = D*(2 * S + FNA(Xl) + FNA(X2))/3 170 PRINT"INTEGRAL = ";S 175 POKE 36878, 15 : POKE 36876, 170 : FOR I = 1 TO 200 : NEXT : POKE 36876, 0 180 PRINT 190 PRINT"TO CONTINUE, HIT ANY{3 SPACES}K EY." 200 GET A$ : IF A$ = "" THEN 200 210 GOTO 5