The ZX80 Makes the Grade

See all articles from SYNC v1 n4

Introduction

It is not a toy! Even with only 1K bytes of storage, the ZX80 can be an invaluable aid to the teacher in the calculation and evaluation of grades. In this article we present two programs running on the 1K Basic machine. The first determines the test scores and keeps track of which question caused the class the greatest difficulty. The second finds the class distribution of grades, enabling the teacher to scale the grades. While with more memory the two programs can be easily combined, presentation of the separate codes is made for those, like me, who want to do something while they wait for the 16K memory to arrive.

These programs have been used to handle the bi-weekly exams of twenty questions given to the 95 students in my introductory astronomy class. While, in principle, the same sort of computations could be accomplished at the university main frame computer, there is no comparison between that and a comfortable chair in front of the TV and ZX80. Further, because of the way the programs are set up, the data can be entered piecemeal, with more being added at your convenience. Finally, the tape storage system makes it a trivial task to keep the results for all the tests together. You can mount the cartridge and “instantly” see how the class did on any exam.

Program 1: Test Scoring

Using the ZX80 to add the scores on questions is an obvious and useful application. The ZX80 can be even more useful, however, because it can also keep track of which questions are being missed. After all the tests are graded, the teacher has a measure of which concepts were the hardest for the students. Knowing the question-by-question scoring, the teacher can see exactly which topics need review.

Before using the first program, edit lines 10 and 11. N is the number of questions on the test (20 or fewer; more may cause memory overflow). P is the default number of points per question. This number is used for the default when no number is explicitly entered in answer to the prompt at line 136. The reason for having a default P is that most answers are right (we hope!) and it is needless to have to enter numbers when just a single NEWLINE will do.

Having defined N and P appropriately, we can now enter the data. In response to the prompt “Q”, where Q is the number of the question whose score is being requested, reply with the value earned. As described above, NEWLINE by itself will give the default value, P. Any other number is simply typed in the normal manner. The characters “K” and “E” are special and are interpreted as follows: 1) “K” stops (i.e., “kills”) the program at this point. You can resume grading at exactly this point at a later time simply by using a CONTINUE command. More on this below. 2) “E” means the last score entered was in “error.” The score is erased, and you are asked to correct its value.

After the scores on each question have been entered, the student’s total is given. At this time you can get a plot of the relative number of points lost per question by typing “P” in answer to the prompt. The length of the bar is proportional to how many fewer points were earned by correct answers to this question than the one that earned the most points. Note that the shortest bar is the question the students did best on. The numeric value of the plotted quantity is listed at the end of the bar. After looking at the plot, you can either kill the program with “K” or go back to enter another exam by typing NEWLINE.

After stopping the program by entering “K” at any time, it may be SAVEd. All the relevant information is stored. The program and data may be LOADed, and you will start at the place where you stopped simply by executing CONTINUE.

Program 2: Grade Distribution

The overall performance of the class is determined by entering the test grades into Program 2. Grades are assumed to be in the range 0 to 100. A different range is easily accommodated by modification of the scaling used in line 225. Instead of 5, use another number which maps your input into the range (0,20). After a grade is entered, a plot of the number of students receiving a grade in each indicated interval is made. The first number in a row is the grade interval being plotted. The length of the bar labeled with the value G in the first column is proportional to the number of people who scored in the range, G to G+4; e.g., the bar labeled 75 contains all who scored 75 to 79. The second column contains the number who scored in this range; the bar length is proportional to this figure. The third is the cumulative distribution, i.e., how many were in this grade range or lower. The cumulative distribution is particularly important because it indicates the relative merit of a given absolute grade. The last value in this column is always just the number of test grades entered so far.

As in Program 1, the letter “E” entered instead of a grade deletes the grade just entered, i.e., it erases the error. If you type the letter “K”, the program will stop. CONTINUE will start you again. SAVE preserves all data as well as the program, so you do not have to enter the grades again if something prevents you from finishing in one session.

Programming Suggestions of General Applicability

Several programming techniques used in these codes will be useful in other ZX80 programs.

When you have to enter the grades for 95*20=1900 answers, most of which are for full credit, you can get very tired of typing “5” then NEWLINE. It is much more efficient simply to type NEWLINE (NL in prompts) and let the machine make the default. Unfortunately, if you are INPUTing into a numeric field, NEWLINE by itself is ignored; thus, you have to use a string variable for INPUT. In this case, NEWLINE by itself sets the string to be the null string, “”. The price paid is the need to convert any non-null string to a numeric value. For example, one has to set G=15 when the input is the string “15”, i.e., characters “1” and “5”. The requisite code is in lines 148-151 of Program 1. Line 152 takes care of the default for null strings. Note the use of the operator “[illegible]”, which permits the code to work even if A$ is initially null.

It is human (rather than machine!) to want to use mnemonic notation to enter signals for action. That is, when you want something erased, it is more natural to type “E” than to enter the value 101. When the input is being made into strings, it is no problem to check whether the string is the symbolic signal. This is the technique used in Program 1, line 265. In Program 2 the input is numeric, however. In order to use the letters “K” and “E” as symbolic signals there, we have to be a little more tricky. What we do in lines 3 and 4 of Program 2 is to define the variables E and K, giving them appropriate numerical values. The text typed in response to an INPUT statement is evaluated before being stored into the destination. Thus, typing E in response to the INPUT statement in line 200 is equivalent to entering the number 101. Typing the letter K there sets G=K=-1 and this value of G triggers the STOP command in line 201. As each of these variables can be set to any appropriate “impossible” test scores, it is no problem to make modifications if grades [illegible] 100 are allowed. Finally, if you prefer, more dramatic and memorable variable names like KILL or ERASE can be used.

