--- title: "Stamp Inventory" id: 71367 type: "computer_media" slug: "stamp-inventory" url: "http://localhost/computer_media/stamp-inventory/" markdown_url: "http://localhost/computer_media/stamp-inventory.md" published_at: "2026-09-02T07:12:32+00:00" modified_at: "2026-09-02T07:12:33+00:00" author: "David Anderson" featured_image: url: "http://localhost/wp-content/uploads/2026/09/stamp-inventory.png" excerpt: "A seven-function stamp collection manager that stores up to 150 stamps with names and quantities, featuring search, add, delete with array compaction, and quantity adjustment." 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/" indiv: - name: "Stephen Justham" slug: "stephen-justham" taxonomy: "indiv" url: "http://localhost/indiv/stephen-justham/" genre: - name: "Hobby" slug: "hobby" taxonomy: "genre" url: "http://localhost/type/hobby/" media_type: "Program" programmers: - name: "Stephen Justham" slug: "stephen-justham" taxonomy: "indiv" url: "http://localhost/indiv/stephen-justham/" download_url: "https://archive.org/download/timex-sinclair-software-archive/Stamp%20Inventory%20(198x)(Justham%2C%20Stephen)(TS2068)(US)(Program).zip" mediadate: "198x" images: - url: "http://localhost/wp-content/uploads/2026/09/stamp-inventory.png" media_type_tags: "Hobby" --- # Stamp Inventory Stamp Inventory is a menu-driven stamp collection management program that supports up to 150 stamps, storing each stamp’s name (up to 15 characters) and quantity in parallel arrays. It offers seven functions: starting a fresh list, searching by name, browsing the full listing, adding new entries, adjusting quantities with signed increments, deleting stamps with automatic array compaction, and exiting with a tape-save prompt. The delete routine shifts all subsequent array elements down one position to close gaps, maintaining a contiguous list. The search function uses a dynamically dimensioned temporary string array sized to the search term length for substring-matched comparison. *** ### Program Structure The program is organized as a main menu dispatcher with dedicated subroutines branched via `GO TO`. Lines 40–260 form the main menu and input loop. The core functional blocks are: | Lines | Function | | --- | --- | | 290–620 | Start a new stamp list | | 630–780 | Check (browse) stamp list | | 790–1100 | Add a new stamp | | 1110–1370 | Change quantity of a stamp | | 1380–1830 | Delete (erase) a stamp | | 1840–1920 | Exit with tape-save prompt | | 1930–2120 | Search for a stamp by name | | 2130 | SAVE with auto-run | Two utility subroutines are defined at lines 270 and 280. Line 270 prints a decorative separator line of asterisks. Line 280 prints a formatted row showing stamp number, name, and quantity using `TAB` stops. ### Data Storage Stamp data is held in two parallel structures declared at lines 320–330: - `DIM I$(151,15)` — a string array of 151 entries, each 15 characters wide, holding stamp names. - `DIM Q(151)` — a numeric array of 151 entries holding quantities. The variable `N` tracks the current count of stamps in the list, acting as a logical end-of-file marker. Only indices 1 through `N` are considered active. The arrays are dimensioned to 151 to give one extra slot beyond the stated 150-stamp limit, though index 0 is unused in BASIC’s 1-based convention here. ### Key BASIC Idioms The program uses several idiomatic patterns common in BASIC of this era: - The `TAB PI` expression in the subroutine at line 280 evaluates to `TAB 3` (since `INT PI = 3`), a compact way to achieve a fixed indent without writing a literal integer. - Menu options use embedded `\\{18}\\{0}` and `\\{18}\\{1}` escape sequences (PAPER/INK attribute control codes within PRINT statements) to highlight option numbers in inverse or contrasting color. - The `INPUT C$` followed by `IF C$="C"` pattern is used in multiple places (add stamps, exit) to detect a sentinel string that triggers a mode change. - `POKE 23658,8` at line 10 enables CAPS LOCK, ensuring uppercase input for the string comparisons used in stamp name matching and command detection. ### Delete with Array Compaction The erase routine (lines 1380–1830) is the most algorithmically complex section. When the user marks a stamp for deletion with “D”, lines 1710–1770 shift all subsequent elements down one index position: - `LET I$(B)=I$(B+1)` and `LET Q(B)=Q(B+1)` are executed in a `FOR B=Y TO 150` loop, effectively closing the gap left by the deleted entry. - `N` is decremented at line 1780 to reflect the reduced count. - The loop variable `Y` records the position of the deleted stamp and `X` is used to resume display iteration correctly after the shift. ### Search Function The search (lines 1930–2120) accepts a full stamp name via `INPUT C$`, then at line 1980 dynamically dimensions a temporary array `DIM M$(151,J)` where `J = LEN C$`. Each entry of `I$` is copied into `M$` and compared to `C$`. Because fixed-length string arrays in BASIC pad entries with spaces, truncating the comparison width to match the search term length via the `M$` dimension is an effective workaround for exact-match searching against padded strings. Only the first matching entry is found; the loop does not continue to find duplicates. ### Bugs and Anomalies - The “Start New List” routine at line 310 prompts for the number of stamps to list, storing this in `N`, but then the `FOR B=1 TO 151` loop at line 390 iterates up to 151 regardless. The `IF X=N THEN GO TO 500` guard at line 480 exits at the right count, but only if `N` is within range. If `N > 150` is entered, the loop runs to 151. - The browse loop at line 670 iterates `FOR B=1 TO 300`, well beyond the array bounds of 151. If `N` is never equal to `B` within that range (e.g., due to a corrupted `N`), an out-of-bounds subscript error would occur. - Line 610 reads `IF P=1 THEN GO TO 240`, which branches to the “Erase a Stamp” section rather than the intended re-do of the new stamp list; the intent was likely `GO TO 290`. The fallthrough at line 620 returns to the main menu correctly for any other value. - The exit routine at line 1910 branches to line 2130 on input “C” to save the program. This `SAVE "STAMPS" LINE 1` saves the entire program with auto-run, which also re-executes `DIM I$` and `DIM Q`, erasing the data arrays on reload — data is not saved separately from the program. - Lines 1820–1830 (`LET N=N-1 : GO TO 1650`) appear unreachable; no code path leads to line 1820 via normal execution. ## Source Code ``` 10 BORDER 0:PAPER 0:INK 7:CLS :POKE 23658,8 20 REM STEPHEN A. JUSTHAM 8-5-81 30 REM "STAMP INVENTORY-150" 40 CLS :PRINT TAB 7;"************** " 50 PRINT " STAMP INVENTORY-150" 60 PRINT TAB 7;"************** " 70 PRINT "THIS PROGRAM HANDLES 150 STAMPS" 80 PRINT TAB 7;"************** " 90 PRINT '"DO YOU WANT TO:" 100 PRINT '" \{18}\{0}\{18}\{1}1\{18}\{0})START A NEW STAMP LIST?" 110 PRINT " \{18}\{1}2\{18}\{0})SEARCH FOR A STAMP?" 120 PRINT " \{18}\{1}3\{18}\{0})CHECK STAMP LIST?" 130 PRINT " \{18}\{1}4\{18}\{0})ADD A NEW STAMP TO LIST?" 140 PRINT " \{18}\{1}5\{18}\{0})CHANGE QUANTITY OF A STAMP?" 150 PRINT " \{18}\{1}6\{18}\{0})ERASE A STAMP?" 160 PRINT " \{18}\{1}7\{18}\{0})EXIT PROGRAM?" 170 INPUT "ENTER YOUR CHOICE,1-7.";A 180 CLS 190 IF A=1 THEN GO TO 290 200 IF A=2 THEN GO TO 1930 210 IF A=3 THEN GO TO 630 220 IF A=4 THEN GO TO 790 230 IF A=5 THEN GO TO 1110 240 IF A=6 THEN GO TO 1380 250 IF A=7 THEN GO TO 1840 260 GO TO 170 270 PRINT "********************************":RETURN 280 PRINT TAB PI;B; TAB 11;I$(B); TAB 26;Q(B) 290 CLS :PRINT " START A NEW STAMP LIST" 300 GO SUB 270 310 PRINT '"HOW MANY STAMPS TO BE LISTED?" 320 DIM I$(151,15) 330 DIM Q(151) 340 INPUT N 350 CLS 360 PRINT '"STAMP " 370 PRINT " NO. " 380 PRINT 390 FOR B=1 TO 151 400 PRINT " ";B; 410 PRINT " STAMP NAME? = "; 420 INPUT I$(B) 430 PRINT I$(B); 440 PRINT " HOW MANY? = "; 450 INPUT Q(B) 460 PRINT Q(B) 470 LET X=B 480 IF X=N THEN GO TO 500 490 NEXT B 500 CLS 510 PRINT '"ITEM NO. ITEM NAME QUANT." 520 FOR B=1 TO 150 530 GO SUB 280 540 LET X=B 550 IF X=N THEN GO TO 570 560 NEXT B 570 PRINT '"END OF FILE." 580 PRINT '"TYPE 1) TO RE-DO THE STAMP LIST, 2) TO RETURN TO START." 590 INPUT P 600 CLS 610 IF P=1 THEN GO TO 240 620 IF P <>1 THEN GO TO 40 630 CLS :PRINT TAB 7;"STAMP LISTING" 640 GO SUB 270 650 PRINT ''"ITEM NO. ITEM NAME QUANT." 660 PRINT 670 FOR B=1 TO 300 680 LET X=B 690 GO SUB 280 700 IF X <>N THEN GO TO 730 710 PRINT '"END OF FILE." 720 GO TO 740 730 NEXT B 740 PRINT '"TYPE 1) TO EXAMINE LIST, 2) TO RETURN TO START." 750 INPUT D 760 CLS 770 IF D=1 THEN GO TO 630 780 IF D <>1 THEN GO TO 40 790 CLS :PRINT TAB 6;"ADD STAMP TO INVENTORY" 800 GO SUB 270 810 PRINT '"WHEN YOU WISH TO END NEW ENTRIES,TYPE ""RETURN .""" 820 PRINT ''"ITEM NO. ITEM NAME QUANT." 830 PRINT 840 FOR B=1 TO 150 850 GO SUB 280 860 LET X=B 870 LET G=N 880 IF B=150 THEN GO TO 910 890 IF X=N THEN GO TO 950 900 NEXT B 910 PRINT "SORRY,FILE IS FULL." 920 PRINT "TYPE <\{18}\{1}C\{18}\{0}> TO RETURN TO START." 930 STOP 940 GO TO 40 950 LET B=B+1 960 LET N=B 970 IF G=B THEN GO TO 910 980 PRINT '"STAMP NO.";B 990 PRINT " STAMP NAME? "; 1000 INPUT C$ 1010 PRINT C$ 1020 LET I$(B)=C$ 1030 IF C$="C" THEN GO TO 1080 1040 PRINT " HOW MANY? "; 1050 INPUT Q(B) 1060 CLS 1070 GO TO 950 1080 CLS 1090 LET N=B-1 1100 GO TO 40 1110 CLS :PRINT " CHANGE QUANTITY OF A STAMP" 1120 GO SUB 270 1130 PRINT ''"SELECT STAMP TO BE CHANGED BY <\{18}\{1}STAMP NO.\{18}\{0}>" 1140 PRINT '"STAMP NO. STAMP NAME QUANT." 1150 PRINT 1160 FOR B=1 TO 150 1170 LET X=B 1180 GO SUB 280 1190 IF X <>N THEN GO TO 1220 1200 PRINT '"END OF FILE." 1210 GO TO 1230 1220 NEXT B 1230 PRINT ''"SELECT STAMP TO BE CHANGED BY <\{18}\{1}STAMP NO.\{18}\{0}>" 1240 INPUT B 1250 CLS 1260 PRINT "STAMP NO. ";B;" IS ";I$(B);" WHICH CURRENTLY CONTAINS ";Q(B);" STAMPS." 1270 PRINT "USE A ""MINUS""SIGN TO REDUCE THE QUANTITY." 1280 INPUT "INPUT QUANTITY CHANGE.";K 1290 CLS 1300 LET Q(B)=Q(B)+K 1310 PRINT "STAMP NO. ";B;", ";I$(B);" NOW HAS ";Q(B);" STAMPS. " 1320 PRINT '"TYPE \{18}\{1}1\{18}\{0}) TO CHANGE ANOTHER STAMP \{18}\{1}2\{18}\{0}) TO RETURN TO START \{18}\{1}3\{18}\{0}) TO REVIEW THIS LISTING." 1330 INPUT R 1340 CLS 1350 IF R=1 THEN GO TO 1230 1360 IF R=2 THEN GO TO 40 1370 IF R=3 THEN GO TO 1110 1380 CLS :PRINT TAB 2;"DELETE A STAMP FROM INVENTORY" 1390 GO SUB 270 1400 PRINT '"EACH STAMP WILL APPEAR ONE AT A TIME." 1410 PRINT '" 1) TO SAVE TYPE <\{18}\{1}S\{18}\{0}>." 1420 PRINT '" 2) TO DELETE TYPE <\{18}\{1}D\{18}\{0}>." 1430 PRINT '" 3) TO GO TO START TYPE <\{18}\{1}T\{18}\{0}>." 1440 PRINT '"**********" 1450 PRINT '"STAMP NAME" 1460 PRINT 1470 LET X=1 1480 FOR B=X TO 300 1490 IF I$(B)="" THEN GO TO 1630 1500 LET Y=B 1510 LET X=B 1520 LET Z=N 1530 PRINT TAB 3;I$(B);"#"; 1540 INPUT Z$ 1550 PRINT Z$ 1560 IF Z$="S" THEN GO TO 1630 1570 IF Z$="D" THEN GO TO 1710 1580 IF Z$="T" THEN GO TO 1610 1590 CLS 1600 GO TO 1400 1610 CLS 1620 GO TO 40 1630 IF B=N THEN GO TO 1650 1640 NEXT B 1650 PRINT ''"END OF FILE." 1660 PRINT '"TYPE ""1"" IF YOU WISH TO DELETEOTHER STAMPS,TYPE ""2 "" TO RETURN TO START OF PROGRAM." 1670 INPUT W 1680 CLS 1690 IF W=1 THEN GO TO 1380 1700 IF W <>1 THEN GO TO 40 1710 LET I$(B)="" 1720 LET Q(B)=0 1730 FOR B=Y TO 150 1740 LET I$(B)=I$(B+1) 1750 LET Q(B)=Q(B+1) 1760 IF Z=B THEN GO TO 1780 1770 NEXT B 1780 LET N=N-1 1790 LET B=X 1800 IF N=B THEN GO TO 1650 1810 GO TO 1480 1820 LET N=N-1 1830 GO TO 1650 1840 CLS :PRINT AT 6,0;"YOU HAVE INDICATED TO EXIT THIS PROGRAM." 1850 PRINT '"IF YOU HAVE MADE ANY CHANGES" 1860 PRINT ':GO SUB 270 1870 PRINT "*DO NOT FORGET TO RE-LOAD TAPE*" 1880 GO SUB 270 1890 PRINT '"TO SAVE THIS PROGRAM AS CHANGED PREPARE THE TAPE RECORDER, BEGINRECORDING,AND TYPE ""C.""" 1900 INPUT X$ 1910 IF X$="C" THEN GO TO 2130 1920 GO TO 40 1930 CLS :PRINT TAB 7;"SEARCH FOR A STAMP" 1940 GO SUB 270 1950 PRINT '"TYPE THE NAME OF THE STAMP YOU ARE SEARCHING FOR." 1960 INPUT C$ 1970 LET J= LEN C$ 1980 DIM M$(151,J) 1990 FOR B=1 TO 150 2000 LET M$(B)=I$(B) 2010 IF C$=M$(B) THEN GO TO 2050 2020 NEXT B 2030 PRINT '"NO SUCH STAMP HAS BEEN FOUND IN THE LISTING." 2040 GO TO 2080 2050 PRINT '''"THERE ARE >> ";Q(B);" <<" 2060 PRINT '" ** ";C$;" **"; 2070 PRINT ''"LOCATED IN THE LISTING." 2080 PRINT '''" \{18}\{1}1\{18}\{0}) TO SEARCH FOR ANOTHER ITEM, \{18}\{1}2\{18}\{0}) TO RETURN TO START." 2090 INPUT U 2100 CLS 2110 IF U=1 THEN GO TO 1930 2120 IF U <>1 THEN GO TO 40 2130 SAVE "STAMPS" LINE 1 ```