--- title: "Shoppers Friend" id: 57011 type: "computer_media" slug: "shoppers-friend" url: "http://localhost/computer_media/shoppers-friend/" markdown_url: "http://localhost/computer_media/shoppers-friend.md" published_at: "2024-10-02T07:35:18+00:00" modified_at: "2026-03-30T21:20:13+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2024/10/35_Shop.png" excerpt: "Enter two brand names, quantities, and prices, and this vintage shopping helper instantly calculates which product gives you the best value per unit." 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: 56732 title: "Timex Sinclair Public Domain Library Tape 1001" type: "computer_media" url: "http://localhost/computer_media/timex-sinclair-public-domain-library-tape-1001/" media_type: "Program" mediadate: "198x" images: - url: "http://localhost/wp-content/uploads/2024/10/35_Shop.png" media_type_tags: "Home" --- # Shoppers Friend Shoppers Friend is a unit-price comparison program that helps users decide which of two branded products offers better value for money. The user enters a name, quantity, and price for each of two brands; the program then divides price by quantity to compute a per-unit cost and declares the cheaper brand the best buy. Three outcomes are handled: Brand 1 cheaper, Brand 2 cheaper, or equal value. Lines 700–720 implement a “press any key to continue” loop that would restart the comparison, though this code is never reached due to the STOP at line 530. *** ## Program Analysis ### Program Structure The program is divided into clearly separated functional blocks, using line-number ranges as logical sections: 1. **Lines 10–50:** Title display and decorative asterisk banner (15 asterisks via a `FOR` loop). 2. **Lines 100–180:** Input for the first brand — name (`X$`), quantity (`M`), and price (`N`). 3. **Lines 200–280:** Input for the second brand — name (`Y$`), quantity (`Q`), and price (`R`). 4. **Lines 300–330:** Comparison logic and routing via `IF…GOTO`. 5. **Lines 400–530:** Result display and program halt. 6. **Lines 600–610:** Equal-value handler, falls through to the unit-price display. 7. **Lines 700–720:** Dead code — a keypress-wait loop intended to restart the program. 8. **Lines 800–900:** Utility lines for saving and auto-running. ### Comparison Logic The core decision is made at lines 300–320 by computing the unit price as `N/M` (price divided by quantity) for Brand 1 and `R/Q` for Brand 2: | Line | Condition | Action | | --- | --- | --- | | 300 | `N/M = R/Q` | Jump to line 600 (equal value message) | | 310 | `N/M < R/Q` | Jump to line 400 (Brand 1 is best buy) | | 320 | (implicit else) | Brand 2 is best buy, fall through to line 500 | Lines 500–510 always print both unit prices regardless of which brand won, providing a useful cost breakdown before the program halts at line 530. ### Bugs and Anomalies - **Typo at line 320:** The message reads `"IS BCST BUY"` instead of `"IS BEST BUY"` — a transcription error that only affects Brand 2’s winning message. - **Dead code at lines 700–720:** The “press any key” loop and `GOTO 10` restart are unreachable because execution always hits `STOP` at line 530 or falls through to it via line 610. No path in the program leads to line 700. - **Division by zero risk:** If the user enters `0` for either quantity (`M` or `Q`), the division `N/M` or `R/Q` will produce an error with no guard. - **Missing dollar sign for Brand 2 price prompt:** Line 160 prompts `"PRICE: $"` for Brand 1, but line 260 prompts only `"PRICE: "` without the dollar symbol — an inconsistency in the UI. - **Currency symbol in unit display:** Line 500 prints `"UNIT = $"` but line 510 omits the dollar sign, again inconsistent. ### Key BASIC Idioms - The asterisk banner at lines 20–40 uses a `FOR…NEXT` loop with `PRINT "*";` (semicolon suppresses newline) — a common ZX81 technique for drawing horizontal rules without a dedicated graphics command. - Input values are echoed back to the screen immediately after entry (e.g. lines 120, 150, 180), which was necessary on the ZX81 since `INPUT` consumed the display area during entry. - The `REM` at line 5 stores the program title in inverse video characters, serving as an in-memory label visible in the program listing. ### Notable Structural Choice The equal-value branch at line 600 prints an equivalence message and then uses `GOTO 500` to fall into the same unit-price display used by the other branches. This avoids duplicating the display code and is a reasonable subroutine-like pattern without using `GOSUB`. ## Source Code ``` 5 REM %S%H%O%P%P%E%R%S% %F%R%I%E%N%D 10 PRINT "SHOPPERS FRIEND" 20 FOR L=1 TO 15 30 PRINT "*"; 40 NEXT L 50 PRINT 100 PRINT "FIRST BRAND NAME:" 110 INPUT X$ 120 PRINT X$ 130 PRINT "QUANTITY: "; 140 INPUT M 150 PRINT M 160 PRINT "PRICE: $"; 170 INPUT N 180 PRINT N 200 PRINT "SECOND BRAND NAME:" 210 INPUT Y$ 220 PRINT Y$ 230 PRINT "QUANTITY: "; 240 INPUT Q 250 PRINT Q 260 PRINT "PRICE: "; 270 INPUT R 280 PRINT R 300 IF N/M=R/Q THEN GOTO 600 310 IF N/M