--- title: "Exercise and Calories" id: 57263 type: "computer_media" slug: "exercise-and-calories" url: "http://localhost/computer_media/exercise-and-calories/" markdown_url: "http://localhost/computer_media/exercise-and-calories.md" published_at: "2024-10-04T07:47:16+00:00" modified_at: "2026-04-03T07:58:39+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2024/10/151_EnC.png" excerpt: "Enter your exercise activities and hours, and this BASIC program calculates calories burned plus estimated weight loss in both kilograms and pounds." category: - name: "Archived Media" slug: "archived-media" taxonomy: "category" url: "http://localhost/category/archived-media/" post_tag: - name: "Downloadable" slug: "downloadable" taxonomy: "post_tag" url: "http://localhost/tag/downloadable/" - name: "TS 1000" slug: "ts1000" taxonomy: "post_tag" url: "http://localhost/tag/ts1000/" model: - name: "Timex/Sinclair 1000" slug: "ts-1000" taxonomy: "model" url: "http://localhost/model/ts-1000/" genre: - name: "Home" slug: "home" taxonomy: "genre" url: "http://localhost/type/home/" media_contents: - id: 56734 title: "Timex Sinclair Public Domain Library Tape 1003" type: "computer_media" url: "http://localhost/computer_media/timex-sinclair-public-domain-library-tape-1003/" media_type: "Program" mediadate: "198x" images: - url: "http://localhost/wp-content/uploads/2024/10/151_EnC.png" media_type_tags: "Home" --- # Exercise and Calories 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: 1. **Line 8 / GOSUB 500** — initialises the calorie-per-hour constants and resets the accumulator `C`. 2. **Line 10 / GOSUB 1000** — displays the title screen and activity list, then waits for ENTER. 3. **Lines 15–90** — dimensions arrays and collects user input (activity names and hours). 4. **Lines 91–200** — main output loop: prints the activity table, totals, and weight-loss estimate; handles “go again” logic. 5. **Lines 500–800** — value-assignment subroutine for the 20 named activity variables. 6. **Lines 1000–1220** — introductory display subroutine. 7. **Lines 2000–2020** — per-activity formatting subroutine (converts calorie value to string `X$`). 8. **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 `C` using `VAL 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 string `X$` 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. ## 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 1000 REM **ACTIVITIES LIST** 1010 PRINT TAB 5;"%E%X%E%R%C%I%S%E% %A%N%D% %C%A%L%O%R%I%E%S" 1020 PRINT 1030 PRINT 1040 PRINT "DO YOU EXERCISE? BELOW IS A" 1050 PRINT "LIST OF SOME COMMON EXERCISE" 1060 PRINT "ACTIVITIES." 1080 PRINT "BADMINTON","RACQUETBALL" 1090 PRINT "BASEBALL","RUNNING" 1100 PRINT "BASKETBALL","SITTING" 1110 PRINT "BICYCLING","SKATING" 1120 PRINT "BOWLING","SKIING" 1130 PRINT "DANCING","SOCCER" 1140 PRINT "FOOTBALL","TABLE TENNIS" 1150 PRINT "GOLF","TENNIS" 1160 PRINT "HANDBALL","VOLLEYBALL" 1170 PRINT "JOGGING","WALKING" 1180 PRINT 1190 PRINT "HIT TO CONTINUE" 1200 IF INKEY$="" THEN GOTO 1200 1210 CLS 1220 RETURN 2000 REM **LINE UP ROUTINE" 2005 LET Y=VAL A$(N)*H(N) 2010 LET X$=STR$ Y 2015 LET Y=0 2020 RETURN 3000 LET Z=C 3010 LET Y$=STR$ Z 3020 LET Z=0 3030 RETURN 4000 SAVE "1015%1" 5000 RUN ```