The Secret Guide to Computers |
||
|
|
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 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: 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 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 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 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. 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 " O my darling, o my darling, o my darling Clementine," PRINT " You are lost and gone forever. Dreadful sorry, Clementine!" SLEEP 11 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." 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." 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 |