--- title: "Utility Bill Audit" id: 64561 type: "computer_media" slug: "utility-bill-audit" url: "http://localhost/computer_media/utility-bill-audit/" markdown_url: "http://localhost/computer_media/utility-bill-audit.md" published_at: "2026-03-02T02:46:59+00:00" modified_at: "2026-03-30T21:46:21+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2026/03/SCR-20260301-svmz.png" excerpt: "A complete household utility auditor that handles three-tier electric, gas, water, and shared phone bills — all driven by editable DATA statements." 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 2068" slug: "ts2068" taxonomy: "post_tag" url: "http://localhost/tag/ts2068/" model: - name: "Timex/Sinclair 2068" slug: "ts-2068" taxonomy: "model" url: "http://localhost/model/ts-2068/" genre: - name: "Finance" slug: "finance" taxonomy: "genre" url: "http://localhost/type/finance/" - name: "Home" slug: "home" taxonomy: "genre" url: "http://localhost/type/home/" media_contents: - id: 60550 title: "Fort Worth TS2068 Club Library Tape" type: "computer_media" url: "http://localhost/computer_media/fort-worth-ts2068-club-library-tape/" media_type: "Program" download_url: "https://archive.org/download/timex-sinclair-software-archive/Utility%20Bill%20Audit%20%28198x%29%28TS2068%29%28US%29%28Program%29.zip" mediadate: "198x" images: - url: "http://localhost/wp-content/uploads/2026/03/SCR-20260301-svmz.png" media_type_tags: "Finance, Home" --- This program audits utility bills — electric, gas, water, and telephone — by accepting meter readings and billing period lengths, then calculating charges using up to three consumption tiers plus tax and manual adjustments. Each utility’s rate structure (monthly minimum, tier thresholds, and per-unit rates) is loaded from DATA statements at startup into parallel arrays. The phone bill module handles multiple residents sharing a line, collecting individual long-distance call charges one at a time into the w() array and splitting the base service charge proportionally. Results can be split among a configurable number of occupants, with the split count also stored in a DATA-driven array n(). *** ## Program Structure The program is organised as a menu dispatcher with a shared calculation subroutine. Execution begins at line `340`, which loads all rate data from `DATA` statements into arrays before falling through to the menu at line `410`. The main menu (lines `410`–`555`) routes to one of four utility handlers or an “all utilities” batch mode. 1. **Lines 340–400**: Data initialisation — reads occupant counts `n()`, then per-utility parameters into parallel arrays. 2. **Lines 410–555**: Menu display and dispatch. 3. **Lines 560–1010**: Shared metered-utility subroutine (electric, gas, water) — prompts for readings, computes tiered charge, prints summary, offers split. 4. **Lines 1110–1580**: Phone bill handler — loops over `n(4)` persons, collects individual LD call amounts, verifies each entry, totals and taxes. 5. **Lines 1590–1630**: Batch mode — iterates utilities 1–3 via the shared subroutine, then falls through to the phone handler. 6. **Lines 1640–1690**: `DATA` block and `STOP`. ## Data Layout All rate parameters are held in parallel arrays indexed by utility number `x` (1=Electric, 2=Gas, 3=Water, 4=Phone). | Array | Meaning | | --- | --- | | `n(x)` | Number of occupants sharing the bill | | `a$(x)` | Utility name (e.g. “Electric”) | | `b$(x)` | Unit name (e.g. “KWH”, “CCF”) | | `m(x)` | Monthly minimum / base service charge | | `z(x)` | Tax rate (fractional) | | `a(x)` | Tier 1 upper threshold (units) | | `b(x)` | Tier 2 upper threshold (units) | | `c(x)` | Tier 1 rate (per unit) | | `d(x)` | Tier 2 rate (per unit) | | `e(x)` | Tier 3 rate (per unit) | Gas and water are effectively single-tier utilities: gas uses an astronomically high tier threshold (99999) so only tier 1 ever applies, while water has a tier 2 threshold of 99999 to suppress the third tier. ## Tiered Rate Calculation The metered-utility subroutine implements a standard block-rate tariff at lines `740`–`800`: - **Tier 1** (`u ≤ a(x)`): `t = m(x) + c(x)*u` - **Tier 2** (`a(x) < u ≤ b(x)`): `t = m(x) + c(x)*a(x) + d(x)*(u-a(x))` - **Tier 3** (`u > b(x)`): full staircase including `e(x)*(u-b(x))` Tax is computed as `t1 = t * z(x)` and the adjustment total `a1` (from subroutine at line `110`) is added last to give the final bill `t3`. ## Key BASIC Idioms - **Sliced string printing**: `a$(x, TO 8)` and `b$(x, TO 8)` trim the fixed-length DIM strings to their content without trailing spaces causing layout problems. - **Integer rounding**: `INT (value * 100) / 100` is used throughout to display monetary amounts to two decimal places, since there is no built-in formatting function. - **Compound condition guard**: Line `540` uses `IF (p<1)+(p>6) THEN` — boolean addition as an OR, a classic Sinclair BASIC idiom. - **Global variable reuse**: The adjustment accumulator `a1`, control variable `x`, and loop index `i` are all unscoped globals shared across subroutine calls. - **Input prompt confirmation**: Line `605`/`635`/`665` use `PRINT ,value` after `INPUT` to echo the entered value with a tab, providing visible confirmation. ## Phone Bill Handler The phone module (lines `1110`–`1580`) is structurally distinct. It loops over `n(4)` persons, collecting LD call amounts one at a time into the `w()` array (dimensioned to 50 entries). After collection, a verification loop iterates over each call (`FOR j=1 TO i-1`) and offers a correction prompt before computing the per-person total. ## Source Code ``` 10 REM A program for utility bills 90 DIM a$(4,8): DIM b$(4,8): DIM a(3): DIM b(3): DIM m(4): DIM c(3): DIM d(3): DIM e(3): DIM w(50): DIM z(4): DIM n(4) 100 GO TO 340 110 LET a1=0 120 PRINT " Input adjustments to bill (+ or - , ""0"" when done)" 130 INPUT f 140 LET a1=a1+f 150 IF f=0 THEN GO TO 170 160 GO TO 130 170 GO SUB 250 180 GO SUB 290 190 RETURN 200 CLS 210 RETURN 220 PRINT " ";a$(x, TO 8);" Bill (cont')" 230 PRINT 240 RETURN 250 FOR i=1 TO 3 260 PRINT 270 NEXT i 280 RETURN 290 PRINT "INPUT ""C"" to continue"; 300 INPUT c$ 310 GO SUB 200 320 RETURN 340 FOR i=1 TO 4 350 READ n(i) 360 NEXT i 370 FOR i=1 TO 3 380 READ a$(i),b$(i),m(i),z(i),a(i),b(i),c(i),d(i),e(i) 390 NEXT i 400 READ a$(4),m(4),z(4) 410 GO SUB 200 420 PRINT " UTILITY BILL AUDIT" 430 GO SUB 250 440 PRINT " 1. Electric Bill" 450 PRINT " 2. Gas Bill" 460 PRINT " 3. Water Bill" 470 PRINT " 4. Phone Bill" 480 PRINT " 5. All of the above" 490 PRINT " 6. Exit" 500 PRINT : PRINT 520 PRINT " CHOOSE an option "; 530 INPUT p 540 IF (p<1)+(p>6) THEN GO TO 530 550 IF p=1 THEN GO TO 1020 551 IF p=2 THEN GO TO 1050 552 IF p=3 THEN GO TO 1080 553 IF p=4 THEN GO TO 1110 554 IF p=5 THEN GO TO 1590 555 IF p=6 THEN GO TO 1690 560 GO SUB 200 570 PRINT " ";a$(x, TO 8);" Bill" 580 PRINT 590 PRINT "Previous meter reading:" 600 INPUT e1 605 PRINT ,e1 610 PRINT 620 PRINT "Present meter reading:" 630 INPUT e2 635 PRINT ,e2 640 PRINT 650 PRINT "Input days in the billing period:" 660 INPUT g 665 PRINT ,g 670 GO SUB 250 680 GO SUB 290 690 GO SUB 200 700 GO SUB 220 710 GO SUB 110 720 LET u=e2-e1 730 LET y=u/g 740 IF u>b(x) THEN GO TO 800 750 IF u>a(x) THEN GO TO 780 760 LET t=m(x)+c(x)*u 770 GO TO 810 780 LET t=m(x)+c(x)*a(x)+d(x)*(u-a(x)) 790 GO TO 810 800 LET t=m(x)+c(x)*a(x)+d(x)*(b(x)-a(x))+e(x)*(u-b(x)) 810 LET t1=t*z(x) 820 LET t2=t+t1 830 LET t3=t2+a1 840 GO SUB 200 850 GO SUB 220 860 PRINT "Use for the period is ";INT (u*100)/100;" ";b$(x, TO 8) 870 PRINT 880 PRINT "Use/Day is ";INT (y*100)/100;" ";b$(x, TO 8);" or $"; 890 PRINT INT (t2/g*100)/100;"/Day including tax" 900 PRINT 910 PRINT a$(x, TO 8);" Bill:" 920 PRINT " W/out tax :$";INT (t*100)/100 930 PRINT " Tax is :$";INT (t1*100)/100 940 PRINT " ADJ'TS :$";a1 950 PRINT 960 PRINT " *TOTAL* :$";INT (t3*100)/100 970 IF n(x)=1 THEN GO TO 990 980 PRINT "SPLIT ";n(x);" ways:$";INT (t3/n(x)*100)/100 990 PRINT 1000 GO SUB 290 1010 RETURN 1020 LET x=1 1030 GO SUB 560 1040 GO TO 430 1050 LET x=2 1060 GO SUB 560 1070 GO TO 430 1080 LET x=3 1090 GO SUB 560 1100 GO TO 430 1110 GO SUB 200 1120 LET x=4 1130 PRINT " ";a$(x, TO 8);" Bill" 1140 PRINT 1150 GO SUB 110 1160 FOR k=1 TO n(x) 1170 LET i=1 1180 IF n(x)=1 THEN GO TO 1200 1190 PRINT "For person #";k;","; 1200 PRINT "INPUT charge for each long distance call (INPUT ""0"" when done)" 1210 INPUT w(i) 1220 IF w(i)=0 THEN GO TO 1250 1230 LET i=i+1 1240 GO TO 1210 1250 GO SUB 200 1260 PRINT " Person #";k;","; 1270 FOR j=1 TO -1 1280 PRINT "Call #";j;" :$";w(j) 1290 PRINT 1300 PRINT "Is the correct? (Y/N)" 1310 INPUT c$ 1320 IF c$="Y" OR c$="y" THEN GO TO 1350 1330 PRINT "Type in correction" 1340 INPUT w(j) 1350 PRINT 1360 NEXT j 1370 GO SUB 200 1380 GO SUB 220 1390 LET t=0 1400 FOR j=1 TO i-1 1410 LET t=t+w(j) 1420 NEXT j 1430 PRINT "SERVICE: $";INT (m(x)/n(x)*100)/100 1440 PRINT 1450 PRINT "LD calls: $";t 1460 PRINT 1470 PRINT "ADJ'TS : $";INT (a1/n(x)*100)/100 1480 PRINT 1490 LET t1=t+INT (m(x)/n(x)*100)/100 1500 LET t2=INT (t1*z(x)*100)/100 1510 PRINT "TOTAL TAX: $";t2 1520 PRINT : PRINT 1540 PRINT " TOTAL BILL: $";t1+t2+INT (a1/n(x)*100)/100 1550 GO SUB 250 1560 GO SUB 290 1570 NEXT k 1580 GO TO 430 1590 FOR h=1 TO 3 1600 LET x=h 1610 GO SUB 560 1620 NEXT h 1630 GO TO 1110 1640 DATA 2,1,2,4 1650 DATA "Electric","KWH",5.40,0,350,1300,.0495,.0565,.0541 1660 DATA "Gas","CCF",4.04,0,99999,99999,.49541,0,0 1670 DATA "Water","CCF",3.26,0,500,99999,.144,.160,0 1680 DATA "Phone",13.50,.03 1690 STOP ```