The Secret Guide to Computers

 home » read » qbasic 4


 
 

Subscripts

Instead of being a single string, x$ can be a whole list of strings, like this:

      "love"

      "hate"

      "kiss"

x$=   "kill"

      "peace"

      "war"

      "why"

Here’s how to make x$ be that list of strings.…

Begin your program as usual, by saying:

CLS

Then say:

DIM x$(7)

That line says x$ will be a list of 7 strings. DIM means dimension; the line says the dimension of x$ is 7.

Next, tell the computer what strings are in x$. Type these lines:

x$(1) = "love"

x$(2) = "hate"

x$(3) = "kiss"

x$(4) = "kill"

x$(5) = "peace"

x$(6) = "war"

x$(7) = "why"

That says x$’s first string is “love”, x$’s second string is “hate”, etc.

If you want the computer to print all those strings, type this:

FOR i = 1 TO 7

  PRINT x$(i)

NEXT

That means: print all the strings in x$. The computer will print:

love

hate

kiss

kill

peace

war

why

That program includes a line saying x$(1) = “love”. Instead of saying x$(1), math books say:

x1

The “1” is called a subscript.

Similarly, in the line saying x$(2) = “hate”, the number 2 is a subscript. Some programmers pronounce that line as follows: “x string, subscripted by 2, is hate”. Hurried programmers just say: “x string 2 is hate”.

In that program, x$ is called an array (or matrix). Definition: an array (or matrix) is a variable that has subscripts.


Subscripted DATA

That program said x$(1) is “love”, and x$(2) is “hate”, and so on. This program does the same thing, more briefly:

CLS

DIM x$(7)

DATA love,hate,kiss,kill,peace,war,why

FOR i = 1 TO 7

  READ x$(i)

NEXT

FOR i = 1 TO 7

  PRINT x$(i)

NEXT

The DIM line says x$ will be a list of 7 strings. The DATA line contains a list of 7 strings. The first FOR..NEXT loop makes the computer READ those strings and call them x$. The bottom FOR...NEXT loop makes the computer print those 7 strings.

In that program, the first four lines say:

CLS

DIM

DATA

FOR i

Most practical programs begin with those four lines.

Let’s lengthen the program, so that the computer prints all this:

love

hate

kiss

kill

peace

war

why

 

why love

why hate

why kiss

why kill

why peace

why war

why why

That consists of two verses. The second verse resembles the first verse, except that each line of the second verse begins with “why”.

To make the computer print all that, just add the shaded lines to the program:

CLS

DIM x$(7)

DATA love,hate,kiss,kill,peace,war,why

FOR i = 1 TO 7

  READ x$(i)

NEXT

FOR i = 1 TO 7

  PRINT x$(i)

NEXT

PRINT               

FOR i = 1 TO 7      

  PRINT "why "; x$(i)

NEXT                

The shaded PRINT line leaves a blank line between the first verse and the second verse. The shaded FOR..NEXT loop, which prints the second verse, resembles the FOR...NEXT loop that printed the first verse but prints “why” before each x$(i).

Let’s add a third verse, which prints the words in reverse order:

why

war

peace

kill

kiss

hate

love

Before printing that third verse, print a blank line:

PRINT

Then print the verse itself. To print the verse, you must print x$(7), then print x$(6), then print x$(5), etc. To do that, you could say:

PRINT x$(7)

PRINT x$(6)

PRINT x$(5)

etc.

But this way is shorter:

FOR i = 7 TO 1 STEP -1

  PRINT x$(i)

NEXT

Numeric arrays

Let’s make y be this list of five numbers: 100, 94, 201, 8.3, and -7. To begin, tell the computer that y will consist of five numbers:

CLS

DIM y(5)

Next, tell the computer what the six numbers are:

DATA 100,94,201,8.3,-7

Make the computer READ all that data:

FOR i = 1 TO 5

  READ y(i)

NEXT

To make the computer PRINT all that data, type this:

FOR i = 1 TO 5

  PRINT y(i)

NEXT

If you want the computer to add those 5 numbers together and print their sum, say:

PRINT y(1) + y(2) + y(3) + y(4) + y(5)


Strange example

Getting tired of x and y? Then pick another letter! For example, you can play with z:

Silly, useless program      What the program means

CLS                           CLear the Screen

DIM z(5)                   z will be a list of 5 numbers

FOR i = 2 TO 5

  z(i) = i * 100       z(2)=200; z(3)=300; z(4)=400; z(5)=500

NEXT

z(1) = z(2) - 3       z(1) is 200 - 3, so z(1) is 197

z(3) = z(1) - 2       z(3) changes to 197 - 2, which is 195

FOR i = 1 TO 5

  PRINT z(i)        print z(1), z(2), z(3), z(4), and z(5)

NEXT

The computer will print:

 197

 200

 195

 400

 500

Problems and solutions

Suppose you want to analyze 20 numbers. Begin your program by saying:

CLS

DIM x(20)

Then type the 20 numbers as data:

DATA etc.

Tell the computer to READ the data:

FOR i = 1 TO 20

  READ x(i)

NEXT

Afterwards, do one of the following, depending on which problem you want to solve.…

Print all the values of x Solution:

FOR i = 1 TO 20

  PRINT x(i)

NEXT

Print all the values of x, in reverse order Solution:

FOR i = 20 TO 1 STEP -1

  PRINT x(i)

NEXT

Print the sum of all the values of x In other words, print x(1) + x(2) + x(3)+… + x(20). Solution: start the sum at 0 —

sum = 0

and then increase the sum, by adding each x(i) to it:

FOR i = 1 TO 20

  sum = sum + x(i)

NEXT

Finally, print the sum:

PRINT "The sum of all the numbers is"; sum

Find the average of x In other words, find the average of the 20 numbers. Solution: begin by finding the sum —

sum = 0

FOR i = 1 TO 20

  sum = sum + x(i)

NEXT

and then divide the sum by 20:

PRINT "The average is"; sum / 20

Find whether any of x’s values is 79.4 In other words, find out whether 79.4 is a number in the list. Solution: if x(i) is 79.4, print “Yes” —

FOR i = 1 TO 20

  IF x(i)=79.4 THEN PRINT "Yes, 79.4 is in the list": END

NEXT

otherwise, print “No”:

PRINT "No, 79.4 is not in the list"

In x’s list, count how often 79.4 appears Solution: start the counter at zero —

counter = 0

and increase the counter each time you see the number 79.4:

FOR i = 1 TO 20

  IF x(i) = 79.4 THEN counter = counter + 1

NEXT

Finally, print the counter:

PRINT "The number 79.4 appears"; counter; "times"

Print all x values that are negative In other words, print all the numbers that have minus signs. Solution: begin by announcing your purpose —

PRINT "Here are the values that are negative:"

and then print the values that are negative; in other words, print each x(i) that’s less than 0:

FOR i = 1 TO 20

  IF x(i) < 0 THEN PRINT x(i)

NEXT

Print all x values that are above average Solution: find the average —

sum = 0

FOR i = 1 TO 20

  sum = sum + x(i)

NEXT

average = sum / 20

then announce your purpose:

PRINT "The following values are above average:"

Finally, print the values that are above average; in other words, print each x(i) that’s greater than average:

FOR i = 1 TO 20

  IF x(i) > average THEN PRINT x(i)

NEXT

Find the biggest value of x In other words, find which of the 20 numbers is the biggest. Solution: begin by assuming that the biggest is the first number —

biggest = x(1)

but if you find another number that’s even bigger, change your idea of what the biggest is:

FOR i = 2 TO 20

  IF x(i) > biggest THEN biggest = x(i)

140 NEXT

Afterwards, print the biggest:

PRINT "The biggest number in the list is"; biggest

Find the smallest value of x In other words, find which of the 20 numbers is the smallest. Solution: begin by assuming that the smallest is the the first number —

smallest = x(1)

but if you find another number that’s even smaller, change your idea of what the smallest is:

FOR i = 2 TO 20

  IF x(i) < smallest THEN smallest = x(i)

NEXT

Afterwards, print the smallest:

PRINT "The smallest number in the list is"; smallest

Check whether x’s list is in strictly increasing order In other words, find out whether the following statement is true: x(1) is a smaller number than x(2), which is a smaller number than x(3), which is a smaller number than x(4), etc. Solution: if x(i) is not smaller than x(i + 1), print “No” —

FOR I = 1 TO 19

  IF x(i) >= x(i + 1) THEN

    PRINT "No, the list is not in strictly increasing order"

    END

  END IF

NEXT

otherwise, print “Yes”:

PRINT "Yes, the list is in strictly increasing order"

Test yourself: look at those problems again, and see whether you can figure out the solutions without peeking at the answers.

Multiple arrays

Suppose your program involves three lists. Suppose the first list is called a$ and consists of 18 strings; the second list is called b and consists of 57 numbers; and the third list is called c$ and consists of just 3 strings. To say all that, begin your program with this statement:

DIM a$(18), b(57), c$(3)

Double subscripts

You can make x$ be a table of strings, like this:

     "dog"     "cat"     "mouse"

X$=

     "hotdog"  "catsup"  "mousetard"

Here’s how to make x$ be that table.…

Begin by saying:

CLS

DIM x$(2, 3)

That says x$ will be a table having 2 rows and 3 columns.

Then tell the computer what strings are in x$. Type these lines:

x$(1, 1) = "dog"

x$(1, 2) = "cat"

x$(1, 3) = "mouse"

x$(2, 1) = "hotdog"

x$(2, 2) = "catsup"

x$(2, 3) = "moustard"

That says the string in x$’s first row and first column is “dog”, the string in x$’s first row and second column is “cat”, etc.

If you’d like the computer to print all those strings, type this:

FOR i = 1 TO 2

  FOR j = 1 TO 3

    PRINT x$(i, j),

  NEXT

  PRINT

NEXT

That means: print all the strings in x$. The computer will print:

dog           cat           mouse

hotdog        catsup        mousetard

Most programmers follow this tradition: the row’s number is called i, and the column’s number is called j. That program obeys that tradition. The “FOR i = 1 TO 2” means “for both rows”; the “FOR j = 1 TO 3” means “for all 3 columns”.

Notice i comes before j in the alphabet; i comes before j in x(i, j); and “FOR i” comes before “FOR j”. If you follow the i-before-j tradition, you’ll make fewer errors.

At the end of the first PRINT line, the comma makes the computer print each column in a separate zone. The other PRINT line makes the computer press the ENTER key at the end of each row. The x$ is called a table or two-dimensional array or doubly subscripted array.

Multiplication table

This program prints a multiplication table:

CLS

DIM x(10, 4)

FOR i = 1 TO 10

  FOR j = 1 TO 4

    x(i, j) = i * j

  NEXT

NEXT

FOR i = 1 TO 10

  FOR j = 1 TO 4

    PRINT x(i, j),

  NEXT

  PRINT

NEXT

Line 2 says x will be a table having 10 rows and 4 columns.

The line saying “x(i, j) = i * j” means the number in row i and column j is i*j. For example, the number in row 3 and column 4 is 12. Above that line, the program says “FOR i = 1 TO 10” and “FOR j = 1 TO 4”, so that x(i,j)=i*j for every i and j, so every entry in the table is defined by multiplication.

The computer prints the whole table:

1               2               3               4

2               4               6               8

3               6               9               12

4               8               12              16

5               10              15              20

6               12              18              24

7               14              21              28

8               16              24              32

9               18              27              36

10              20              30              40

Instead of multiplication, you can have addition, subtraction, or division: just change the line saying “x(i, j) = i * j”.

Summing a table

Suppose you want to analyze this table:

  32.7      19.4      31.6      85.1

  -8       402       -61         0

5106         -.2       0        -1.1

  36.9        .04      1        11

 777       666        55.44      2

   1.99      2.99      3.99      4.99

  50        40        30        20

  12        21        12        21

   0      1000         2       500

Since the table has 9 rows and 4 columns, begin your program by saying:

CLS

DIM x(9, 4)

Each row of the table becomes a row of the DATA:

DATA 32.7, 19.4, 31.6, 85.1

DATA -8, 402, -61, 0

DATA 5106, -.2, 0, -1.1

DATA 36.9, .04, 1, 11

DATA 777, 666, 55.44, 2

DATA 1.99, 2.99, 3.99, 4.99

DATA 50, 40, 30, 20

DATA 12, 21, 12, 21

DATA 0, 1000, 2, 500

Make the computer READ the data:

FOR i = 1 TO 9

  FOR j = 1 TO 4

    READ x(i, j)

  NEXT

NEXT


To make the computer print the table, say this:

FOR i = 1 TO 9

  FOR j = 1 TO 4:

    PRINT X(I,J),

  NEXT

  PRINT

NEXT

Here are some problems, with solutions.…

Find the sum of all the numbers in the table Solution: start the sum at 0 —

sum = 0

and then increase the sum, by adding each x(i, j) to it:

FOR i = 1 TO 9

  FOR j = 1 TO 4

    sum = sum + x(i, j)

  NEXT

NEXT

Finally, print the sum:

PRINT "The sum of all the numbers is"; sum

The computer will print:

The sum of all the numbers is 8877.84

Find the sum of each row In other words, make the computer print the sum of the numbers in the first row, then the sum of the numbers in the second row, then the sum of the numbers in the third row, etc. Solution: the general idea is —

FOR i = 1 TO 9

  print the sum of row i

NEXT

Here are the details:

FOR i = 1 TO 9

  sum = 0

  FOR j = 1 TO 4

    sum = sum + x(i, j)

  NEXT

  PRINT "The sum of row"; i; "is"; sum

