This program calculates calories burned during physical exercise activities and estimates the corresponding weight loss. It stores activity names as strings in a two-dimensional array and exploits the ZX81/TS1000 convention of using variable names that match activity strings, so that VAL A$(N) retrieves the calorie-per-hour value stored in the identically-named numeric variable (e.g., LET JOGGING=560). Up to 20 activities are supported, each with a name up to 12 characters and an associated number of hours. The total calorie count is converted to kilograms and pounds of weight loss using a 7000-calories-per-kilogram approximation, with results displayed in a right-aligned tabular format using TAB arithmetic.
Program Analysis
Program Structure
The program is divided into clearly labelled subroutines, with a main flow that proceeds through initialisation, a title/list display, user input, calculation, and output:
- Line 8 / GOSUB 500 — initialises the calorie-per-hour constants and resets the accumulator
C. - Line 10 / GOSUB 1000 — displays the title screen and activity list, then waits for ENTER.
- Lines 15–90 — dimensions arrays and collects user input (activity names and hours).
- Lines 91–200 — main output loop: prints the activity table, totals, and weight-loss estimate; handles “go again” logic.
- Lines 500–800 — value-assignment subroutine for the 20 named activity variables.
- Lines 1000–1220 — introductory display subroutine.
- Lines 2000–2020 — per-activity formatting subroutine (converts calorie value to string
X$). - Lines 3000–3030 — total formatting subroutine (converts accumulated total to string
Y$).
The VAL A$(N) Trick
The most technically interesting feature is the calorie lookup mechanism at lines 110 and 2005:
LET C=C+(VAL A$(N)*H(N))
On the ZX81/TS1000, VAL evaluates a string as a BASIC expression. Because the activity names stored in A$(N) (e.g., "JOGGING") are also the names of numeric variables assigned in the subroutine at lines 500–700, VAL A$(N) effectively dereferences the activity name as a variable, returning its calorie-per-hour value. This is a compact and clever indirect-variable lookup that avoids any need for a lookup table or IF/THEN chain.
Activity Variables
| Variable | Calories/Hour |
|---|---|
BADMINTON | 300 |
BASEBALL | 360 |
BASKETBALL | 500 |
BICYCLING | 400 |
BOWLING | 400 |
DANCING | 300 |
FOOTBALL | 550 |
GOLF | 250 |
HANDBALL | 600 |
JOGGING | 560 |
RACQUETBALL | 600 |
RUNNING | 900 |
SITTING | 100 |
SKATING | 400 |
SKIING | 600 |
SOCCER | 550 |
TABLE TENNIS | 230 |
TENNIS | 440 |
VOLLEYBALL | 350 |
WALKING | 300 |
Note that TABLE TENNIS contains a space, which is valid as a ZX81 variable name only if typed as a multi-word name — the tokeniser treats it as a single variable on that platform.
Array Dimensions and Input
DIM A$(20,12) allocates a 20-row, 12-character string array for activity names. This imposes a hard 12-character limit; “RACQUETBALL” is exactly 11 characters, which fits, but any activity name longer than 12 characters would be silently truncated. DIM H(20) stores the corresponding hours as a numeric array. The program supports a maximum of 20 activities per session.
Right-Aligned Column Formatting
The program right-aligns calorie figures in a column at position T (set to 24) using the expression TAB T-LEN X$. The per-line calorie value is first converted to a string in subroutine 2000 and stored in X$; the total is handled analogously in subroutine 3000 using Y$. This is a standard ZX81 idiom for producing tidy tabular output without fixed-width formatting.
Weight Loss Calculation
The weight-loss estimate at line 140 uses the approximation of 7000 calories per kilogram of body fat (C/7000 for kg), then divides by 2.2 to convert to pounds. This figure (7000 kcal/kg) is a common rough estimate used in popular literature of the era; the more precise clinical value is approximately 7700 kcal/kg.
Input Wait Idiom
Line 1200 uses the busy-loop pattern IF INKEY$="" THEN GOTO 1200 to pause until a key is pressed. This is a standard ZX81 idiom. The “go again” logic at lines 180–200 re-enters at line 8, which re-runs the value-assignment subroutine (resetting C to 0 and re-declaring all activity variables) before presenting the activity list again.
Bugs and Anomalies
- Line 2000 has a mismatched delimiter:
REM **LINE UP ROUTINE"uses a closing quote instead of the expected asterisk, though this is harmless since it is inside a REM statement. - Line 110 accumulates
CusingVAL A$(N)*H(N), which is the same expression computed in GOSUB 2000 at line 2005. The subroutine result is discarded for accumulation purposes — the subroutine only provides the formatted stringX$for display. This is correct behaviour but slightly redundant. - The introductory key-wait at line 1200 waits for any key to be held down (INKEY$ non-empty) rather than detecting a fresh keypress, meaning it will also advance if the user is still holding a key from a previous input.
- If the user enters an activity name that does not match any of the 20 predefined variables,
VAL A$(N)will cause an error (variable not found), crashing the program.
Content
Source Code
1 REM EXERCISE AND CALORIES
8 GOSUB 500
10 GOSUB 1000
15 DIM A$(20,12)
17 DIM H(20)
20 REM **USER INPUT**
25 PRINT "HOW MANY ACTIVITIES?"
30 INPUT X
35 PRINT AT 0,22;X
40 PRINT
45 FOR N=1 TO X
50 PRINT "ACTIVITY?"
60 INPUT A$(N)
65 PRINT A$(N)
70 PRINT "HOURS?"
75 INPUT H(N)
80 PRINT H(N)
85 PRINT
90 NEXT N
91 REM **MAIN PROGRAM**
92 CLS
93 PRINT "ACTIVITY","CALORIES USED"
94 PRINT "\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\..\.."
95 PRINT
96 LET T=24
100 FOR N=1 TO X
103 GOSUB 2000
105 PRINT A$(N);TAB T-LEN X$;X$
110 LET C=C+(VAL A$(N)*H(N))
120 NEXT N
125 PRINT
127 GOSUB 3000
130 PRINT TAB 10;"TOTAL";TAB T-LEN Y$;Y$
135 PRINT
140 PRINT "%W%E%I%G%H%T% %L%O%S%S = ";C/7000;" KG/";(C/7000)/2.2;" LBS"
150 PRINT
160 PRINT
170 PRINT "GO AGAIN? (Y/N)"
175 INPUT C$
177 CLS
180 IF C$="Y" THEN GOTO 8
190 IF C$="N" THEN STOP
200 IF C$<>"Y" AND C$<>"N" THEN GOTO 170
500 REM **ASSIGN VALUES**
505 LET C=0
510 LET BADMINTON=300
520 LET BASEBALL=360
530 LET BASKETBALL=500
540 LET BICYCLING=400
550 LET BOWLING=400
560 LET DANCING=300
570 LET FOOTBALL=550
580 LET GOLF=250
590 LET HANDBALL=600
600 LET JOGGING=560
610 LET RACQUETBALL=600
620 LET RUNNING=900
630 LET SITTING=100
640 LET SKATING=400
650 LET SKIING=600
660 LET SOCCER=550
670 LET TABLE TENNIS=230
680 LET TENNIS=440
690 LET VOLLEYBALL=350
700 LET WALKING=300
800 RETURN
\n1000 REM **ACTIVITIES LIST**
\n1010 PRINT TAB 5;"%E%X%E%R%C%I%S%E% %A%N%D% %C%A%L%O%R%I%E%S"
\n1020 PRINT
\n1030 PRINT
\n1040 PRINT "DO YOU EXERCISE? BELOW IS A"
\n1050 PRINT "LIST OF SOME COMMON EXERCISE"
\n1060 PRINT "ACTIVITIES."
\n1080 PRINT "BADMINTON","RACQUETBALL"
\n1090 PRINT "BASEBALL","RUNNING"
\n1100 PRINT "BASKETBALL","SITTING"
\n1110 PRINT "BICYCLING","SKATING"
\n1120 PRINT "BOWLING","SKIING"
\n1130 PRINT "DANCING","SOCCER"
\n1140 PRINT "FOOTBALL","TABLE TENNIS"
\n1150 PRINT "GOLF","TENNIS"
\n1160 PRINT "HANDBALL","VOLLEYBALL"
\n1170 PRINT "JOGGING","WALKING"
\n1180 PRINT
\n1190 PRINT "HIT <ENTER> TO CONTINUE"
\n1200 IF INKEY$="" THEN GOTO 1200
\n1210 CLS
\n1220 RETURN
\n2000 REM **LINE UP ROUTINE"
\n2005 LET Y=VAL A$(N)*H(N)
\n2010 LET X$=STR$ Y
\n2015 LET Y=0
\n2020 RETURN
\n3000 LET Z=C
\n3010 LET Y$=STR$ Z
\n3020 LET Z=0
\n3030 RETURN
\n4000 SAVE "1015%1"
\n5000 RUN
Note: Type-in program listings on this website use ZMAKEBAS notation for graphics characters.