The CONTINUE Command

Of all the pieces of hidden gold in the ZX80, the most valuable is the command CONTINUE. When you leave the program execution mode either voluntarily because of a STOP statement in your program or involuntarily because of an error (like trying to write too much on the screen), the place you were when you stopped is remembered. While in immediate mode, you can do what you want, including resetting variables and even editing the program. The CONTINUE statement will start you again at the line following the one where you stopped. Thus, in these programs you can kill (i.e., “K”) whenever you want, then SAVE the file on tape. The LOAD operation brings in the file with the program, all the data, and even the information on where you stopped. CONTINE following the LOAD acts just as if there had been no tape storage in between. That is, SAVE followed by LOAD completely re-establishes the environment as it was before the SAVE operation. The only thing to remember if you are going to use the STOP-CONTINUE trick is to make sure that the statement following the STOP produces a recognizable cue. If you just have the sequence, 100 STOP, 110 INPUT X, when you restart with CONTINUE you will have a nice blank screen and the cursor waiting for input with no hint as to what input is wanted. To avoid this problem in Program 1, for example, line 139 jumps back to the input prompt, so you can tell what is expected when you restart.

One of the problems in having only 1K of memory is that peculiar errors can occur when you are OUTPUTing. The characters to be written on the screen occupy the same memory as your program. You can, therefore, be running quite nicely, entering question scores, and then have trouble when you try the plot, because you do not have enough memory for the output. The choices made for the scaling of the bar lengths in these programs work well for my exams with 20 questions and 95 students, but there may be something unusual about your distributions. If you do have trouble, do not panic! Simply change the scaling; reduce the 15 in line 226 of Program 1 and/or the 20 in line 120 of Program 2. None of the data will be lost as long as you use CONTINUE to restart.

More memory will permit these programs to be significantly improved. Programs 1 and 2 could then be combined so that all you would ever enter would be the question scores. Also, one could add a subroutine which would give the test grade above which a specified fraction of the class scored. Finally, with 16K you should be able to store the names with the grades and thus have your “mark book” on tape. In any case, I hope that you find these programs as useful as I have even in their limited form.

Program 1: Test Scoring

 10 LET N = 20
11 LET P = 5
20 DIM S(N)
25 LET T = 0
100 CLS
105 PRINT "SCORES?"
110 LET T = T + 1
115 LET R = 9999
116 LET Q = 0
120 LET Z = 0
130 FOR I = 1 TO N
135 PRINT "Q";I;
136 INPUT A$
137 IF NOT A$="K" THEN GOTO 140
138 STOP
139 GOTO 135
140 IF NOT A$="E" THEN GOTO 148
141 CLS
142 LET I = I - 1
143 LET Z = Z - G
144 LET S(I) = S(I) - G
145 GOTO 135
148 LET G = 0
149 LET G = 10*G + CODE(A$) - 28
150 LET A$ = TL$(A$)
151 IF A$ > "" THEN GOTO 149
152 IF G < 0 THEN LET G = P
153 PRINT G
155 LET Z = Z + G
160 LET S(I) = S(I) + G
165 IF S(I) < R THEN LET R = S(I)
166 IF S(I) > Q THEN LET Q = S(I)
170 NEXT I
171 LET R = Q - R
175 PRINT "P TO PLOT",
200 PRINT "GRADE",Z
205 INPUT A$
210 IF NOT A$ = "P" THEN GOTO 100
215 CLS
216 PRINT "REL ERRORS"
220 FOR I = 1 TO N
222 IF I < 10 THEN PRINT " ";
224 PRINT I;" ";
226 LET Z = 15*(Q - S(I))/R
227 IF Z = 0 THEN GOTO 233
230 FOR J = 1 TO Z
231 PRINT CHR$(128);
232 NEXT J
233 PRINT "▒";Q-S(I)
250 NEXT I
255 PRINT "K TO KILL"
260 INPUT A$
265 IF A$ = "K" THEN STOP
270 GOTO 100

Program 2: Grade Distribution

  1 REM GRADE HISTOGRAM
3 LET K = -1
4 LET E = 101
10 DIM C(20)
15 LET A = 0
20 LET N = 0
25 LET S = 1
100 LET G = 0
110 FOR I = 0 TO 20
115 LET G = G + C(I)
120 LET L = 20*C(I)/S
122 IF I < 2 THEN PRINT " ";
123 PRINT 5*I
124 IF C(I) < 10 AND I < 20 THEN PRINT "▒";
125 PRINT C(I);"▒";G;
130 IF L = 0 THEN GOTO 150
135 FOR J = 1 TO L
140 PRINT CHR$(128)
145 NEXT J
150 PRINT "▒"
155 NEXT I
160 IF N > 0 THEN PRINT "AV=";A/N;
198 REM K=KILL(STOP), E=ERROR
199 PRINT " GIVE GRADE, K OR E"
200 INPUT G
201 IF G > K THEN GOTO 205
203 STOP
204 GOTO 100
205 IF G < E THEN GOTO 215
206 LET D = -1
207 LET G = Q
208 GOTO 220
215 LET D = 1
216 LET Q = G
220 LET N = N + D
221 LET A = A + D*G
225 LET G = G/5
230 LET C(G) = C(G) + D
235 IF C(G) > S THEN LET S = C(G)
240 CLS
245 GOTO 100

Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.