NEXT

The computer will print:

The sum of row 1 is 168.8

The sum of row 2 is 333

The sum of row 3 is 5104.7

etc.

Find the sum of each column In other words, make the computer print the sum of the numbers in the first column, then the sum of the numbers in the second column, then the sum of the numbers in the third column, etc. Solution: the general idea is —

FOR j = 1 TO 4

  print the sum of column j

NEXT

Here are the details:

FOR j = 1 TO 4

  sum = 0

  FOR i = 1 TO 9

    sum = sum + x(i, j)

  NEXT

  PRINT "The sum of column"; j; "is"; sum

NEXT

The computer will print:

The sum of column 1 is 6008.59

The sum of column 2 is 2151.23

The sum of column 3 is 75.03

The sum of column 4 is 642.99

In all the other examples, “FOR i” came before “FOR j”; but in this unusual example, “FOR i” comes after “FOR j”.


SUB procedures

Here’s a sick program:

CLS

PRINT "We all know..."

PRINT "You are stupid!"

PRINT "You are ugly!"

PRINT "...and yet we love you."

It makes the computer print this message:

We all know...

You are stupid!

You are ugly!

...and yet we love you.

So the computer prints “We all know...”, then insults the human (“You are stupid! You are ugly!”), then prints “...and yet we love you.”

Here’s a more sophisticated way to write that program:

CLS

PRINT "We all know..."

insult

PRINT "...and yet we love you."

SUB insult

  PRINT "You are stupid!"

  PRINT "You are ugly!"

END SUB

I’m going to explain that sophisticated version. Just read my explanation: don’t type the sophisticated version into your computer yet. (Wait until you read the next section, called “How to type the program”.)

In the sophisticated version, the top 4 lines tell the computer to clear the screen (CLS), print “We all know...”, then insult the human, then print “...and yet we love you.” But the computer doesn’t know how to insult yet.

The bottom 4 lines teach the computer how to insult: they say “insult” means to print “You are stupid!” and “You are ugly!” Those bottom 4 lines define the word insult; they’re the definition of insult.

That program is divided into two procedures. The top 4 lines are called the main procedure (or main routine or main module). The bottom 4 lines (which just define the word “insult”) are called the SUB procedure (or subroutine or submodule).

The SUB procedure’s first line (SUB insult) means: here’s the SUB procedure that defines the word “insult”. The SUB procedure’s bottom line (END SUB) means: this is the END of the SUB procedure.

How to type the program

Now you’re smart enough to begin typing that sophisticated program! Begin by typing the first four lines. Then start typing the SUB procedure, beginning with the line that says “SUB insult”.

When you finish typing the “SUB insult” line (and press the ENTER key at the end of that line), the computer analyzes that line and realizes you’re starting to type a new procedure. The computer devotes the entire screen to the new procedure. Yes, the screen shows just the SUB insult procedure! The screen no longer shows the main procedure! Here’s the rule: the computer’s screen shows just one procedure at a time.


So now the top of the screen says “SUB insult”. At the bottom of the screen, the computer automatically types “SUB END” for you. In between the “SUB insult” and “SUB END” lines, type PRINT “You are stupid!” and PRINT “You are ugly!” (and indent those lines by pressing the TAB key), so the screen looks like this:

SUB insult

  PRINT "You are stupid!"

  PRINT "You are ugly!"

END SUB

Congratulations! You finished typing the program!

Seeing different procedures

The computer’s screen shows just the SUB procedure. To see the main procedure instead, press the F2 key, then ENTER.

To flip back to the SUB procedure again, press the F2 key again, then the down-arrow key (so the world “insult” is highlighted), then ENTER.

Here’s the rule: to see a different procedure, press the F2 key, then highlight the name of the procedure you want to see (by pressing the down-arrow key if necessary), then press ENTER.

Run

Whenever you want to run the program, press SHIFT with F5. The computer will say:

We all know...

You are stupid!

You are ugly!

...and yet we love you.

Print

If you choose Print from the file menu (by pressing Alt then F then P) and then press ENTER, the computer will print the entire program onto a single sheet of paper.

When printing on paper, the computer will automatically leave a blank line between the procedures, so the paper will show this:

CLS

PRINT "We all know..."

insult

PRINT "...and yet we love you."

 

SUB insult

  PRINT "You are stupid!"

  PRINT "You are ugly!"

END SUB

You must eject the paper from the printer manually.

Save

If you choose Save from the file menu (by pressing Alt then F then S) and then give the program a name (and press ENTER), the computer saves the entire program onto the hard disk.

While saving, the computer automatically adds an extra line at the top of the program, so the main procedure becomes this:

DECLARE SUB insult ()

CLS

PRINT "We all know..."

insult

PRINT "...and yet we love you."

The DECLARE line reminds the computer that the program includes a SUB insult.


Refrains

This is chanted by boys playing tag — and protesters fearing dictators:

The lion is a-coming near.

         He'll growl and sneer

         And drink our beer.

The lion never brings us cheer.

         He'll growl and sneer

         And drink our beer.

The lion is the one we fear.

         He'll growl and sneer

         And drink our beer.

Gotta stop the lion!

In that chant, this refrain is repeated:

         He'll growl and sneer

         And drink our beer.

This program prints the entire chant:

CLS

PRINT "The lion is a-coming near."

refrain

PRINT "The lion never brings us cheer."

refrain

PRINT "The lion is the one we fear."

refrain

PRINT "Gotta stop the lion!"

 

SUB refrain

  PRINT "         He'll growl and sneer"

  PRINT "         And drink our beer."

END SUB

Clementine The famous folk song “Clementine” begins like this:

In a cavern in a canyon, excavating for a mine,

Lived a miner (49'er) and his daughter, Clementine.

 

  O my darling, o my darling, o my darling Clementine,

  You are lost and gone forever.  Dreadful sorry, Clementine!

 

Light she was and like a fairy, and her shoes were #9.

Herring boxes without tops: those sandals were for Clementine.

 

  O my darling, o my darling, o my darling Clementine,

  You are lost and gone forever.  Dreadful sorry, Clementine!

 

Drove her ducklings to the water ev'ry morning just at 9.

Hit her foot against a splinter, fell into the foaming brine.

 

  O my darling, o my darling, o my darling Clementine,

  You are lost and gone forever.  Dreadful sorry, Clementine!



This program prints the song’s updated version with a twisted ending:

CLS

PRINT "In a cavern in a canyon, excavating for a mine,"

PRINT "Lived a miner (49'er) and his daughter, Clementine."

chorus

PRINT "Light she was and like a fairy, and her shoes were #9."

PRINT "Herring boxes without tops: those sandals were for Clementine."

chorus

PRINT "Drove her ducklings to the water ev'ry morning just at 9."

PRINT "Hit her foot against a splinter, fell into the foaming brine."

chorus

PRINT "Ruby lips above the water, blowing bubbles soft and fine!"

PRINT "But alas, I was no swimmer, so I lost my Clementine."

chorus

PRINT "How I missed her!  How I missed her!  How I missed my Clementine!"

PRINT "But I kissed her little sister and forgot my Clementine."

chorus

PRINT "Sister gladly to me married.  Then she found in nine months time"

PRINT "A nice daughter.  As she oughta, named the daughter Clementine."

chorus

PRINT "There's our daughter in the water.  Suddenly, she gives a wail"

PRINT "At some red-stained herring boxes.  Now I'm sitting here in jail."

chorus

PRINT "In my dreams she still doth haunt me, robed in garments soaked in brine."

PRINT "Once I wooed her.  Now a loser singing songs while doing time!"

chorus

 

SUB chorus

  SLEEP 11

  PRINT

  PRINT "  O my darling, o my darling, o my darling Clementine,"

  PRINT "  You are lost and gone forever.  Dreadful sorry, Clementine!"

  SLEEP 11

  PRINT

END SUB

At the beginning and end of the chorus, the “SLEEP 11” makes the computer pause for 11 seconds, to give the human a chance to read & sing what the computer wrote before the computer puts more words onto the screen.

Big love

This program prints a love poem:

CLS

PRINT "The most beautiful thing in the world is"

PRINT "LOVE"

PRINT "The opposite of war is"

PRINT "LOVE"

PRINT "And when I look at you, I feel lots of"

PRINT "LOVE"

In that program, many of the lines make the computer print the word LOVE. Let’s make those lines print the word LOVE bigger, like this:

*               *       *       *     * * * * *

*             *   *      *     *      *

*           *       *     *   *       * * *

*             *   *        * *        *

* * * * *       *           *         * * * * *

To make LOVE be that big, run this version of the program:

CLS

PRINT "The most beautiful thing in the world is"

big.love

PRINT "The opposite of war is"

big.love

PRINT "And when I look at you, I feel lots of"

big.love

 

SUB big.love

  PRINT "*               *       *       *     * * * * *"

  PRINT "*             *   *      *     *      *"

  PRINT "*           *       *     *   *       * * *"

  PRINT "*             *   *        * *        *"

  PRINT "* * * * *       *           *         * * * * *"

END SUB

In that version, the lines say “big.love” instead of PRINT “LOVE”. The SUB procedure teaches the computer how to make big.love.

Variables

Each procedure uses its own part of the RAM. For example, the main procedure uses a different part of the RAM than a SUB procedure.

Suppose the main procedure says “x = 4”, and a SUB procedure named “joe” says “x = 100”. The computer puts 4 into the main procedure’s x box and puts 100 into joe’s x box, like this:

                        ┌─────────────┐

main procedure's x box  │        4    │

                        └─────────────┘

                        ┌─────────────┐

joe's x box             │      100    │

                        └─────────────┘

Those two boxes are stored in different parts of the RAM from each other, and they don’t interfere with each other.

For example, suppose you run this program:

CLS

x = 4

joe

PRINT x

 

SUB joe

  PRINT x

  x = 100

END SUB

The computer begins by doing the main procedure, which says “x = 4”, so the computer puts 4 into the main procedure’s x box:

                        ┌─────────────┐

main procedure's x box  │        4    │

                        └─────────────┘

The main procedure’s next line says “joe”, which makes the computer do the joe procedure. The joe procedure begins by saying “PRINT x”; but since joe’s x box is still empty, the computer will print 0. Joe’s next line says “x = 100”, which puts 100 into joe’s x box. Then the computer comes to the end of joe, returns to the main procedure, and does the “PRINT x” line at the bottom of the main procedure; but since the main procedure’s x box still contains 4, the computer will print 4. The computer will not print 100.

If a committee of programmers wants to write a big, fancy program, the committee divides the programming task into a main procedure and several SUB procedures, then assigns each procedure to a different programmer. If you’re one of the programmers, you can use any variable names you wish, without worrying about what names the other programmers chose: if you accidentally pick the same variable name as another programmer, it’s no problem, since each procedure stores its variables in a different part of the RAM.

If you want a variable to affect and be affected by what’s in another procedure, use one of these methods…


Method 1: SHARED At the top of the main procedure, you can say:

COMMON SHARED x

That means x is a variable whose box will be shared among all procedures, so that if a procedure says “x = 4” the x will be 4 in all procedures.

For example, suppose you say:

COMMON SHARED x

CLS

x = 4

joe

PRINT x

 

SUB joe

  PRINT x

  x = 100

END SUB

Then when the computer comes to joe’s first line, which says “PRINT x”, the computer will print 4 (because the main procedure had made x become 4); and when the computer comes to the main procedure’s bottom line, which says “PRINT x”, the computer will print 100 (because the joe procedure had made x become 100).

Put the COMMON SHARED line at the main procedure’s top, above CLS.

You can write a program containing other shared variables besides x. For example, if you want x and sammy$ to both be common shared variables, say:

COMMON SHARED x, sammy$

If you want y$ to be a list of 20 strings, you normally say DIM y$(20); but if you want to share that list among all the procedures, say this instead:

DIM SHARED y$(20)

Put that line just at the top of the main procedure; you do not need to say DIM y$(20) in the SUB procedures.

The program is your world! A SHARED variable is called a global variable, since its value is shared throughout the entire program. An ordinary, unshared variable is called a local variable, since its value is used just in one procedure.

Method 2: arguments Here’s a simple program:

CLS

INPUT "How many times do you want to kiss"; n

FOR i = 1 TO n

  PRINT "kiss"

NEXT

It asks “How many times do you want to kiss”, then waits for your answer, then prints the word “kiss” as many times as you requested. For example, if you type 3, the computer will print:

kiss

kiss

kiss

If you input 5 instead, the computer will print this instead:

kiss

kiss

kiss

kiss

kiss

Let’s turn that program into a SUB procedure that gets its input from the main procedure instead of from a human. Here’s the SUB procedure:

SUB kiss (n)

  FOR i = 1 TO n

    PRINT "kiss"

  NEXT

END SUB

In that SUB procedure’s top line, the “(n)” means “input the number n from the main procedure, instead of from a human”. If the main procedure says —

kiss 3

then the n will be 3, so the SUB procedure will print “kiss” 3 times, like this:

kiss

kiss

kiss

If the main procedure says —

kiss 5

then the n will be 5, so the SUB procedure will print “kiss” 5 times.

Please type this complete program, which contains that SUB procedure:

DEFINT A-Z

CLS

PRINT "The boy said:"

kiss 3

PRINT "His girlfriend said okay!"

PRINT "Then the boy said:"

kiss 5

PRINT "His girlfiend said okay!"

PRINT "Finally, the boy said:"

kiss 8

PRINT "His girlfriend said:"

PRINT "I'm not prepared to go that far."

 

SUB kiss (n)

  FOR i = 1 TO n

    PRINT "kiss"

  NEXT

END SUB

When you run that program, the computer will print:

The boy said:

kiss

kiss

kiss

His girlfriend said okay!

Then the boy said:

kiss

kiss

kiss

kiss

kiss

His girlfriend said okay!

Finally, the boy said:

kiss

kiss

kiss

kiss

kiss

kiss

kiss

kiss

His girlfriend said:

I'm not prepared to go that far.

In that SUB procedure’s top line, the n is called the parameter; put it in parentheses. In the line that says “kiss 3”, the 3 is called the argument.

In that program, instead of saying —

kiss 3

you can say:

y = 3

kiss y

Then y’s value (3) will become n, so the SUB procedure will print “kiss” 3 times. The n (which is the parameter) will use the same box as y (which is the argument). For example, if you insert into the SUB procedure a line saying “n = 9”, the y will become 9 also.

You can write fancier programs. Here’s how to begin a SUB procedure called joe having three parameters (n, m, and k$):

SUB joe (n, m, k$)

To use that subroutine, give a command such as:

joe 7, 9, "love"

Suppose your main procedure says:

DIM x$(3)

x$(1) = "love"

x$(2) = "death"

x$(3) = "war"

That means x$ is a list of these 3 strings: “love”, “death”, and “war”. To make joan be a SUB procedure manipulating that list, make joan’s top line say —

SUB joan (x$())

In that line, the () warns the computer that x$ is a list. You do not need to say DIM x$(3) in the SUB procedure. When you want to make the main procedure use joan, put this line into the main procedure:

joan x$()

Those lines, “SUB joan (x$())” and “joan x$()”, work even if x$ is a table defined by a line such as DIM x$(30, 40).

DEFINT To make all the variables in your program be short integers, say “DEFINT A-Z” at the top of the main procedure and say it again at the top of each SUB procedure, so SUB procedure joe begins like this:

DEFINT A-Z

SUB joe

If you typed “DEFINT A-Z” at the top of the main procedure, the computer will automatically type “DEFINT A-Z” for you at the top of each new SUB procedure.


Style

To become a good programmer, write your programs using a good style. Here’s how.…

Design a program

First, decide on your ultimate goal. Be optimistic. Maybe you’d like the computer to play the perfect game of chess? or translate every English sentence into French?

Research the past Whatever you want the computer to do, someone else probably thought of the same idea already and wrote a program for it.

Find out. Ask your friends. Ask folks in nearby schools, computer stores, computer centers, companies, libraries, and bookstores. Look through books and magazines. There are even books that list what programs have been written. Ask the company you bought your computer from.

Even if you don’t find exactly the program you’re looking for, you may find one that’s close enough to be okay, or that will work with just a little fixing or serve as part of your program or at least give you a clue as to where to begin. In a textbooks or magazines, you’ll probably find a discussion of the problem you’re trying to solve and the pros and cons of various solutions to it — some methods are faster than others.

Remember: if you keep your head in the sand and don’t look at what other programmers have done already, your programming effort may turn out to be a mere exercise, useless to the rest of the world.

Simplify Too often, programmers embark on huge projects and never get them done. Once you have an idea of what’s been done before and how hard your project is, simplify it.

Instead of making the computer play a perfect game of chess, how about settling for a game in which the computer plays unremarkably but at least doesn’t cheat? Instead of translating every English sentence into French, how about translating just English colors? (We wrote that program already.)

In other words, pick a less ambitious, more realistic goal, which if achieved will please you and be a steppingstone to your ultimate goal.

Finding a bug in a program is like finding a needle in a haystack: removing the needle is easier if the haystack is small than if you wait until more hay’s been piled on.

Specify the I/O Make your new, simple goal more precise. That’s called specification. One way to be specific is to draw a picture, showing what your screen will look like if your program’s running successfully.

In that picture, find the lines typed by the computer. They become your program’s PRINT statements. Find the lines typed by the human: they become the INPUT statements. Now you can start writing your program: write the PRINT and INPUT statements on paper, with a pencil, and leave blank lines between them. You’ll fill in the blanks later.


Suppose you want the computer to find the average of two numbers. Your picture will look like this:

What's the first number? 7

What's the second number? 9

The average is 8

Your program at this stage will be:

CLS

INPUT "What's the first number"; a

INPUT "What's the second number"; b

etc.

PRINT "The average is"; c

All you have left to do is figure out what the “etc.” is. Here’s the general method.…

Choose your statements Suppose you didn’t have a computer. Then how would you get the answer?

Would you have to use a mathematical formula? If so, put the formula into your program, but remember that the equation’s left side must have just one variable. For example, if you’re trying to solve a problem about right triangles, you might have to use the Pythagorean formula a²+b²=c²; but the left side of the equation must have just one variable, so your program must say a=SQR(c^2-b^2), or b=SQR(c^2-a^2), or c=SQR(a^2+b^2), depending on whether you’re trying to compute a, b, or c.

Would you have to use a memorized list, such as an English-French dictionary or the population of each state or the weight of each chemical element? If so, that list becomes your DATA, and you need to READ it. If it would be helpful to have the data numbered — so the first piece of data is called x(1), the next piece of data is called x(2), etc. — use the DIM statement.

Subscripts are particularly useful if one long list of information will be referred to several times in the program.

Does your reasoning repeat? That means your program should have a loop. If you know how many times to repeat, say FOR...NEXT. If you’re not sure how often, say DO...LOOP. If the thing to be repeated isn’t repeated immediately, but just after several other things have happened, make the repeated part be a SUB procedure.

At some point in your reasoning, do you have to make a decision? Do you have to choose among several alternatives? To choose between two alternatives, say IF...THEN. To choose among three or more alternatives, say SELECT CASE. If you want the computer to make the choice arbitrarily, “by chance” instead of for a reason, say IF RND<.5.

Do you have to compare two things? The way to say “compare x with y” is: IF x = y THEN.

Write pseudocode Some English teachers say that before you write a paper, you should make an outline. Some computer teachers give similar advice about writing programs.

The “outline” can look like a program in which some of the lines are written in plain English instead of computerese. For example, one statement in your outline might be:

a = the average of the twelve values of x

Such a statement, written in English instead of in computerese, is called pseudocode. Later, when you fill in the details, expand that pseudocode into the following:

sum = 0

FOR i = 1 TO 12

  sum = sum + x(i)

NEXT

average = sum / 12


Organize yourself Keep the program’s over-all organization simple. That will make it easier for you to expand the program and find bugs. Here’s some folklore, handed down from generation to generation of programmers, that will simplify your organization.…

Use top-down programming. That means write a one-sentence description of your program; then expand that sentence to several sentences; then expand each of those sentences to several more sentences; and so on, until you can’t expand any more. Then turn each of those new sentences into lines of program. Then your program will be in the same order as the English sentences and therefore organized the same way as an English-speaking mind.

A variation is to use SUB procedures. That means writing the essence of the program as a very short main procedure; instead of filling in the grubby details immediately, replace each piece of grubbiness by a SUB procedure. Your program will be like a good book: your main procedure will move swiftly, and the annoying details will be relegated to the appendices at the back; the appendices are the SUB procedures. Make each procedure brief — no more than 20 lines — so the entire procedure can fit on the screen; if it starts getting longer and grubbier, replace each piece of grubbiness by another SUB procedure.

Avoid GO TO. It’s hard for a human to understand a program that’s a morass of GO TO statements. It’s like trying to read a book where each paragraph says to turn to a different page! When you must say GO TO, try to go forward instead of backwards and not go too far.

Use variables After you’ve written some lines of your program, you may notice that your reasoning “almost repeats”: several lines bear a strong resemblance to each other. You can’t use DO...LOOP or FOR...NEXT unless the lines repeat exactly. To make the repetition complete, use a variable to represent the parts that are different.

For example, suppose your program contains these lines:

PRINT 29.34281 + 9.876237 * SQR(5)

PRINT 29.34281 + 9.876237 * SQR(7)

PRINT 29.34281 + 9.876237 * SQR(9)

PRINT 29.34281 + 9.876237 * SQR(11)

PRINT 29.34281 + 9.876237 * SQR(13)

PRINT 29.34281 + 9.876237 * SQR(15)

PRINT 29.34281 + 9.876237 * SQR(17)

PRINT 29.34281 + 9.876237 * SQR(19)

PRINT 29.34281 + 9.876237 * SQR(21)

Each of those lines says PRINT 29.3428 + 9.87627 * SQR(a number). The number keeps changing, so call it x. All those PRINT lines can be replaced by this loop:

FOR x = 5 TO 21 STEP 2

  PRINT 29.34281 + 9.876237 * SQR(x)

NEXT

Here’s a harder example to fix:

PRINT 29.34281 + 9.876237 * SQR(5)

PRINT 29.34281 + 9.876237 * SQR(97.3)

PRINT 29.34281 + 9.876237 * SQR(8.62)

PRINT 29.34281 + 9.876237 * SQR(.4)

PRINT 29.34281 + 9.876237 * SQR(200)

PRINT 29.34281 + 9.876237 * SQR(12)

PRINT 29.34281 + 9.876237 * SQR(591)

PRINT 29.34281 + 9.876237 * SQR(.2)

PRINT 29.24281 + 9.876237 * SQR(100076)

Again, let’s use x. All those PRINT lines can be combined like this:

DATA 5,97.3,8.62,.4,200,12,591,.2,100076

FOR i = 1 TO 9

  READ x

  PRINT 29.34281 + 9.876237 * SQR(x)

NEXT

This one’s even tougher:

PRINT 29.34281 + 9.876237 * SQR(a)

PRINT 29.34281 + 9.876237 * SQR(b)

PRINT 29.34281 + 9.876237 * SQR(c)

PRINT 29.34281 + 9.876237 * SQR(d)

PRINT 29.34281 + 9.876237 * SQR(e)

PRINT 29.34281 + 9.876237 * SQR(f)

PRINT 29.34281 + 9.876237 * SQR(g)

PRINT 29.34281 + 9.876237 * SQR(h)

PRINT 29.34281 + 9.876237 * SQR(i)

Let’s assume a, b, c, d, e, f, g, h, and i have been computed earlier in the program. The trick to shortening those lines is to change the names of the variables. Throughout the program, say x(1) instead of a, say x(2) instead of b, say x(3) instead of c, etc. Say DIM x(9) at the beginning of your program. Then replace all those PRINT lines by this loop:

FOR i = 1 TO 9

  PRINT 29.34281 + 9.876237 * SQR(x(i))

NEXT

Make it efficient

Your program should be efficient. That means it should use as little of the computer’s time and memory as possible.

To use less of the computer’s memory, make your DIMensions as small as possible. Try writing the program without any arrays at all; if that turns out to be terribly inconvenient, use the smallest and fewest arrays possible.

To use less of the computer’s time, avoid having the computer do the same thing more than once.

These lines force the computer to compute SQR(8.2 * n + 7) three times:

PRINT SQR(8.3 * n + 7) + 2

PRINT SQR(8.3 * n + 7) / 9.1

PRINT 5 - SQR(8.3 * n + 7)

You should change them to:

k = SQR(8.3 * n + 7)

PRINT k + 2

PRINT k / 9.1

PRINT 5 - k

These lines force the computer to compute x ^ 9 + 2 a hundred times:

FOR i = 1 TO 100

  PRINT (x ^ 9 + 2) / i

NEXT

You should change them to:

k = x ^ 9 + 2

FOR i = 1 TO 100

  PRINT k / i

NEXT

These lines force the computer to count to 100 twice:

sum = 0

FOR i = 1 TO 100

  sum = sum + x(i)

NEXT

PRINT "The sum of the x's is"; sum

product = 1

FOR i = 1 TO 100

  product = product * x(i)

NEXT

PRINT "The product of the x's is"; product

You should combine the two FOR...NEXT loops into a single FOR...NEXT loop, so the computer counts to 100 just once. Here’s how:


sum = 0

product = 1

FOR i = 1 TO 100

  sum = sum + x(i)

  product = product * x(i)

NEXT

PRINT "The sum of the x's is"; sum

PRINT "The product of the x's is"; product

Here are more tricks to make your program run faster.…

Instead of exponents, use multiplication.

slow:      y = x ^ 2

faster:       y = x * x

If your program doesn’t involve decimals or big numbers, put this statement at the top of your program:

DEFINT A-Z

If your program involves just a few decimals or big numbers, begin your program by saying DEFINT A-Z; then put the symbol “&” after every variable that stands for a long integer, and put the symbol “!” after every variable that stands for a single-precision real number.

Test it

When you’ve written a program, test it: run it and see whether it works.

If the computer does not gripe, your tendency will be to say “Whoopee!” Don’t cheer too loudly. The answers the computer is printing might be wrong. Even if its answers look reasonable, don’t assume they’re right: the computer’s errors can be subtle. Check some of its answers by computing them with a pencil.

Even if the answers the computer prints are correct, don’t cheer. Maybe you were just lucky. Type different input, and see whether your program still works. Probably you can input something that will make your program go crazy or print a wrong answer. Your mission: to find input that will reveal the existence of a bug.

Try six kinds of input.…

Try simple input Type in simple integers, like 2 and 10, so the computation is simple, and you can check the computer’s answers easily.

Try input that increases See how the computer’s answer changes when the input changes from 2 to 1000.

Does the change in the computer’s answer look reasonable? Does the computer’s answer go up when it should go up, and down when it should go down?… and by a reasonable amount?

Try input testing each IF For a program that says —

IF x < 7 THEN GOTO 10

input an x less than 7 (to see whether line 10 works), then an x greater than 7 (to see whether the line underneath the IF line works), then an x equal to 7 (to see whether you really want “<” instead of “<=”), then an x very close to 7, to check round-off error.

For a program that says —

IF x ^ 2 + y < z THEN GOTO 10

input an x, y, and z that make x ^ 2 + y less than z. Then try inputs that make x ^ 2 + y very close to z.

Try extreme input What happens if you input:

a huge number, like 45392000000 or 1E35?

a tiny number, like .00000003954 or 1E-35?

a trivial number, like 0 or 1?

a typical number, like 45.13?

a negative number, like -52?

Find out.

If the input is supposed to be a string, what happens if you input aaaaa or zzzzz? What happens if you capitalize the input? If there are supposed to be two inputs, what happens if you input the same thing for each?

Try input making a line act strange If your program contains division, try input that will make the divisor be zero or a tiny decimal close to zero. If your program contains the square root of a quantity, try input that will make the quantity be negative. If your program says “FOR i = x TO y”, try input that will make y be less than x, then equal to x. If your program mentions x(i), try input that will make i be zero or negative or greater than the DIM.

Try input that causes round-off error: for a program that says “x - y” or says “IF x = y”, try input that will make x almost equal y.

Try garbage Computers often print wrong answers. A computer can print a wrong answer because its circuitry is broken or because a program has a bug. But the main reason why computers print wrong answers is incorrect input. Incorrect input is called garbage and has several causes.…

The user’s finger slips. Instead of 400, he inputs 4000. Instead of 27, he inputs 72. Trying to type .753, he leaves out the decimal point.

The user got wrong info. He tries to input the temperature, but his thermometer is leaking. He tries to input the results of a questionnaire, but everybody who filled out his questionnaires lied.

The instructions aren’t clear, so the user isn’t sure what to input.

The program asks “How far did the ball fall?” but the user doesn’t know whether to type the distance in feet or in meters.

Is time to be given in seconds or minutes? Are angles to be measured in degrees or radians?

If the program asks “What is your name?” should the user type “Joe Smith” or “Smith,Joe” or just “Joe”?

Can the user input “y” instead of “yes”?

Maybe the user isn’t clear about whether to insert commas, quotation marks, and periods. If several items are to be typed, should they be typed on the same line or on separate lines? If your program asks “How many brothers and sisters do you have?” and the user has 2 brothers & 3 sisters, should he type “5” or “2,3” or “2 brothers and 3 sisters”?

For a quiz that asks “Who was the first U.S. President?” what if the user answers “George Washington” or simply “Washington” or “washington” or “G. Washington” or “General George Washington” or “President Washington” or “Martha’s husband?” Make the instructions clearer:

Who was the first U.S. President (give just his last name)?

The user tries to joke or sabotage. Instead of inputting his name, he types an obscene comment. When asked how many brothers and sisters he has, he says 275.

Responsibility! As a programmer, it’s your duty to include clear directions for using your program, and you must make the program reject ridiculous input.

For example, if your program is supposed to print weekly paychecks, it should refuse to print checks for more than $10000. Your program should contain these lines:

10 INPUT "How much money did the employee earn"; e

IF e > 10000 THEN

  PRINT e; "is quite a big paycheck!  I don't believe you."

  PRINT "Please retype your request."

  GO TO 10

END IF

That IF line is called an error trap (or error-handling routine). Your program should contain several, to prevent printing checks that are too small (2¢?) or negative or otherwise ridiculous ($200.73145?)

To see how your program reacts to input that’s either garbage or unusual, ask a friend to run your program. That person might input something you never thought of.


Document it

Write an explanation that helps other people understand your program.

An explanation is called documentation. When you write an explanation, you’re documenting the program.

You can write the documentation on a separate sheet of paper, or you can make the computer print the documentation when the user runs or lists the program.

A popular device is to begin the program by making the computer ask the user:

Do you need instructions?

You need two kinds of documentation: how to use the program, and how the program was written.

How to use the program Your explanation of how to use the program should include:

the program’s name

how to get the program from the disk

the program’s purpose

a list of other programs that must be combined with this program, to make a workable combination

the correct way to type the input and data (show an example)

the correct way to interpret the output

the program’s limitations (input it can’t handle, a list of error messages that might be printed, round-off error)

a list of bugs you haven’t fixed yet

How the program was written An explanation of how you wrote the program will help other programmers borrow your ideas, and help them expand your program to meet new situations. It should include:

your name

the date you finished it

the computer you wrote it for

the language you wrote it in (probably BASIC)

the name of the method you used (“solves quadratic equations by using the quadratic formula”)

the name of the book or magazine where you found the method

the name of any program you borrowed ideas from

an informal explanation of how program works (“It loops until x>y, then computes the weather forecast.”)

the purpose of each SUB procedure

the meaning of each variable

the significance of reaching a line (for a program saying “IF x < 60 THEN GOTO 1000”, say “Reaching line 1000 means the student flunked.”)


Weird features

You’ve learned QBASIC’s normal features. Now let’s look at features that are weirder.

Fancy input

The typical INPUT statement looks like this:

INPUT "What is your name"; n$

It makes the computer ask “What is your name?” then wait for you to answer the question. So when you run the program, the conversation looks like this:

What is your name? Maria

Notice that the computer automatically adds a question mark at the end of the question, and leaves a blank space after the question mark.

Omitting the question mark If you want to omit the question mark and the blank space, replace the semicolon by a comma:

INPUT "What is your name", n$

The comma makes the computer omit the question mark and the blank space, so the conversation will look like this:

What is your nameMaria

Here’s a prettier example of how to use the comma:

INPUT "Please type your name...", n$

The conversation will look like this:

Please type your name...Maria

Here’s an even prettier example:

INPUT "To become a movie star, type your name next to the stars***", n$

The conversation will look like this:

To become a movie star, type your name next to the stars***Maria

Omitting the prompt The typical INPUT statement contains a question, such as “What is your name”. The question is called the prompt. If you wish, you can omit the prompt, like this:

INPUT n$

That line doesn’t include a question, but the computer still prints a question mark followed by a blank space, so the conversation looks like this:

? Maria

To make that INPUT line more practical, put a PRINT line above it, like this:

PRINT "Please type your name after the question mark"

INPUT N$

That makes the conversation look like this:

Please type your name after the question mark

? Maria

Adjacent printing Here’s a simple program:

CLS

INPUT "What is your name"; n$

PRINT "!!!What a wonderful name!!!"

It produces this conversation:

What is your name? MARIA

!!!What a wonderful name!!!

To have more fun, insert a semicolon immediately after the word INPUT, like this:

CLS

INPUT ; "What is your name"; n$

PRINT "!!!What a wonderful name!!!"

The conversation will begin normally:

What is your name? Maria

But when you press the ENTER key after Maria, the extra semicolon makes the computer do the PRINTing next to Maria, like this:

What is your name? Maria!!!What a wonderful name!!!


To surprise your friends, run this program:

CLS

INPUT ; "What is your name"; n$

PRINT n$; n$; n$

The program begins by asking:

What is your name?

Suppose the person says Maria, like this:

What is your name? Maria

When the person presses the ENTER key after Maria, the PRINT line automatically prints Maria three more times afterwards, like this:

What is your name? MariaMariaMariaMaria

This program asks for your first name, then your last name:

CLS

INPUT ; "What is your first name"; first.name$

INPUT "   What is your last name"; last.name$

The first INPUT line makes the conversation begin like this:

What is your first name? Maria

When you press the ENTER key after Maria, that INPUT’s extra semicolon makes makes the next INPUT appear on the same line, like this:

What is your first name? Maria   What is your last name?

If you answer Yee, the whole conversation looks like this:

What is your first name? Maria   What is your last name? Yee

Multiple input This program asks for your name, age, and weight:

CLS

INPUT "Name, age, weight"; n$, a, w

When you run the program, the computer asks:

Name, age, weight?

The computer waits for you to type your name, age, and weight. When you type them, put commas between them, like this:

Name, age, weight? John,25,148

If your name is “John Smith, Jr.”, and you want to input all that instead of just John, you must put quotation marks around your name:

Name, age, weight? "John Smith, Jr.",25,148

Here’s the rule: you must put quotation marks around any INPUT string that contains a comma.

LINE INPUT If you say —

LINE INPUT "Please type your name..."; n$

the computer will say:

Please type your name...

Then the computer will wait for you to type your name. You do not have to put quotation marks around your name, even if your name contains a comma. LINE INPUT means: the entire line that the person inputs will become the string, even if the line contains a comma.

Notice that the LINE INPUT statement does not make the computer automatically print a question mark. And notice that the variable must be a string (such as n$), not a number.


INPUT$ This program reveals private information about Mary:

CLS

PRINT "Mary secretly wishes to kiss a cow!"

Here’s how to protect that program, so only people who know the “secret password” can run it.…

First, invent a secret password. Let’s make it be “tuna”.

Here’s the program:

CLS

INPUT "What's the secret password"; a$

IF a$ = "tuna" THEN

  PRINT "Mary secretly wishes to kiss a cow!"

ELSE

  PRINT "You are an unauthorized user!"

END IF

The INPUT line asks the person to type the secret password. Whatever the person types is called a$. If the person types “tuna”, the computer will say:

Mary secretly wishes to kiss a cow!

But if the person does not type “tuna”, the computer says “You are an unauthorized user!” and refuses to reveal Mary’s secret desire.

This program’s better:

CLS

PRINT "Please type the secret password."

a$ = INPUT$(4)                         

IF a$ = "tuna" THEN

  PRINT "Mary secretly wishes to kiss a cow!"

ELSE

  PRINT "You are an unauthorized user!"

END IF

Line 2 makes the computer say:

Please type the secret password.

Line 3 waits for the person to input 4 characters. The characters that the person inputs will become a$. For example, suppose the person types t, then u, then n, then a; then a$ will become “tuna” and the computer will reveal Mary’s secret.

While the person inputs the 4 characters, they won’t appear on the screen; they’ll be invisible. That’s to prevent other people in the room from peeking at the screen and noticing the password.

After typing the 4 characters, the person does not have to press the ENTER key. As soon as the person types the 4th character, the computer makes a$ be the 4 characters that the person typed.

This devilish program makes your computer pretend to be broken, so that whenever you press the w key your screen shows an f instead:

CLS

DO

  a$ = INPUT$(1)

  IF a$ = "w" THEN PRINT "f";  ELSE PRINT a$;

LOOP

Line 3 waits for you to type 1 character. The IF line says: if the character you typed was “w”, print an “f” on the screen instead; otherwise, print the character you typed. Since that routine is in a DO loop, the computer will repeat the routine forever. For example, if you try to type “the weather is wonderful”, you’ll see this on the screen instead:

the feather is fonderful

For an even wilder time, tell the computer to change each “e” to “ooga”, by changing the IF line to this:

        IF a$ = "e" THEN PRINT "ooga";  ELSE PRINT a$;

Then if you try to type “We are here”, you’ll see this on the screen instead:

wooga arooga hoogarooga


This program gives you a choice of literature:

CLS

PRINT "Welcome to the world's great literature, abridged."

PRINT "Which kind of literature would you like?"

PRINT "n: novel"

PRINT "p: poem"

10 PRINT "Please press n or p."

SELECT CASE INPUT$(1)

  CASE "n"

    PRINT "He:  I love you."

    PRINT "She: I'm pregnant."

    PRINT "He:  Let's get married."

    PRINT "She: Let's get divorced."

    PRINT "He:  Let's get back together."

    PRINT "She: Too bad you died in the war, but I'll never forget you!"

  CASE "p"

    PRINT "Noses"

    PRINT "Blowses"

  CASE ELSE

    GOTO 10

END SELECT

The program begins by printing:

Welcome to the world's great literature, abridged.

Which kind of literature would you like?

n: novel

p: poem

Please press n or p.

The SELECT CASE line makes the computer wait for you to press a key. You do not have to press the ENTER key afterwards.

If you press the n key, the computer does the lines indented under CASE “n”.

Those lines print an abridged novel.

If you press the p key instead, the computer does the lines indented under CASE “p”.

Those lines print an abridged poem.

If you press neither n nor p, the computer does the line indented under CASE ELSE.

That line makes the computer GO back TO line 10, which reminds you to press n or p.

SWAP

The computer understands the word SWAP:

CLS

x = 4

y = 9

SWAP x, y

PRINT x; y

Lines 2 & 3 say x is 4, and y is 9. The SWAP line swaps x with y; so x becomes 9, and y becomes 4. The bottom line prints:

 9  4

That example swapped numbers. You can also swap strings:

CLS

a$ = "horse"

b$ = "cart"

SWAP a$, b$

PRINT a$; " "; b$

Lines 2 & 3 say a$ is “horse” and b$ is “cart”. The SWAP line swaps a$ with b$; so a$ becomes “cart”, and b$ becomes “horse”. The bottom line puts the cart before the horse:

cart horse

Shuffling Here are some cards:

queen of hearts

jack of diamonds

ace of spades

joker

king of clubs

Let’s shuffle them, to put them into a random order.

To begin, put the list of cards into a DATA statement:

CLS

DATA queen of hearts,jack of diamonds,ace of spades,joker,king of clubs


We have 5 cards. Let the queen of hearts be called card$(1), the jack of diamonds be called card$(2), the ace of spades be called card$(3), the joker be called card$(4), and the king of clubs be called card$(5):

n = 5

DIM card$(n)

FOR i = 1 TO n

  READ card$(i)

NEXT

Shuffle the cards, by using the following strategy.…

Swap card n with a random card before it (or with itself); then swap card n-1 with a random card before it (or with itself); then swap card n-2 with a random card before it (or with itself); etc. Keep doing that, until you finally reach card 2, which you swap with a random card before it (or with itself). Here’s the code:

RANDOMIZE TIMER

FOR i = n TO 2 STEP -1

  SWAP card$(i), card$(1 + INT(RND * i))

NEXT

Finally, print the shuffled deck:

FOR i = 1 TO n

  PRINT card$(i)

NEXT


So altogether, here’s the entire program:

CLS

DATA queen of hearts,jack of diamonds,ace of spades,joker,king of clubs

 

n = 5

DIM card$(n)

FOR i = 1 TO n

  READ card$(i)

NEXT

 

RANDOMIZE TIMER

FOR i = n TO 2 STEP -1

  SWAP card$(i), card$(1 + INT(RND * i))

NEXT

 

FOR i = 1 TO n

  PRINT card$(i)

NEXT

The computer will print something like this:

king of clubs

joker

jack of diamonds

queen of hearts

ace of spades

To shuffle a larger deck, change just the DATA and the line saying n=5.

3-Line Sort Putting words in alphabetical order — or putting numbers in numerical order — is called sorting.

Here are a dozen names: Sue, Ann, Joe, Alice, Ted, Jill, Fred, Al, Sam, Pat, Sally, Moe. Let’s make the computer alphabetize them (sort them).

Begin by clearing the screen:

CLS

To make the program run faster, tell the computer that all numbers in the program will be short integers:

DEFINT A-Z

Put the list of names in a DATA statement:

DATA Sue,Ann,Joe,Alice,Ted,Jill,Fred,Al,Sam,Pat,Sally,Moe

We have 12 names:

n = 12

Let Sue by called x$(1), Ann be called x$(2), Joe be called x$(3), etc. Here’s how:

DIM X$(n)

FOR i = 1 TO n

  READ x$(i)

NEXT

Alphabetize the names, by using the following strategy.…

Compare the first name against the second; if they’re not in alphabetical order, swap them. Compare the second name against the third; if they’re not in alphabetical order, swap them. Compare the third name against the fourth; if they’re not in alphabetical order, swap them. Continue that process, until you finally compare the last two names. But each time you swap, you must start the whole process over again, to make sure the preceding names are still in alphabetical order. Here’s the code:

10 FOR i = 1 TO n - 1

  IF x$(i) > x$(i + 1) THEN SWAP x$(i), x$(i + 1): GOTO 10

NEXT


Finally, print the alphabetized list:

FOR I = 1 TO n

  PRINT x$(i)

NEXT

So altogether, the program looks like this:

CLS

DEFINT A-Z

DATA Sue,Ann,Joe,Alice,Ted,Jill,Fred,Al,Sam,Pat,Sally,Moe

n = 12

DIM x$(n)

FOR i = 1 TO n

  READ x$(i)

NEXT

10 FOR i = 1 TO n - 1

  IF x$(i) > x$(i + 1) THEN SWAP x$(i), x$(i + 1): GOTO 10

NEXT

FOR i = 1 TO n

  PRINT x$(i)

NEXT

The computer will print:

Al

Alice

Ann

Fred

Jill

Joe

Moe

Pat

Sally

Sam

Sue

Ted

In that program, the sorting occurs in the FOR loop that begins at line 10. Those 3 lines are called the 3-Line Sort.

Those 3 lines form a loop. The part of the loop that the computer encounters the most often is the phrase “IF x$(i) > x$(i + 1)”. In fact, if you tell the computer to alphabetize a list of names that’s long (several hundred names), the computer spends the majority of its time repeatedly handling “IF x$(i) > x$(i + 1)”.

How long will the computer take to handle a long list of names? The length of time depends mainly on how often the computer encounters the phrase “IF x$(i) > x$(i + 1)”.

If the list contains n names, the number of times that the computer encounters the phrase “IF x$(i) > x$(i + 1)” is approximately n3/8. Here are some examples:

n (number of names)    n3 / 8 (approximate number of encounters)

     10                                                125

     12                                                216

     20                                             1,000

     40                                             8,000

   100                                         125,000

1,000                                  125,000,000

For example, the chart says that a list of 12 names requires approximately 216 encounters.

The 216 is just an approximation: the exact number of encounters depends on which list of names you’re trying to alphabetize. If the list is nearly in alphabetical order already, the number of encounters will be less than 216; if the list is in reverse alphabetical order, the number of encounters will be more than 216; but if the list is typical (not yet in any particular order), the number of encounters will be about 216. For the list that we tried (Sue, Ann, Joe, Alice, Ted, Jill, Fred, Al, Sam, Pat, Sally, Moe), the exact number of encounters happens to be 189, which is close to 216.

How long will your computer take to finish sorting? The length of time depends on which computer you have, how many names are in the list, and how long each name is. A typical 486DX-66 computer (handling a list of typical names) requires about .00002 seconds per encounter. Multiplying the number of encounters by .00002 seconds, you get:

Number of names    Encounters (n3 / 8)             Time___

     10                                      125                         .0025   secs

     12                                      216                         .00432 secs

     20                                   1,000                         .02       secs

     40                                   8,000                         .16       secs

   100                               125,000                       2.5         secs

1,000                        125,000,000                 2500            secs = about 42 minutes

5-Line Sort To make the program run faster, use the 5-Line Sort instead, which uses this strategy.… Compare the first name against the second (that comparison is called i=1), then compare the second name against the third (that comparison is called i=2), then compare the third name against the fourth (that comparison is called i=3), etc. If you find a pair of names that are out of order, swap them and then recheck the pairs that came before. To “recheck the pairs that came before”, start with the most recent pairs and work back toward the first name (FOR j = i TO 1 STEP -1), swapping whenever necessary, until you come to a pair that doesn’t need to be swapped. When you come to a pair that doesn’t need to be swapped, stop the rechecking and proceed to the next i.

Here’s the code:

FOR i = 1 TO n - 1

  FOR j = i TO 1 STEP -1

    IF x$(j) > x$(j + 1) THEN SWAP x$(j), x$(j + 1) ELSE GOTO 10

  NEXT

10 NEXT

The IF line says: if x$(j) and x$(j + 1) are out of order, SWAP them; but if they’re not out of order, get out of the j loop and GOTO the NEXT i instead.

Even though that 5-Line Sort is longer to type than the 3-Line Sort, the computer handles the 5-Line Sort faster, because its “GOTO 10” lets the computer hop ahead to the NEXT i instead of forcing the computer to go back to the “FOR i = 1”.

For the 5-Line Sort, the number of times the computer encounters the phrase “IF x$(j) > x$(j + 1)” is just n2/4:

Number of names       Encounters (n2 / 4)              Time__

     10                                     25                             .0005   secs

     12                                     36                             .00072 secs

     20                                   100                             .002     secs

     40                                   400                             .008     secs

   100                                2,500                             .05       secs

1,000                            250,000                           5            secs


8-Line Sort The 5-Line Sort compares just adjacent pairs: x$(j) and x$(j+1). The 8-Line Sort compares pairs that are farther apart: x$(j) and x$(j+d), where d is a big distance. So the 8-Line Sort resembles the 5-Line Sort but says +d instead of +1, and says -d instead of -1:

FOR i = 1 TO n - d

  FOR j = i TO 1 STEP -d

    IF x$(j) > x$(j + d) THEN SWAP x$(j), x$(j + d) ELSE GOTO 10

  NEXT

10 NEXT

But how big is d?

Begin by making d be a big number, about 1/3 as big as n, and perform those 5 lines. Then divide by 3 again, so d becomes about 1/9 as big as n, and perform those 5 lines again. Then divide by 3 again, so d becomes about 1/27 as big as n, and perform those 5 lines again. Keep dividing by 3, until d finally becomes 1, which makes those 5 lines act exactly the same as the 5-Line Sort. But during that last pass through the data, when d is 1, the computer performs the 5 lines very quickly, since the earlier passes already put the names into roughly alphabetical order by comparing pairs that were far apart.

Moreover, those early passes consumed very little time, since during those passes the computer did the FOR j loop very few times. (It did that loop few times because it said to “STEP -d”, where d was a big number.)

Here’s the complete 8-Line Sort:

d = n

2 d = d \ 3 + 1

FOR i = 1 TO n - d

  FOR j = i TO 1 STEP -d

    IF x$(j) > x$(j + d) THEN SWAP x$(j), x$(j + d) ELSE GOTO 10

  NEXT

10 NEXT

IF d > 1 THEN GOTO 2

In line 2, the symbol “\” says to do integer division, so the computer will divide by 3 but ignore all digits after the decimal point. Altogether, line 2 says this: to get the new d, divide the old d by 3 (ignoring all digits after the decimal point) and then add 1. That “+ 1” makes the new d be slightly more than the old d divided by 3.

For the 8-Line Sort, the number of times the computer encounters the phrase “IF x$(j) > x$(j + d)” is just 1.5*(n-1)^(4/3):

Number of names       Encounters      Time__

     10                                   28            .00056 secs

     12                                   37            .00074 secs

     20                                   76            .00152 secs

     40                                 198            .00396 secs

   100                                 687            .01374 secs

1,000                            14,980            .2996  secs

Notice that the 8-Line Sort handles 1,000 names in .2996 seconds. That’s much faster than the 5-Line Sort, which takes 5 seconds. But to handle just 10 names, the 8-Line Sort does not run faster than the 5-Line Sort. So use the 8-Line Sort just for handling long lists of names.

We’ve sure come a long way! To alphabetize 1,000 names, the 3-Line Sort took about 42 minutes; the 5-Line Sort took 5 seconds; the 8-Line Sort took about .3 seconds.

If you try running those sorting methods on your computer, you’ll find the timings are different, since the exact timings depend on which computer you have, the length of each name, and how badly the names are out of order.

Famous sorts Though I “invented” all those sorting methods, most of them just improve a little on methods developed by others.

The 5-Line Sort improves slightly on the Shuttle Sort, which was invented by Shaw & Trimble in 1983. The 8-Line Sort improves slightly on the Shell Sort, which was invented by Donald Shell in 1959 and further developed by Hibbard & Boothroyd in 1963, Peterson & Russell in 1971, and Knuth in 1973.


Sorting a phone directory Suppose you want to alphabetize this phone directory:

Name                Phone number

Mary Smith        277-8139

John Doe            513-9134

Russ Walter         666-6644

Information        555-1212

Just use one of the alphabetizing programs I showed you! Type the DATA like this:

DATA Smith Mary 277-8139,Doe John 513-9134

DATA Walter Russ 666-6644,Information 555-1212

The computer will print:

Doe John 513-9134

Information 555-1212

Smith Mary 277-8139

Walter Russ 666-6644

Sorting numbers Suppose you want to put a list of numbers into increasing order. For example, if the numbers are 51, 4.257, -814, 62, and .2, let’s make the computer print:

-814

 .2

 4.257

 51

 62

To do that, just use one of the alphabetizing programs I showed you — but in the DATA statement, put the numbers instead of strings, and say “x!” instead of “x$”.

To put a list of numbers into decreasing order, begin by writing a program that puts them into increasing order, and then change each “> x” to “< x”.

Sequential data files

Here’s a simple program:

CLS

PRINT "eat"

PRINT 2 + 2

PRINT "eggs"

It makes the computer print this message onto your screen:

eat

 4

eggs

Instead of printing that message onto your screen, let’s make the computer print the message onto your disk. Here’s how.…

OPEN FOR OUTPUT This program prints the message onto your disk, instead of onto your screen:

CLS

OPEN "joan" FOR OUTPUT AS 1

PRINT #1, "eat"

PRINT #1, 2 + 2

PRINT #1, "eggs"

CLOSE

Those PRINT lines make the computer print the message onto your disk instead of onto your screen. Each line says PRINT #1, which means: print onto the disk.

The OPEN line is an introductory line that tells the computer where on the disk to print the message. The OPEN line says: find a blank place on the disk, call it JOAN, and make JOAN be file #1. So PRINT #1 will mean: print onto file #1, which is JOAN.

Any program that says OPEN should also say CLOSE, so the bottom line says CLOSE. The CLOSE line makes the computer put some “finishing touches” on JOAN, so that JOAN becomes a perfect, finished file.

When you run that program, the computer will automatically put onto the disk a file called JOAN that contains this message:

eat

 4

eggs


After running that program, try this experiment.… Exit from QBASIC (by choosing Exit from the File menu), so the computer says:

C:\>

After that C prompt, type “dir”, so the screen looks like this:

C:\>dir

When you press the ENTER key at the end of that line, the computer will print the names of all the disk’s files — and one of the names it prints will be JOAN.

After the C prompt, try saying “type joan”, like this:

C:\>type joan

That makes the computer show you what’s in JOAN; the computer will say:

eat

 4

eggs

OPEN FOR INPUT To see the message that’s in JOAN, run this program, which inputs from JOAN and prints onto your screen:

CLS

OPEN "joan" FOR INPUT AS 1

 

INPUT #1, a$

PRINT a$

 

INPUT #1, b

PRINT b

 

INPUT #1, c$

PRINT c$

 

CLOSE

The OPEN line prepares the computer to input from JOAN.

The next line inputs a$ from JOAN, so a$ is “eat”. The next line prints “eat” onto your screen.

The next pair of lines input b from JOAN (so b is 4) and print 4 onto your screen. The next pair of lines input c$ from JOAN (so c$ is “eggs”) and print “eggs” onto your screen. So altogether, on your screen you’ll see:

eat

 4

eggs

The CLOSE line tells the computer that you’re done using JOAN for a while (until you say OPEN again).

OPEN FOR APPEND After you’ve put JOAN onto the disk, so that JOAN consists of “eat” and 4 and “eggs”, try running this program:

CLS

OPEN "joan" FOR APPEND AS 1

PRINT #1, "good morning!"

CLOSE


In the OPEN line, the word APPEND tells the computer to keep adding onto JOAN. So when the computer comes to the PRINT line, it adds “good morning!” onto JOAN, and JOAN becomes this:

eat

 4

eggs

good morning!

Erasing For your next experiment, try running this program:

CLS

OPEN "joan" FOR OUTPUT AS 1

PRINT #1, "pickles are pleasant"

CLOSE

Since the OPEN line does not say APPEND, the computer will not keep adding onto JOAN. Instead, the computer erases everything that’s been in JOAN. So when the computer finishes processing the OPEN line, JOAN’s become blank.

The PRINT line puts “pickles are pleasant” into JOAN. So at the end of the program, JOAN includes “pickles are pleasant”; but JOAN does not include “eat” and 4 and “eggs” and “good morning!”, which have all been erased.

OUTPUT or INPUT or APPEND? In the OPEN line, you can say OUTPUT or INPUT or APPEND. Here’s how they differ:

If the OPEN line says FOR INPUT,     the program can say INPUT #1 but cannot say PRINT #1.

If the OPEN line says FOR OUTPUT,the program can say PRINT #1 but cannot say INPUT #1.

If the OPEN line says FOR APPEND,  the program can say PRINT #1 but usually not INPUT #1.

Here’s what happens if you say OPEN “joan” and the file JOAN exists already:

FOR INPUT       makes the computer use JOAN without changing JOAN.

FOR APPEND makes the computer use JOAN and lengthen it (by appending extra lines to its end).

FOR OUTPUT   makes the computer erase JOAN and then create a totally new JOAN.

Here’s what happens if you say OPEN “joan” when JOAN doesn’t exist yet:

FOR OUTPUT or FOR APPEND  makes the computer create JOAN.

FOR INPUT                                     makes the computer gripe and say “File not found”.

The following program plays a trick: if JOAN doesn’t exist yet, the program creates JOAN; if JOAN exists already, the program leaves JOAN alone.

CLS

OPEN "joan" FOR APPEND AS 1

CLOSE

Loops This program lets you put the names of all your friends onto the disk:

CLS

OPEN "friends" FOR OUTPUT AS 1

DO

  PRINT "Please type a friend's name (or the word 'end')"

  INPUT friend$: IF friend$ = "end" THEN EXIT DO

  PRINT #1, friend$

LOOP

CLOSE

The OPEN line makes the computer find a blank space on the disk and call it FRIENDS. The first PRINT line makes the computer print:

Please type a friend's name (or the word 'end')

The INPUT line prints a question mark and waits for you to type something; whatever you type will be called friend$. For example, if you type Mary Williams, then friends$ will be Mary Williams, and the next line prints the name Mary Williams onto the disk.

The lines are in a DO loop, so that you can type as many names as you wish. (Remember to press the ENTER key after each name.)

When you’ve finished typing the names of all your friends, type the word “end”. Then the last part of the INPUT line will make the computer EXIT from the DO loop and CLOSE the file.

This program makes the computer look at the FRIENDS file and copy all its names to your screen:

CLS

OPEN "friends" FOR INPUT AS 1

DO UNTIL EOF(1)

  INPUT #1, friend$

  PRINT friend$

LOOP

CLOSE

PRINT "Those are all the friends."


The OPEN line prepares the computer to input from the FRIENDS file. The lines DO and LOOP make the computer do the indented lines repeatedly. The first indented line makes the computer input a string from the file and call the string friend$; so friend$ becomes the name of one of your friends. The next indented line prints that friend’s name onto your screen. Since those indented lines are in a loop, the names of all your friends are printed on the screen.

Eventually, the computer will reach the end of the file, and there won’t be any more names to input from the file. In the DO line, the “UNTIL EOF(1)” means: if the computer reaches the End Of the File and can’t input any more names from it, the computer should stop looping and proceed to the line underneath LOOP. That line makes the computer CLOSE the file. Then the computer will print on your screen, “Those are all the friends.”

As that program illustrates, to read from a file you create a DO loop. Above the loop, say OPEN FOR INPUT; below the loop, say CLOSE; in the loop, say INPUT #1; next to the DO, say UNTIL EOF(1).

LOF In the middle of your program, if you say PRINT LOF(1), the computer will tell you the Length Of the File: it will tell you how many bytes are in the file.

Multiple files If you want the computer to handle two files simultaneously, use two OPEN statements. At the end of the first OPEN statement, say “AS 1”; at the end of the second OPEN statement, say “AS 2”.

For the second file, say PRINT #2 instead of PRINT #1, say INPUT #2 instead of INPUT #1, say EOF(2) instead of EOF(1), and say LOF(2) instead of LOF(1).

How to CLOSE The CLOSE statement closes all files. To be more specific, you can say CLOSE 1 (which closes just the first file) or CLOSE 2 (which closes just the second).

Whenever you’re done using a file, CLOSE it immediately. When you say CLOSE, the computer puts finishing touches on the file that protect the file against damage.

Suppose that halfway through your program, you finish using file 2 but want to continue using file 1. Say CLOSE 2 there, and delay saying CLOSE 1 until later.

Random access

On a disk, you can store two popular kinds of data files. The simple kind is called a sequential-access data file; the complicated kind is called a random-access data file. You’ve already learned how to create and retrieve a sequential-access file. Now let’s look at random-access.

Though more complicated than sequential-access data files, random-access data files have an advantage: they let you skip around. In a sequential-access data file, you must look at the first item of data, then the second, then the third, etc. In a random-access data file, you can look at the seventh item of data, then skip directly to the tenth, then hop back to the third, then skip directly to the sixth, etc.

Each item is called a record. The number of characters (bytes) in the record is called the record’s length. For example, if a record contains 20 characters, the record’s length is 20. In a random-access file, all records must have the same length as each other.


PUT Here’s how to write a program that creates a random-access file. Begin the program by saying:

CLS

Let’s make each record be a string containing 20 characters:

DIM record AS STRING * 20

Let’s make the file’s name be JIM:

OPEN "jim" FOR RANDOM AS 1 LEN = LEN(record)

Let’s make JIM’s 7th record be “Love makes me giggle” (which contains 20 characters):

record = "Love makes me giggle"

PUT 1, 7, record

Let’s make JIM’s 9th record be “Please hold my hand”:

record = "Please hold my hand"

PUT 1, 9, record

Since JIM’s record length is supposed to be 20 characters but “Please hold my hand” contains just 19 characters, the computer will automatically add a blank to the end of “Please hold my hand”.

Let’s make JIM’s 4th record be “I love Lucy”:

record = "I love Lucy"

PUT 1, 4, record

The computer will automatically add blanks to the end of “I love Lucy”.

To finish the program, say:

CLOSE

So altogether, the program looks like this:

CLS

DIM record AS STRING * 20

OPEN "jim" FOR RANDOM AS 1 LEN = LEN(record)

 

record = "Love makes me giggle"

PUT 1, 7, record

 

record = "Please hold my hand"

PUT 1, 9, record

 

record = "I love Lucy"

PUT 1, 4, record

 

CLOSE

When you run that program, the computer will automatically put onto the disk a file called JIM in which each record is a 20-character string.

After running that program, try this experiment.… Exit from QBASIC (by choosing Exit from the File menu), so the computer says:

C:\>

After that C prompt, type “dir”. The computer will print the names of all the disk’s files — and one of the names it prints will be JIM.

After the C prompt, try saying “copy jim con /b”. The computer will show you what’s in JIM. You’ll see that JIM includes “I love Lucy” (in the 4th record), “Love makes me giggle” (in the 7th record), and “Please hold my hand” (in the 9th record). Since the program didn’t say what to put into the other records, those other records still contain garbage (whatever data was sitting on that part of the hard disk before the program ran).

GET This program makes the computer tell you JIM’s 7th item:

CLS

DIM record AS STRING * 20

OPEN "jim" FOR RANDOM AS 1 LEN = LEN(record)

 

GET 1, 7, record

PRINT record

 

CLOSE


Multi-field records Let’s write a program that creates a fancier random-access file. As usual, begin by saying:

CLS

Let’s make each record be a combination of two parts:

The record’s first part, called “part a”, will be a string of 20 characters.

The record’s second part, called “part b”, will be a string of 5 characters.

Here’s how:

TYPE combination

  a AS STRING * 20

  b AS STRING * 5

END TYPE

DIM record AS combination

Let’s make the file be called JACK:

OPEN "jack" FOR RANDOM AS 1 LEN = LEN(record)

Let’s make the 6th record’s first part be “I want turkey on rye” and the second part be “yummy”:

record.a = "I want turkey on rye"

record.b = "yummy"

PUT 1, 6, record

To finish the program, say:

CLOSE

So altogether, here’s the program:

CLS

TYPE combination

  a AS STRING * 20

  b AS STRING * 5

END TYPE

DIM record AS combination

OPEN "jack" FOR RANDOM AS 1 LEN = LEN(record)

 

record.a = "I want turkey on rye"

record.b = "yummy"

PUT 1, 6, record

 

CLOSE

Go ahead: run that program!

Then run the following program, which makes the computer tell you JACK’s 6th record:

CLS

TYPE combination

  a AS STRING * 20

  b AS STRING * 5

END TYPE

DIM record AS combination

OPEN "jack" FOR RANDOM AS 1 LEN = LEN(record)

 

GET 1, 6, record

PRINT record.a 

PRINT record.b 

 

CLOSE

Lengths If you say PRINT LOF(1), the computer will tell you the Length Of the File (how many bytes are in the file). If you say PRINT LEN(record), the computer will tell you the LENgth of a record (how many bytes are in a record).

Since LOF(1) is the length of the file, and LEN(record) is the length of a record, this line makes the computer tell you how many records are in the file:

PRINT LOF(1) \ LEN(record)

End of the file The EOF function doesn’t work well for random-access files. To deal with the end of the file, use the following trick instead.

Since the number of records in the file is LOF(1) \ LEN(record), these lines print all the records:

FOR i = 1 TO LOF(1) \ LEN(record)

  GET 1, i, record

  PRINT record.a

  PRINT record.b

NEXT

Numeric data To make each record consist of a 20-character string followed by a 5-character string, you learned to say this:

TYPE combination

  a AS STRING * 20

  b AS STRING * 5

END TYPE

DIM record AS combination

Here’s how to make each record consist of a 20-character string followed by a short INTEGER followed by a LONG integer followed by a SINGLE-precision real number followed by a DOUBLE-precision real number:

TYPE combination

  a AS STRING * 20

  b AS INTEGER

  c AS LONG

  d AS SINGLE

  e AS DOUBLE

END TYPE

DIM record AS combination

A short INTEGER consumes 2 bytes, a LONG integer consumes 4 bytes, a SINGLE-precision real number consumes 4 bytes, and a DOUBLE-precision real number consumes 8 bytes; so in that example, the record’s length is 20 + 2 + 4 + 4 + 8, which is 38 bytes.

Descriptive variables Instead of talking about “part a” and “part b” of a record, you can pick names that are more descriptive. For example, if a record consists of a person’s nickname and age, you can say:

TYPE combination

  nickname AS STRING * 10

  age AS integer

END TYPE

DIM record AS combination

To make the 6th record contain my nickname (Russy-poo) and age (48), say:

record.nickname = "Russy-poo"

record.age = 48

PUT 1, 6, record

LOC If you say PRINT LOC(1), the computer tells you which record it just dealt with. It tells you the record’s LOCation.

For example, if you say “PUT 1, 7, record” or “GET 1, 7, record” and then say PRINT LOC(1), the computer prints the number 7.

Instead of saying “PUT 1, 7, record” or “PUT 1, 8, record”, you can leave the record’s number blank and say just:

PUT 1, , record

That makes the computer PUT the next record. For example, it will PUT the 9th record if the previous PUT or GET mentioned the 8th. Saying “PUT 1, , record” has the same effect as saying “PUT 1, LOC(1) + 1, record”.

If you say —

GET 1, , record

the computer will GET the next record. For example, it will GET the 9th record if the previous PUT or GET mentioned the 8th.

Multiple files If you want the computer to handle two random-access files simultaneously, use two OPEN statements. In the first OPEN statement, say “AS 1 LEN = LEN(record)”; in the second OPEN statement, say “AS 2 LEN = LEN(record2)”.

For the second file, say 2 instead of 1 (in the OPEN, PUT, and GET statements and in the LOF and LOC functions); say combination2 instead of combination; and say record2 instead of record.


Create a database

I’m going to show you how to write a program that creates a database, in which you can store information about your friends & enemies, your business & bills, birthdays & appointments, desires & dreads, and whatever else bothers you.

Here’s how the program works.…

When you run the program, the computer begins by asking, “What topic interests you?” If you type a topic the computer knows about, the computer will tell you what data it knows about that topic; then the computer will let you change that data. If you type a topic that the computer doesn’t know anything about, the computer will admit ignorance then let you teach the computer about that topic.

After dealing with the topic you requested, the computer will let you request additional topics.

If you type a question mark, the computer will print a list of all the topics in its database so far. If you type an x, the computer will exit from the program.

Simple chronological database The simplest way to write the program is to write a main procedure and seven SUB procedures:


 


Allow 3000 topics & data about them. Share with SUBs.    DIM SHARED topic$(3000), data$(3000)

Share these variables with the SUBs.                                   COMMON SHARED topic.desired$, data.inputted$, n, i

Make n (the number of topics) start at 0.                              n = 0

Do the following loop repeatedly:                                      DO

   Clear the screen.                                                               CLS

   Ask the human, “What topic interests you?”                       PRINT "What topic interests you? ";

   Remind the human to type “?” if unsure, “x” to exit.          PRINT "(If unsure, type a question mark. To exit, type an x.)"

   Make the human’s response be called topic.desired$.          10 LINE INPUT topic.desired$

   If human confused, list all topics & ask human again.       IF topic.desired$ = "?" THEN list.all.topics: GOTO 10

   If the human’s response is “x”, exit from the program.        IF topic.desired$ = "x" THEN END

   Otherwise, capitalize the response & delete extra blanks.     topic.desired$ = UCASE$(LTRIM$(RTRIM$(topic.desired$)))

   Search for the topic that the human requested.                     search.for.topic

Repeat that loop until the human types “x”.                         LOOP

 

Here’s how to list all topics:                                                  SUB list.all.topics

   Clear the screen.                                                               CLS

   If there are no topics yet, do this:                                        IF n = 0 THEN

       Say “I don’t know any topics yet.”                                     PRINT "I don't know any topics yet. My mind is still blank. ";

       Say “Please teach me a new topic.”                                    PRINT "Please teach me a new topic."

   If some topics exist, do this:                                                ELSE

       Say “I know about these topics”.                                         PRINT "I know about these topics:"

       Leave a blank line underneath that heading.                        PRINT

       For every individual topic in the database,                       FOR i = 1 TO n

       print that topic, then hop to the next zone.                            PRINT topic$(i),

       When you finish printing all the topics,                              NEXT

       return to the screen’s left margin                                        PRINT

       and leave a blank line                                                          PRINT

       then say “Pick one of those or teach me a new one.”         PRINT "Pick one of those topics, or teach me a new one."

   At the end of all that,                                                          END IF

   ask the human again, “What topic interests you?”               PRINT "What topic interests you? (To exit, type an x.)"

                                                                                          END SUB

 

Here’s how to search for the topic the human requested:    SUB search.for.topic

   Start to look at every individual topic in the database.      FOR i = 1 TO n

   If a topic’s the one desired, just do “found.the.topic”.         IF topic$(i) = topic.desired$ THEN found.the.topic: EXIT SUB

   If the desired topic is not in the database,                             NEXT

   the topic is missing, so do “missing.topic”.                       missing.topic

                                                                                          END SUB

 

Here’s how to act when situation is “found.the.topic”:          SUB found.the.topic

   Clear the screen.                                                               CLS

   Say “Here’s what I know about” the topic.                        PRINT "Here's what I know about "; topic.desired$; ":"

   Print the data that’s in the database about that topic.           PRINT data$(i)

   Leave a blank line.                                                            PRINT

   Ask “Do you want to change that information?”                 INPUT "Do you want to change that information"; response$

   If the human says “yes” or “y”, change the info.                 IF response$ = "yes" OR response$ = "y" THEN change.the.info

                                                                                       END SUB


Here’s how to change the info:                                              SUB change.the.info

   Say that the computer’s erased old info about the topic.       PRINT "Okay. I've erased that information about "; topic.desired$; "."

   Leave a blank line.                                                            PRINT

   Tell the human to input new info about the topic.                PRINT "Type what you want me to know about "; topic.desired$; "."

   Say that typing an x will delete the topic.                            PRINT "(If you want me to forget about "; topic.desired$; ", type an x.)"

   Wait for the human’s response.                                         LINE INPUT data.inputted$

   If response is x, delete the topic; if not x, use new data.       IF data.inputted$ = "x" THEN delete.the.topic ELSE data$(i) = data.inputted$

                                                                                          END SUB

 

Here’s how to delete the topic:                                              SUB delete.the.topic

   Replace that topic by the last topic (topic #n).                    topic$(i) = topic$(n)

   Replace that topic’s data by the last topic’s data.                 data$(i) = data$(n)

   Decrease the number of topics, by subtracting 1.                  n = n - 1

                                                                                          END SUB

 

Here’s how to act when situation is “missing.topic”:              SUB missing.topic

   Clear the screen.                                                               CLS

   Say “I don’t know anything about” that topic.                     PRINT "I don't know anything about "; topic.desired$; "."

   Say “Please tell me about” that topic.                                  PRINT "Please tell me about "; topic.desired$; "."

   Say “If you don’t want to tell me, type an x.”                     PRINT "(If you don't want to tell me, type an x.)"

   Wait for the human’s response.                                         LINE INPUT data.inputted$

   If the human didn’t type an x, insert the topic.                    IF data.inputted$ <> "x" THEN insert.the.topic

                                                                                          END SUB

 

Here’s how to insert the topic:                                              SUB insert.the.topic

   Increase the number of topics, by adding 1.                       n = n + 1

   Append the new topic. Make it topic #n.                             topic$(n) = topic.desired$

   Also append the new topic’s data. Make it data #n.              data$(n) = data.inputted$

                                                                                          END SUB


The program stores the topics in chronological order: if you begin by feeding it information about SUE and then information about CAROL, it will let topic$(1) be “SUE” and let topic$(2) be “CAROL”.

Copy to disk That program stores the data just in the RAM — not on a disk. When you turn off the power, the RAM forgets all the data!

Let’s write a fancier version that copies the data onto the hard disk before the program ends.

To write the fancier version, just change the main procedure; the seven SUB procedures remain the same! Here’s how to write the main procedure:



Allow 3000 topics & data about them. Share with SUBs.    DIM SHARED topic$(3000), data$(3000)

Share these variables with the SUBs.                                   COMMON SHARED topic.desired$, data.inputted$, n, i

If the database file doesn’t exist yet, create it                        OPEN "database" FOR APPEND AS 1

and polish it up.                                                                 CLOSE                                                     

Prepare to copy from hard disk’s database file to RAM.     OPEN "database" FOR INPUT AS 1

Make n (the number of topics) start at 0.                              n = 0

Repeat the following, until reaching end of database file:       DO UNTIL EOF(1)          

   Increase the number of topics                                           n = n + 1                         

   becausee inputting another topic from the database file        LINE INPUT #1, topic$(n)

   and inputting the topic’s data.                                           LINE INPUT #1, data$(n)

Do that repeatedly until the database is done,                     LOOP                     

then close the database file.                                                CLOSE                    

Do the following loop repeatedly:                                      DO

   Clear the screen.                                                               CLS

   Ask the human, “What topic interests you?”                       PRINT "What topic interests you? ";

   Remind the human to type “?” if unsure, “x” to exit.          PRINT "(If unsure, type a question mark. To exit, type an x.)"

   Make the human’s response be called topic.desired$.          10 LINE INPUT topic.desired$

   If human confused, list all topics & ask human again.       IF topic.desired$ = "?" THEN list.all.topics: GOTO 10

   If the human’s response is “x”, exit from the loop.              IF topic.desired$ = "x" THEN EXIT DO

   Otherwise, capitalize the  response & delete extra blanks.    topic.desired$ = UCASE$(LTRIM$(RTRIM$(topic.desired$)))

   Search for the topic that the human requested.                     search.for.topic

Repeat that loop until the human types “x”.                         LOOP

Prepare to copy from RAM to hard disk’s database file.     OPEN "database" FOR OUTPUT AS 1

For all the topics,                                                                  FOR i = 1 TO n                

copy topic from the RAM to the hard disk’s database file        PRINT #1, topic$(i)         

and also copy the topic’s data.                                                 PRINT #1, data$(i)          

Do that repeatedly, until all the topics are done,                    NEXT                          

then close the database file.                                                CLOSE                         


Alphabetical database Instead of chronological order, you might prefer alphabetical order.

For example, suppose you feed the computer information about SUE then CAROL then ZELDA then ALICE then JANE. Here’s what the computer’s memory would look like, in each kind of order:

Chronological order       Alphabetical order

SUE                ALICE

CAROL            CAROL

ZELDA            JANE

ALICE            SUE

JANE             ZELDA

Which is better: chronological order or alphabetical order?

Chronological order lets you quickly add a new name (just add it at the end of the list), but finding a name in the list is slow (since the list looks disorganized). Alphabetical order lets you find a name faster (since the list is alphabetized), but adding a new name to the alphabetized list is slow (since the only way to insert the new name is to make room for it by shoving other names out of the way).

So which is better?

Chronological order is the simplest to program and the fastest for inserting.

Alphabetical order is the fastest for finding information.

If you want to store the names in alphabetical order instead of chronological order, use these new versions of three SUB procedures:



Here’s how to search for the topic the human requested:    SUB search.for.topic

   What’s the topic’s position in database? 0 is “too low”,       too.low = 0

   but n + 1 is “too high”.                                                     too.high = n + 1

   Try guesses in between, as follows:                                    DO

       Find average (rounded up) of “too low” & “too high”.        i = (too.low + too.high + 1) \ 2

       If average is too high, just do “missing.topic”.                    IF i = too.high THEN missing.topic: EXIT SUB

       If the topic is found, just do “found.the.topic”.                   IF topic$(i) = topic.desired$ THEN found.the.topic: EXIT SUB

       Otherwise, adjust “too high” or “too low”,                      IF topic$(i) > topic.desired$ THEN too.high = i ELSE too.low = i

       then try another guess.                                                  LOOP

                                                                                          END SUB

 

Here’s how to delete the topic:                                              SUB delete.the.topic

   Decrease the number of topics.                                            n = n - 1

   Close the gap from the deleted topic,                                   FOR j = i TO n

   by moving topics                                                                   topic$(j) = topic$(j + 1)

   and their data.                                                                     data$(j) = data$(j + 1)

                                                                                            NEXT

                                                                                          END SUB

 

Here’s how to insert the topic:                                              SUB insert.the.topic

   Increase the number of topics.                                             n = n + 1

   To make room for the new topic,                                        FOR j = n TO i + 1 STEP -1

   move other topics out of the way                                          topic$(j) = topic$(j - 1)

   and move their data.                                                           data$(j) = data$(j - 1)

   When the moving is done,                                                   NEXT

   insert the new topic                                                             topic$(i) = topic.desired$

   and its data.                                                                      data$(i) = data.inputted$

                                                                                          END SUB


That new version of search.for.topic runs faster than the chronological version, because searching through an alphabetical list is faster than searching through a chronological list. (To search through the alphabetical list super-quickly, the new version of search.for.topic uses a trick called binary search.)

Unfortunately, the new versions of delete.the.topic and insert.the.topic run slower than the chronological versions. To get the high speed of the new search method, you must accept the slowness of the new delete & insert methods.

You’ve seen that chronological order is fast for inserting and deleting but slow for searching, whereas alphabetical order is exactly the opposite: it’s fast for searching but slow for inserting or deleting.

Tree-structured database Instead of using chronological order or alphabetical order, advanced programmers use a tree. Like chronological order, a tree lets you insert and delete quickly. Like alphabetical order, a tree lets you search quickly also.

Poets say, “only God can make a tree.” Does that mean advanced programmers are God?


To learn how to make a tree, begin by sketching a picture of a tree on paper. Since N is the alphabet’s middle letter, begin by writing the letter N, and put two arrows underneath it:

                   N

 

The left arrow is called the before-arrow; it will point to the names that come alphabetically before N. The right arrow is called the after-arrow; it will point to the names that come alphabetically after N.

For example, suppose your first topic is SUE. Since SUE comes alphabetically after N, put SUE at the tip of N’s after-arrow:

                   N

 

                            SUE

 

Suppose your next topic is CAROL. Since CAROL comes alphabetically before N, put CAROL at the tip of N’s before-arrow:

                   N

 

       CAROL                SUE

 

Suppose your next topic is ZELDA. Since ZELDA comes after N, we’d like to put ZELDA at the tip of N’s after-arrow; but SUE’s already stolen that position. So compare ZELDA against SUE. Since ZELDA comes after SUE, put ZELDA at the tip of SUE’s after-arrow:

                   N

 

       CAROL                SUE

 

                                ZELDA

 

Suppose your next topic is ALICE. Since ALICE comes before N, look at the tip of N’s before-arrow. Since CAROL’s stolen that position, compare ALICE against CAROL; since ALICE comes before CAROL, put ALICE at the tip of CAROL’s before-arrow:

                   N

 

       CAROL                SUE

 

  ALICE                         ZELDA

 


Suppose your next topic is JANE. Since JANE comes before N, look at the tip of N’s before-arrow. Since CAROL’s stolen that position, compare JANE against CAROL; since JANE comes after CAROL, put JANE at the tip of CAROL’s after-arrow:

                                       N

 

                           CAROL                SUE

 

                      ALICE     JANE                ZELDA

 

If the next few topics are FRED, then LOU, then RON, then BOB, the tree looks like this:

                                       N

 

                           CAROL                SUE

 

                      ALICE     JANE       RON      ZELDA

 

                         BOB  FRED LOU

 

Look at the arrows that point down from N. N’s before-arrow points to the group of names that come alphabetically before N (such as CAROL, ALICE, JANE, BOB, FRED, and LOU); N’s after-arrow points to the group of names that come alphabetically after N (such as SUE, RON, and ZELDA). Similarly, CAROL’s before-arrow points to the group of names that come alphabetically before CAROL (such as ALICE and BOB); CAROL’s after-arrow points to the group of names that come alphabetically after CAROL (such as JANE, FRED, and LOU).

Programmers treat the tree as if it were a “family tree”. CAROL is called the parent of ALICE and JANE, who are therefore called CAROL’s children. CAROL is called the ancestor of ALICE, JANE, BOB, FRED, and LOU, who are therefore called CAROL’s descendants. The arrows are called pointers.

To make the tree more useful, begin with “N !” instead of “N” (so you can choose “N” as a topic later), and number the topics in the order they appeared: since SUE was the first topic, put “1” in front of SUE; since CAROL was the second topic, put “2” in front of CAROL; since ZELDA was the third topic, put “3” in front of ZELDA, like this:

                                      N !

 

                          2CAROL               1SUE

 

                     4ALICE    5JANE      8RON     3ZELDA

 

                        9BOB 6FRED7LOU

 

To describe the tree to the computer, store this table in the computer’s memory:

Topic       Where the before-arrow points      Where the after-arrow points

0 N !           2                         1

1 SUE           8                         3

2 CAROL          4                         5

3 ZELDA          0                         0

4 ALICE          0                         9

5 JANE           6                         7

6 FRED           0                         0

7 LOU           0                         0

8 RON           0                         0

9 BOB           0                         0

That table represents the tree and is called the tree’s representation.

The table’s left column is in chronological order, but the other columns give information about alphabetizing. So a tree combines chronological order with alphabetical order: it combines the advantages of both. Adding a new topic to the tree is quick and easy (as in chronological order): just add the name to the bottom of the list, and adjust a few arrows. Using the tree to search for a topic is quick and easy (as in alphabetical order): just follow the arrows.

Editions 11-20 of this book contained a program that created a tree in a random-access data file. Phone me at 603-666-6644 to find out which editions are still available and their prices. But the best way to create a big, sophisticated database is to buy a database program such as Q&A (which I explained in the database chapter) or use a database programming language such as DBASE (which I’ll explain in the next chapter).

SHELL

In the middle of your program, you can make the computer perform a DOS command! Just say SHELL, and put the DOS command in quotation marks.

For example, this program tells you which version of DOS you’re using:

CLS

SHELL "ver"

This program displays a directory of all your files:

CLS

SHELL "dir /w"

This program changes the name JOE.BAS to FRED.BAS:

CLS

SHELL "rename joe.bas fred.bas"

This program deletes JOE.BAS from your hard disk:

CLS

SHELL "del joe.bas"

This program makes the computer run Windows:

CLS

SHELL "win"

Here are some short cuts:

To see what files are on your hard disk,

you can say FILES

(instead of SHELL “dir /w”).

To delete JOE.BAS from your hard disk,

you can say KILL “joe.bas”

(instead of SHELL “del joe.bas”).

To change the name JOE.BAS to FRED.BAS,

you can say NAME “joe.bas” AS “fred.bas”

(instead of SHELL “rename joe.bas fred.bas”).


ON ERROR GOTO

You can improve the way that the computer handles errors.

Errors in a simple program Here’s a simple program that divides two numbers and prints their quotient:

CLS

INPUT "What's your favorite number"; a

INPUT "What's another favorite number"; b

PRINT "The first number divided by the second is"; a / b

The program works for most numbers. But when the computer tries to divide, the computer will gripe if b is 0 (since you can’t divide by 0) or if the quotient’s too big to be a single-precision real number. (For example, if you try dividing 1E38 by .1, the answer is supposed to be 1E39; but the computer will gripe that the answer is too big for the computer to handle, since the biggest permissible single-precision real number is 3.402823E38.)

If b is 0, the computer will print this error message:

Division by zero

If the quotient’s too big to be a single-precision real number, the computer will print this error message:

Overflow

When the computer prints one of those error messages, the computer stops running the program and shows you the blue screen.

That confuses beginners! If a beginner tries to run your program and sees the computer say “Division by zero” or “Overflow” on a blue screen, the beginner might not understand what the computer means and might not understand what to do next.

Improved error-handling Instead of letting the computer say “Division by zero” or “Overflow”, let’s make the computer print this easier-to-understand message —

I can't handle that pair of numbers.

Please pick a different pair of numbers instead.

and then let the human type a new pair of numbers.

To do that, put these lines at the bottom of your program —

PRINT "I can't handle that pair of numbers."

PRINT "Please pick a different pair of numbers instead."

and tell the computer to do those lines whenever an error occurs in computing the quotient.

Here’s how:

CLS

10 INPUT "What's your favorite number"; a

INPUT "What's another favorite number"; b

ON ERROR GOTO 1000

  quotient = a / b

ON ERROR GOTO 0  

PRINT "The first number divided by the second is"; quotient

END

 

1000 PRINT "I can't handle that pair of numbers."      

PRINT "Please pick a different pair of numbers instead."

PRINT                                                  

RESUME 10                                              

In that program, the source of the error (a / b) is isolated: it’s made into a separate line (quotient = a / b). Above that line, say ON ERROR GOTO 1000; below that line, say ON ERROR GOTO 0. The ON ERROR GOTO 1000 means: if an error occurs in the indented line underneath, go to line 1000. Line 1000 is the beginning of the error-handling routine. The error-handling routine says that when an error occurs, print this —

I can't handle that pair of numbers.

Please pick a different pair of numbers instead.

then print a blank line and then RESUME the program at line 10, which makes the computer ask again “What’s your favorite number?”

Remember:

The bottom line of the error-handling routine should say RESUME.

The bottom line of the rest of the program should say END.

“ON ERROR GOTO 1000” should be paired with “ON ERROR GOTO 0”.

“ON ERROR GOTO 1000” means “Henceforth, if an error ever occurs, GOTO line 1000.”

“ON ERROR GOTO 0” means “Henceforth, if an error ever occurs, go nowhere; just process the error normally.”

In that program, the bottom four lines are called the error-handling routine or error handler or error trap. Making the computer go to the error trap is called trapping the error.

Error numbers Besides “Division by zero” and “Overflow”, there are many other errors that a program can make. Each error has a code number:

Code #Message

   1  NEXT without FOR

   2  Syntax error

   3  RETURN without GOSUB

   4  Out of DATA

   5  Illegal function call

   6  Overflow

   7  Out of memory

   8  Label not defined

   9  Subscript out of range

  10  Duplicate definition

  11  Division by zero

  12  Illegal in direct mode

  13  Type mismatch

  14Out of string space

  16  String formula too complex

  17  Cannot continue

  18  Function not defined

  19  No RESUME

  20  RESUME without error

  24  Device timeout

  25  Device fault

  26  FOR without NEXT

  27  Out of paper

  29  WHILE without WEND

  30  WEND without WHILE

  33  Duplicate label

  35  Subprogram not defined

  37  Argument-count mismatch

  38  Array not defined

  40  Variable required

  50  FIELD overflow

  51  Internal error

  52  Bad file name or number

  53  File not found

  54  Bad file mode

  55  File already open

  56  FIELD statement active

  57  Device I/O error

  58  File already exists

  59  Bad record length

  61  Disk full

  62  Input past end of file

  63  Bad record number

  64  Bad file name

  67  Too many files

  68  Device unavailable

  69  Communication-buffer overflow

  70  Permission denied

  71  Disk not ready

  72  Disk-media error

  73  Advanced feature unavailable

  74  Rename across disks

  75  Path/File access error

  76  Path not found

Whenever the computer detects an error, the computer makes ERR be the error-code number. For example, when the computer detects an Overflow error, the computer makes ERR be 6. If you say —

PRINT ERR

the computer will print 6.


You can use ERR in the error-handling routine. For example, here’s how to say “if the error was Overflow”:

IF ERR = 6 THEN

At the bottom of the error-handling routine, the RESUME line automatically makes the computer reset ERR to 0, so the computer is prepared to handle future errors.

Here’s the sophisticated way to divide two numbers:

CLS

10 INPUT "What's your favorite number"; a

INPUT "What's another favorite number"; b

ON ERROR GOTO 1000     

  quotient = a / b

ON ERROR GOTO 0        

PRINT "The first number divided by the second is"; quotient

END

 

1000 SELECT CASE ERR

  CASE 11

    PRINT "I can't divide by zero."

  CASE 6

    PRINT "The answer is too big for me to handle."

  CASE ELSE

    PRINT "I'm having difficulty."

END SELECT

PRINT "Please pick a different pair of numbers instead."

PRINT

RESUME 10

In that program, the error-handling routine says:

If the error-code number is 11 (which means “Division by zero”), print “I can’t divide by zero.”

If the error-code number is 6 (“Overflow”), print “The answer is too big for me to handle.”

If the error-code number is otherwise, print “I’m having difficulty.”

After printing one of those error messages, the computer will print “Please pick a different pair of numbers instead”. Then the computer will do RESUME 10, which goes back to line 10 and also resets ERR to 0.

Unnumbered RESUME If you don’t put any number after RESUME, the computer will go back to the line that contained the error.

If you say RESUME NEXT, the computer will go to the line underneath the line that contained the error. To make RESUME NEXT work properly, the line that contained the error should consists of just one statement (instead of statements separated by colons).


Memory cells

The computer’s memory chips consist of many memory cells. Each cell holds an integer from 0 to 255. For example, cell #49837 might hold the integer 139.

Segments The first 65536 cells (cell #0 through cell #65535) form segment 0. The next 65536 cells are in the next segment, which is called segment 16. The next 65536 cells are in segment 32; the next 65536 cells are in segment 48; the next 65536 cells are in segment 64; the next 65536 cells are in segment 80; etc. Notice that the segment numbers are multiples of 16.

Within each segment, the cells are numbered from 0 to 65535. For example, the first cell in segment 16 is called “cell #0 of segment 16”; the next cell in segment 16 is called “cell #1 of segment 16”; the last cell in segment 16 is called “cell #65535 of segment 16”.

PEEK This program finds out what number’s in cell #49837 of segment 0:

CLS

DEF SEG = 0

PRINT PEEK(49837)

The “DEF SEG = 0” tells the computer to use the memory’s main SEGment, which is SEGment 0. The bottom line makes the computer PEEK at cell #49837, find the number in that cell, and print that number on your screen. The number it prints will be an integer from 0 to 255. For example, it might be 139.

When dealing with memory cells, make sure your program begins with a DEF SEG line, to tell the computer which segment to look in. If you forget to say DEF SEG, the computer will look in its “favorite” segment, which is not segment 0.

Cell #1047 In cell #1047 of segment 0, the computer puts a number that describes the state of your keyboard. The computer computes that number by using this chart:

Start at 0.

Add     1 if the right SHIFT        key is being pressed now.

Add     2 if the left  SHIFT         key is being pressed now.

Add     4 if either Ctrl key             is being pressed now.

Add     8 if either Alt key           is being pressed now.

Add   16 if the SCROLL LOCK  is turned on (by an earlier keypress).

Add   32 if the NUM LOCK          is turned on (by an earlier keypress).

Add   64 if the CAPS LOCK          is turned on (by an earlier keypress).

Add 128 if the INSERT              is turned on (by an earlier keypress).

For example, if NUM LOCK and INSERT are turned on, that cell contains 32+128, which is 160.

This program shows you what’s in that cell:

CLS

DEF SEG = 0

PRINT PEEK(1047)

For example, if NUM LOCK and INSERT are turned on, the computer will print 160.


This program peeks at cell #1047 repeatedly:

CLS

DEF SEG = 0

DO

  PRINT PEEK(1047)

LOOP

If the NUM LOCK and INSERT keys are turned on, the computer will repeatedly print 160, like this:

 160

 160

 160

etc.

While that program keeps running, try pressing the SHIFT, Ctrl, Alt, SCROLL LOCK, NUM LOCK, CAPS LOCK, and INSERT keys. Each time you press any of those keys, the number 160 will change to a different number.

Cell #1048 In cell #1048 of segment 0, the computer puts a supplementary number describing your keyboard’s state. That number is computed as follows:

Start at 0.

Add     1 if the left Ctrl              key is being pressed now.

Add     2 if the left Alt                key is being pressed now.

Add   16 if the SCROLL LOCK  key is being pressed now.

Add   32 if the NUM LOCK          key is being pressed now.

Add   64 if the CAPS LOCK          key is being pressed now.

Add 128 if the INSERT              key is being pressed now.

This program shows you what’s in both of the keyboard-state cells:

CLS

DEF SEG = 0

DO

  PRINT PEEK(1047), PEEK(1048)

LOOP

While running that program, try pressing the Ctrl, Alt, SCROLL LOCK, NUM LOCK, CAPS LOCK, and INSERT keys. Watch how the numbers on the screen change!

That’s how computers work: in memory cells, the computer stores code numbers that represent what you and the computer are doing.

POKE Let’s make the computer turn on the CAPS LOCK (so all your typing will be capitalized), NUM LOCK (so typing on the numeric keypad will create numbers instead of arrows), and INSERT (so typing in the middle of a document will make the other words move out of the way).

In cell #1047, the code number for NUM LOCK is 32, CAPS LOCK is 64, and INSERT is 128, so the code number for their combination is 32+64+128, which is 224. To turn on CAPS LOCK, NUM LOCK, and INSERT, just put the code number 224 into cell #1047. Here’s how:

CLS

DEF SEG = 0

POKE 1047, 224

In that program, “POKE 1047, 224” means “put, into cell #1047, the number 224”.

Poking into cell 1047 or 1048 is safe (if you say DEF SEG = 0), but poking into other cells can be dangerous, since some of those cells are where the computer stores notes about your program, operating system, disks, and other devices. Poking wrong info into those cells can wreck your program, operating system, and the info on your disks.


all content copyright © 2002 / web design by josh feingold