The Secret Guide to Computers
Series Let’s make the computer add together all the numbers from 7 to 100, so that the computer finds the sum of this series: 7 + 8 + 9 + ... + 100. Here’s how.
Let’s make the computer add together the squares of all the numbers from 7 to 100, so that the computer finds the sum of this series: (7 squared) + (8 squared) + (9 squared) +… + (100 squared). Here’s how:
It’s the same as the previous program, except that indented line says to add i*i instead of i. The bottom line prints the final sum, which is 338259.
Data sums This program adds together the numbers in the data:
The DATA line contains the numbers to be added. The DATA 0 is an end mark. The line saying “s = 0” starts the sum at 0. The READ statement reads an x from the data. The next line (s = s + x) adds x to the sum. The LOOP line makes the computer repeat that procedure for every x. When the computer has read all the data and reaches the end mark (0), the x becomes 0; so the computer will EXIT DO and PRINT the final sum, s.
Here’s how to make your output prettier.
The screen is divided into 5 wide columns, called zones. The leftmost zone is called zone 1; the rightmost zone is called zone 5.
Zones 1, 2, 3, and 4 are each 14 characters wide. Zone 5 is extra-wide: it’s 24 characters wide. So altogether, the width of the entire screen is 14+14+14+14+24, which is 80 characters. The screen is 80 characters wide.
A comma makes the computer jump to a new zone. Here’s an example:
The computer will print “sin” and “king” on the same line; but because of the comma before “king”, the computer will print “king” in the second zone, like this:
first zone second zone third zone fourth zone fifth zone
Here are the words of a poet who drank too much and is feeling spaced out:
The computer will print “love” in the first zone, “cries” in the second zone, and “out” in the third zone, so the words are spaced out like this:
This program’s even spacier:
The computer will print “love” in the first zone, “cries” in the second, “out” in the third, “to” in the fourth, “me” in the fifth, and the remaining words below, like this:
This program tells a bad joke:
The computer will print “I think you are ugly!”, then jump to a new zone, then print “I’m joking”, like this:
first zone second zone third zone fourth zone fifth zone
When you combine commas with semicolons, you can get weird results:
That line contains commas and semicolons. A comma makes the computer jump to a new zone, but a semicolon does not make the computer jump. The computer will print “eat”, then jump to a new zone, then print “me” and “at” and “balls”, then jump to a new zone, then print “no” and “w”. Altogether, the computer will print:
Skip a zone You can make the computer skip over a zone:
The computer will print “Joe” in the first zone, a blank space in the second zone, and “loves Sue” in the third zone, like this:
first zone second zone third zone fourth zone fifth zone
You can type that example even more briefly, like this:
Loops This program makes the computer greet you:
The computer will print “hello” many times. Each time will be in a new zone, like this:
Tables This program prints a list of words and their opposites:
Line 2 makes the computer print “good”, then jump to the next zone, then print “bad”. Altogether, the computer will print:
The first zone contains a column of words; the second zone contains the opposites. Altogether, the computer’s printing looks like a table. So whenever you want to make a table easily, use zones, by putting commas in your program.
Let’s make the computer print this table:
Here’s the program:
Line 2 prints the word “Number” at the top of the first column, and the word “Square” at the top of the second. Those words are called the column headings. The FOR line says i goes from 3 to 10; to begin, i is 3. The indented line makes the computer print:
The bottom line makes the computer do the same thing for the next i, and for the next i, and for the next; so the computer prints the whole table.
When the computer puts a line of information on your screen, the leftmost character in the line is said to be at position 1. The second character in the line is said to be at position 2.
This program makes the computer skip to position 6 and then print “HOT”:
The computer will print:
Here’s a fancier example:
The computer will skip to the 6th position, then print “hot”, then skip to the 13th position, then print “buns”:
Diagonal This program prints a diagonal line:
The FOR line says to do the loop 12 times, so the computer does the indented line. The first time the computer does the indented line, the i is 1, so the computer prints an asterisk at position 1:
The next time, the i is 2, so the computer skips to position 2 and prints an asterisk:
The next time, the i is 3, so the computer skips to position 3 and prints an asterisk:
Altogether, the program makes the computer print this picture:
Calendar Let’s make the computer print this message:
Here’s the program:
The DATA shows each month’s name and how many days are in the month. The READ line says to read a month’s name and how many days are in the month. The PRINT line makes the computer print the month’s name, then skip to the next zone, then print the word “has”, then print how many days, then print the word “days”.
Instead of making the computer say “January has 31 days”, let’s make the computer print all the days of each month:
Let’s make the computer print that on paper, for each month, so the paper shows a crude calendar for the entire year. To do that, just change the program’s PRINT line to this sequence:
In that sequence, the first LPRINT statement makes the computer print, on paper, the month’s name (“January”). The FOR loop makes the computer print each day (1, 2, 3, etc.). The bottom two lines (which both say LPRINT) make the computer leave blank space under January’s calendar, to separate it from February’s. Here’s the entire program:
It makes the computer print a calendar beginning like this:
You must eject the paper from the printer manually. For a leap year, change the DATA’s 28 to 29.
Pretty weeks Although that calendar program makes the computer print the right numbers for each month, it prints the numbers in the wrong places. Let’s make the computer print at most 7 numbers in each row, so each is a week.
To print the numbers in the right places, use TAB. So instead of saying —
That line will make the computer print each day in the right position… if we define t correctly. But how should we define t?
For Sunday, let’s make t be 1, so that Sunday begins at position 1. For Monday, let’s make t be 5, so that Monday begins at position 5. For Tuesday, let’s make t be 9; for Wednesday, 13; Thursday, 17; Friday, 21; and Saturday, 25. So whenever a day’s been printed, t should normally increase by 4 for the next day:
Saturday’s the last day of the week. After Saturday, we must begin a new week. So if t has passed Saturday (which is 25), we want t to become 1 (for Sunday); and if there are more days left in the month, we want the computer to press the ENTER key (to start a new week):
Which year would you like a calendar for: 2002? 2003? 2004? This program makes a pretty calendar for 2003:
Line 4 prints the heading, “Calendar for 2003”. Line 5 puts a blank line underneath the heading. Since 2003 begins on a Wednesday, the next line tells the computer to start t at 13 (which is the position for Wednesday). The next line saying LPRINT “Sun Mon Tue Wed Thu Fri Sat” puts a heading at the top of each month. The next-to-bottom line says: if the computer has reached the end of June (month 6) or December (month 12), eject the paper, so that the first half of the year is on one sheet of paper and the second half of the year is on the other.
The computer will print a calendar beginning like this:
If you want a different year, change line 4 (which says LPRINT “Calendar for 2003”) and line 6 (which says the year starts on Wednesday, t = 13). For a leap year, change the DATA’s 28 to 29.
While your running a program, the black screen show 25 lines of information. The screen’s top line is called line 1; underneath it is line 2; then comes line 3; etc. The bottom line is line 25.
Each line consists of 80 characters. The leftmost character is at position 1; the next character is at position 2; etc. The rightmost character is at position 80.
On the screen, the computer will print wherever you wish.
For example, to make the computer print the word “drown” so that “drown” begins at line 3’s 7th position, type this:
The computer will print the word’s first letter (d) at line 3’s 7th position. The computer will print the rest of the word afterwards.
You’ll see the first letter (d) at line 3’s 7th position, the next letter (r) at the next position (line 3’s 8th position), the next letter (o) at the next position (line 3’s 9th position), etc.
Middle of the screen Since the screen’s top line is 1 and the bottom line is 25, the middle line is 13. Since the screen’s leftmost position is 1 and the rightmost position is 80, the middle positions are 40 and 41.
To make the computer print the word “Hi” in the middle of the screen, tell the computer to print at the middle line (13) and the middle positions (40 and 41):
Bottom line Whenever the computer finishes running a program, the computer prints this message on the black screen’s bottom line:
Then the computer waits for you to press the ENTER key, which makes the screen turn blue and show the lines of your program.
That message, “Press any key to continue”, is the only message that the computer wants to print on the bottom line.
To force the computer to print anything else on the bottom line, do this: say LOCATE, mention line 25, put a semicolon at the end of the PRINT statement (to prevent the computer from pressing the ENTER key, which would disturb the rest of the screen), and say SLEEP (to make the computer pause awhile so you can admire the printing). For example, this program prints an “x” at the screen’s bottom right corner:
The image on the computer’s screen is called the picture. If you stare at the picture closely, you’ll see the picture’s composed of thousands of tiny dots. Each dot, which is a tiny rectangle, is called a picture’s element, or pic’s el, or pixel, or pel.
Coordinates The dot in the screen’s top left corner is called pixel (0,0). Just to the right of it is pixel (1,0). Then comes pixel (2,0), etc.
Underneath pixel (0,0) is pixel (0,1). Farther down is pixel (0,2).
Here are the positions of the pixels:
pixel (0,0) pixel (1,0) pixel (2,0) pixel (3,0) pixel (4,0) etc.
pixel (0,1) pixel (1,1) pixel (2,1) pixel (3,1) pixel (4,1) etc.
pixel (0,2) pixel (1,2) pixel (2,2) pixel (3,2) pixel (4,2) etc.
pixel (0,3) pixel (1,3) pixel (2,3) pixel (3,3) pixel (4,3) etc.
Each pixel’s name consists of two numbers in parentheses. The first number is the X coordinate; the second number is the Y coordinate. For example, if you’re talking about pixel (4,3), its X coordinate is 4; its Y coordinate is 3.
The X coordinate tells how far to the right the pixel is. The Y coordinate tells how far down. So pixel (4,3) is the pixel that’s 4 to the right and 3 down.
On the computer, the Y coordinate measures how far down, not up. If you’ve read old-fashioned math books in which the Y coordinate measured how far up, you’ll have to reverse your thinking!
Screen modes How many pixels are on the screen? The answer depends on which screen mode you choose.
Generally speaking, the best screen mode to choose is mode 12.
In that mode, the X coordinate goes from 0 to 639, and the Y coordinate goes from 0 to 479, so the pixel at the screen’s bottom right corner is pixel (639,479). Since you have 640 choices for the X coordinate (numbered from 0 to 639) and 480 choices for the Y coordinate (numbered from 0 to 479), that mode is called a 640-by-480 mode.
In that mode, the computer can display 16 colors simultaneously.
Mode 12 works just if your computer’s video card is modern (VGA). If your computer’s video card is inferior (CGA, EGA, MCGA, Hercules, or Olivetti), mode 12 doesn’t work, and you must use a more primitive mode instead. Here are your choices:
1 CGA (or EGA, MCGA, VGA) 320 by 200 4
2 CGA (or EGA, MCGA, VGA) 640 by 200 2
3 Hercules monochrome 720 by 348 2
4 Olivetti color 640 by 400 2
7 EGA (or VGA) 320 by 200 16
8 EGA (or VGA) 640 by 200 16
9 EGA (or VGA) 640 by 350 4 or 16
10 EGA (or VGA) 640 by 350 4
11 MCGA (or VGA) 640 by 480 2
12 VGA 640 by 480 16
13 MCGA (or VGA) 320 by 200 256
For example, here’s what that chart’s bottom row means:
To use mode 13, your video card must be MCGA (or VGA).
That mode lets you use 320 values of X (numbered from 0 to 319).
That mode lets you use 200 values of Y (numbered from 0 to 199).
That mode lets the screen display 256 colors simultaneously.
As you can see from that chart, mode 12 is generally the best mode, since it gives you lots of pixels (640 by 480) and lots of colors (16). Mode 13 gives you even more colors (256) but restricts you to fewer pixels (just 320 by 200). That restriction makes mode 13’s drawings look crude.
The following modes are just for bizarre situations.…
Mode 3 is just for a monochrome monitor attached to a Hercules monochrome card. This mode does not work with color monitors. In this mode, you have just 2 “colors”: black and white.
Mode 4 is just for a color video card made by Olivetti. That card is included in the AT&T 6300 computer.
Mode 9 is intended mainly for EGA monitors. It gives you 16 colors usually, but just 4 colors if the video card’s RAM is just 64K.
Mode 10 is intended mainly for monochrome monitors. It gives you 4 “colors”: black, bright white, dull white (cream), and blinking bright white.
Each pixel is a tiny rectangular dot. In modes 11 and 12, each pixel is a perfect square, whose width is the same as its height: on a typical 15-inch monitor, each pixel’s width and height is about a 60th of an inch. In other modes, each pixel is slightly taller than it is wide, so each pixel looks like a little tower.
There’s also a mode 0, which works on all computers and produces just text (no graphics).
Here’s which mode to choose:
CGA 1 (for many colors) or 2 (for many pixels)
EGA 9 (for color) or 10 (for monochrome)
MCGA 11 (for many pixels) or 13 (for many colors)
VGA 12 (for many pixels) or 13 (for many colors)
To give commands about pixels, begin by telling the computer which mode you want. For example, if you want screen mode 12, say:
When you give such a SCREEN command, the computer automatically clears the screen, so the entire screen becomes black. You do not have to say CLS.
PSET If your monitor is modern (VGA), this program makes the screen become black, then makes pixel (100,100) turn white:
If your monitor is less than VGA, choose a different screen mode than 12.
In that program, the PSET (100, 100) makes pixel (100,100) turn white. The word “PSET” means “pixel set”: “PSET (100, 100)” means “set the pixel (100,100) to white”.
LINE This program draws a white line from pixel (0,0) to pixel (100,100):
This program draws a white line from pixel (0,0) to pixel (100,100), then draws a white line from that pixel (100,100) to pixel (120,70):
CIRCLE This program draws a white circle whose center is pixel (100,100) and whose radius is 40 pixels:
In modes 11 and 12, each pixel is a perfect square, and the computer draws the circle easily. The circle’s radius is 40 pixels; the circle’s diameter (width) is 80 pixels.
If you switch to a different screen mode (such as SCREEN 2), each pixel is a tower instead of a square, so a “circle that’s 80 pixels wide and 80 pixels high” would be taller than wide and look like a tall oval. To make sure your “circle of radius 40” looks pretty, the computer cheats: the computer makes the circle’s width be 80 pixels but makes the circle’s height be fewer than 80 pixels, so that the circle’s height is the same number of inches as the width.
Avoid the bottom When your program finishes, the bottom of the screen automatically shows this advice:
To prevent that advice from covering up your drawing, position your drawing near the top of the screen (avoiding the bottom), or else make your program’s bottom line say “SLEEP” so the computer will pause and let you admire the drawing before the advice covers it.
PAINT After drawing a shape’s outline (by using dots, lines, and circles), you can fill in the shape’s middle, by telling the computer to PAINT the shape.
Here’s how to PAINT a shape that you’ve drawn (such as a circle or a house). Find a pixel that’s in the middle of the shape and that’s still black; then tell the computer to PAINT, starting at that pixel. For example, if pixel (100, 101) is inside the shape and still black, say:
Colors In modes 4, 7, 8, and 12, you can use these 16 colors:
0. black 8. light black (gray)
1. blue 9. light blue
2. green 10. light green
3. cyan (greenish blue) 11. light cyan (aqua)
4. red 12. light red (pink)
5. magenta (purplish red) 13. light magenta
6. brown 14. light brown (yellow)
7. cream (yellowish white) 15. light cream (pure white)
In mode 1, you must choose from these 4 colors instead:
1. cyan (greenish blue)
2. magenta (purplish red)
3. cream (yellowish white)
In modes 2, 3, and 11, you must choose from these 2 colors instead:
In mode 10, you have these 4 choices:
2. blinking white
Mode 9 usually gives you the 16 colors used in mode 12; but if you’re using mode 9 with an EGA card having just 64K of RAM, you’re restricted to the 4 colors used in mode 1.
Mode 13 gives you the 16 colors used in mode 12 — and many more colors, too! Here’s the spectrum:
0 through 7: black, blue, green, cyan, red, magenta, brown, cream
8 through 15: same colors as above, but lighter
16 through 31: shades of gray (from dark to light)
32 through 55: color blends (from blue to red to green to blue again)
56 through 79: same color blends, but lighter
80 through 103: same color blends, but even lighter
104 through 175: same as 32 through 103, but darker
176 through 247: same as 104 through 175, but even darker
248 through 255: black
Normally, the PLOT, LINE, CIRCLE, and PAINT commands draw in yellowish white (cream). If you prefer a different color, put the color’s number at the end of the command. Put a comma before the color’s number.
For example, if you want to draw a line from (0,0) to (100,0) using color #2, type this:
When you give a PAINT command, you must make its color be the same color as the outline you’re filling in.
Boxes If you type —
the computer draws a line from pixel (0,0) to (100,100) using color #2.
If you put the letter B at the end of the LINE command, like this —
the computer will draw a box instead of a line. One corner of the box will be at pixel (0,0); the opposite corner will be at (100,100); and the box will be drawn using color 2.
If you put BF at the end of the LINE command, like this —
the computer will draw a box and also fill it in, by painting its interior.
Return to text mode When you finish drawing pictures, you can return to text mode by saying:
If you were using mode 1, 7, or 13, say this instead:
The “WIDTH 80” makes sure the screen will display 80 characters per line instead of 40.
To produce sounds, you can say BEEP, SOUND, or PLAY. BEEP appeals to business executives; SOUND appeals to doctors and engineers; and PLAY appeals to musicians.
BEEP If your program says —
the computer will beep. The beep lasts for about a quarter of a second. Its frequency (“pitch”) is about 875 hertz. (The beep’s length and frequency might be slightly higher or lower, depending on which computer you have.)
You can say BEEP in the middle of your program. For example, you can tell the computer to BEEP if a person enters wrong data.
This program makes the computer act as a priest and perform a marriage ceremony:
Line 10 makes the computer ask the groom, “Do you take this woman to be your lawful wedded wife?” If the groom doesn’t say “I do”, the next line makes the computer beep, say “Try again!”, and repeat the question. Line 20 does the same thing to the bride. The bottom line congratulates the couple for answering correctly and getting married.
SOUND If your program says —
the computer will produce a sound. In that command, the 440 is the frequency (“pitch”), measured in hertz (cycles per second); so the sound will be a musical note whose pitch is 440 hertz. (That note happens to be “the A above middle C”).
If you replace the 440 by a lower number, the sound will have a lower pitch; if you replace the 440 by a higher number, the sound will have a higher pitch.
The lowest pitch that the computer can sing is 37. If you try to go below 37, the computer will gripe by saying:
The highest pitch that the computer can sing is 32767, but human ears aren’t good enough to hear a pitch that high.
When you were a baby, you could probably hear up to 20000. As you get older, your hearing gets worse, and you can’t hear such high notes. Today, the highest sound you can hear is probably somewhere around 14000. To find out, give yourself a hearing test, by running this program:
When you run that program, begin by inputting a low pitch (such as 37). Then input a higher number, then an even higher number, until you finally pick a number so high you can’t hear it. (When trying that test, put your ear close to the computer’s speaker, which is in the computer’s front left corner.) When you’ve picked a number too high for you to hear, try a slightly lower number. Keep trying different numbers, until you find the highest number you can hear.
Have a contest with your friends: find out which of your friends can hear best.
If you run that program every year, you’ll see that your hearing gets gradually worse. For example, when I was 36 years old, the highest pitch I could hear was about 14500, but I can’t hear that high anymore. How about you?
In those examples, the 18.2 makes the computer produce the sound for 1 second. If you want the sound to last longer — so that it lasts 2 seconds — replace the 18.2 by 18.2*2. For 10 seconds, say 18.2*10. (That’s because the computer’s metronome beats 18.2 times per second.)
PLAY If your program says —
the computer will play the note C, then D, then G sharp, then B flat, then A.
In the PLAY command, the computer ignores the spaces; so if you wish, you can write:
The computer can play in seven octaves, numbered from 0 to 6. Octave 0 consists of very bass notes; octave 6 consists of very high-pitched notes. In each octave, the lowest note is a C: the notes in an octave are C, C#, D, D#, E, F, F#, G, G#, A, A#, and B. “Middle C” is at the beginning of octave 2. Normally, the computer plays in octave 4. To make the computer switch to octave 3, type the letter “o” followed by a 3, like this:
After giving that command, anything else you PLAY will be in octave 3, until you change octaves again.
You can use the symbol “>” to mean “go up an octave”, and you can use the symbol “<” to mean “go down an octave”. For example, if you say —
the computer will play the note G, then go up an octave to play C and D in that higher octave, then go down to the original octave to play G again.
The lowest note the computer can play (which is the C in octave 0) is called “note 1”. The highest note the computer can play (which is the B in octave 6) is called “note 84”. To make the computer play note 84, you can type this:
To make the computer play its lowest note (1), then its middle note (42), then its highest note (84), type this:
Besides playing with pitches, you can play with rhythms (“lengths” of the notes). Normally each note is a “quarter note”. To make the computer switch to eighth notes (which are faster), type this:
Besides using L8 for eighth notes, you can use L16 for sixteenth notes (which are even faster), L32 for thirty-second notes (which are super-fast), and L64 for sixty-fourth notes (which are super-super-fast). For long notes, you can use L2 (which gives a half note) or L1 (which gives a whole note). You can use any length from L1 to L64. You can even use in-between lengths, such as L7 or L23 (though such rhythms are hard to stamp your foot to).
If you put a period after a note, the computer will multiply the note’s length by 1½.
For example, suppose you say:
The C will be an 8th note, E will be 1½ times as long as an 8th note, and D will be an 8th note. Musicians call that E a dotted eighth note.
If you put two periods after a note (like this: e..), the computer will multiply the note’s length by 13/4. Musicians say the note is double dotted.
If you put three periods after a note (like this: e...), the computer will multiply the note’s length by 17/8.
To make the computer pause (“rest”) for an eighth note, put a p8 into the music string.
Normally, the computer plays 120 quarter notes per minute; but you can change that tempo. To switch to 150 quarter notes per minute, say:
You can switch to any tempo from 32 to 255. The 32 is very slow; 255 is very fast. In musical terms, 40=larghissimo, 50=largo, 63=larghetto, 65=grave, 68=lento, 71=adagio, 76=andantino, 92=andante, 114=moderato, 120=allegretto, 144=allegro, 168=vivace, 188=presto, and 208=prestissimo.
You can combine all those musical commands into a single PLAY statement. For example, to set the tempo to 150, the octave to 3, the length to 8 (which means an eighth note), and then play C and D, and then change the length to 4 and play E, type this:
Suppose you want to add $12.47 to $1.03. The correct answer is $13.50. This almost works:
It makes the computer print:
But instead of 13.5, we should try to make the computer print 13.50.
This command forces the computer to print 13.50:
The “##.##” is called the picture or image or format: it says to print two characters, then a decimal point, then two digits. The computer will print:
This command puts that answer into a sentence:
The computer will print:
Rounding This program makes the computer divide 300 by 7 but round the answer to two decimal places:
When the computer divides 300 by 7, it gets 42.85714, but the format rounds the answer to 42.86. The computer will print:
Multiple numbers Every format (such as “###.##”) is a string. You can replace the format by a string variable:
The computer will print:
When the computer prints that column of numbers, notice that the computer prints the decimal points underneath each other so that they line up. So to make decimal points line up, say PRINT USING instead of just PRINT.
To print those numbers across instead of down, say this:
It makes the computer print 247.91, then 823.00, etc., like this:
Since the computer prints those numbers so close together, they’re hard to read. To make the computer insert extra space between the numbers, widen the format by putting a fourth “#” before the decimal point:
Then the computer will print:
If you say —
the computer will print:
Oversized numbers Suppose you say:
The computer tries to print 16238.7 by using the format “###.##”. But since that format allows just three digits before the decimal point, the format isn’t large enough to fit 16238.7. So the computer must disobey the format. But the computer also prints a percent sign, which means, “Warning! I am disobeying you!” Altogether, the computer prints:
Final semicolon At the end of the PRINT USING statement, you can put a semicolon:
Line 2 makes the computer print 13.50. The semicolon at the end of line 2 makes the computer print “credit” on the same line, like this:
Advanced formats Suppose you’re running a high-risk business. On Monday, your business runs badly: you lose $27,931.60, so your “profit” is minus $27,931.60. On Tuesday, your business does slightly better than break-even: your net profit for the day is $8.95.
Let’s make the computer print the word “profit”, then the amount of your profit (such as -$27,931.60 or $8.95), then the word “ha” (because you’re cynical about how your business is going).
You can do that printing in several ways. Let’s explore them.…
If you say —
the computer will print:
If you change the format to “profit###,###.##ha”, the computer will insert a comma if the number is large:
If you change the format to “profit+#####.##ha”, the computer will print a plus sign in front of any positive number:
To print a negative number, the computer normally prints a minus sign before the number. That’s called a leading minus. You can make the computer put the minus sign after the number instead; that’s called a trailing minus. For example, if you change the format to “profit######.##-ha”, the computer will print a minus sign AFTER a negative number (and no minus after a positive number), like this:
Normally, a format begins with ##. If you begin with $$ instead (like this: “profit$$#####.##ha”), the computer will print a dollar sign before the digits:
If you begin with ** (like this: “profit**#####.##ha”), the computer will print asterisks before the number:
If you begin with **$ (like this: “profit**$#####.##ha”), the computer will print asterisks and a dollar sign:
When you’re printing a paycheck, use the asterisks to prevent the employee from enlarging his salary. Since the asterisks protect the check from being altered, they’re called check protection.
You can combine several techniques into a single format. For example, you can combine the comma, the trailing minus, and the **$ (like this: “profit**$##,###.##-ha”), so that the computer will print:
If you change the format to “profit##.#####^^^^ha”, the computer will print numbers by using E notation:
You can do fancy calculations — easily!
Try typing this program:
To type the symbol ^, do this: while holding down the SHIFT key, tap this key:
│ ^ │
│ 6 │
That symbol (^) is called a caret.
In that program, the
“4 ^ 3” makes the computer use the number 4, three times. The
computer will multiply together those three 4’s, like this: 4 times 4 times 4.
In the expression “4 ^ 3”, the 4 is called the base; the 3 is called the exponent.
Here’s another example:
The “10 ^ 6” makes the computer use the number 10, six
times. The computer will multiply together those six 10’s (like this:
Here’s another example:
The “3 ^ 2” makes the computer use the number 3, two
times. The computer will multiply together those two 3’s (like this:
Order of operations The symbols +, -, *, /, and ^ are all called operations.
To solve a problem, the computer uses the three-step process taught in algebra and the “new math”. For example, suppose you say:
The computer will not begin by subtracting 3 from 70; instead, it will use the three-step process:
The problem is 70 - 3 ^ 2 + 8 / 2 * 3
Step 1: get rid of ^. Now the problem is 70 - 9 + 8 / 2 * 3
Step 2: get rid of * and /. Now the problem is 70 - 9 + 12
Step 3: get rid of + and -. The answer is 73
In each step, it looks from left to right. For example, in step 2, it sees / and gets rid of it before it sees *.
Speed Though exponents are fun, the computer handles them slowly. For example, the computer handles 3 ^ 2 slower than 3 * 3. So for fast calculations, say 3 * 3 instead of 3 ^ 2.
Square roots What positive number, when multiplied by itself, gives 9? The answer is 3, because 3 times itself is 9.
3 squared is 9. 3 is called the square root of 9.
To make the computer deduce the square root of 9, type this:
The computer will print 3.
When you tell the computer to PRINT SQR(9), make sure you put the parentheses around the 9.
The symbol SQR is called a function. The number in parentheses (9) is called the function’s input (or argument or parameter). The answer, which is 3, is called the function’s output (or value).
SQR(9) gives the same answer as 9 ^ .5. The computer handles SQR(9) faster than 9 ^ .5.
Cube roots What number, when multiplied by itself and then multiplied by itself again, gives 64? The answer is 4, because 4 times 4 times 4 is 64. The answer (4) is called the cube root of 64.
Here’s how to make the computer find the cube root of 64:
The computer will print 4.
EXP The letter “e” stands for a special number, which is approximately 2.718281828459045. You can memorize that number easily, if you pair the digits:
2.7 18 28 18 28 45 90 45
That weird number is important in calculus, radioactivity, biological growth, and other areas of science. It’s calculated by this formula:
EXP(x) means ex. For example, EXP(3) means e3, which is e * e * e, which is:
2.718281828459045 * 2.718281828459045 * 2.718281828459045
EXP(4) means e4, which is e * e * e * e. EXP(3.1) means e3.1, which is more than e3 but less than e4.
Here’s a practical application. Suppose you put $800 in a savings account, and the bank promises to give you 5% annual interest “compounded continuously”. How much money will you have at the end of the year? The answer is 800 * EXP(.05).
Logarithms Here are some powers of 2:
To compute the logarithm-base-2 of a number, find the number in the right-hand column; the answer is in the left column. For example, the logarithm-base-2 of 32 is 5. The logarithm-base-2 of 15 is slightly less than 4.
The logarithm-base-2 of 64 is 6. That fact is written:
log2 64 is 6
It’s also written:
To make the computer find the logarithm-base-2 of 64, say:
The computer will print 6.
Here are some powers of 10:
The logarithm-base-10 of 100000 is 5. The logarithm-base-10 of 1001 is slightly more than 3.
The logarithm-base-10 of 10000 is 4. That fact is written:
log10 10000 is 4
It’s also written:
To make the computer do that calculation, say:
The computer will print 4.
The logarithm-base-10 is called the common logarithm. That’s the kind of logarithm used in high school and chemistry. So if a chemistry book says to find the logarithm of 10000, the book means the logarithm-base-10 of 10000, which is LOG(10000) / LOG(10).
What happens if you forget the base, and say just LOG(10000) instead of LOG(10000) / LOG(10)? If you say just LOG(10000), the computer will find the natural logarithm of 10000, which is loge 10000 (where e is 2.718281828459045), which isn’t what your chemistry book wants.
The computer’s notation resembles that of arithmetic and algebra, but beware of these contrasts.…
Multiplication To make the computer multiply, you must type an asterisk:
2n 2 * n
5(n+m) 5 * (n + m)
nm n * m
Exponents Put an exponent in parentheses, if it contains an operation:
xn+2 x ^ (n + 2)
x3n x ^ (3 * n)
52/3 5 ^ (2 / 3)
Fractions Put a fraction’s numerator in parentheses, if it contains addition or subtraction:
Put a denominator in parentheses, if it contains addition, subtraction, multiplication, or division:
Mixed numbers A mixed number is a number that contains a fraction. For example, 9½ is a mixed number. When you write a mixed number, put a plus sign before its fraction:
9½ 9 + 1 / 2
If you’re using the mixed number in a further calculation, put the mixed number in parentheses:
7 - 2¼ 7 - (2 + 1 / 4)
The computer has a built-in clock/calendar.
Setting the date & time To set the date to January 24, 1996, you can run this program —
or give this DOS command (after leaving QBASIC):
To set the time to 7 seconds after 1:45PM, you can run this program —
or give this DOS command:
Printing the date & time After you’ve set the date & time, the computer’s clock/calendar will try to keep track of the date & time for you. Then whenever you want to find out the current date & time, run this program:
If you say —
the computer will tell you how many seconds have elapsed since midnight.
This program makes the computer print the DATE$, TIME$, and TIMER across the top of your screen:
The top of your screen will look like this:
The following program makes the computer look at the clock (and tell you the TIME$), then look at the clock again and tell you the new TIME$, then look at the clock again and tell you the new TIME$, etc.:
For example, if the time starts at 18:07:04 (and eventually changes to 18:07:05 and then 18:07:06), the screen will look like this:
The program will continue telling you the time until you abort the program.
Clock battery The typical computer contains a little battery, called a clock battery. While the computer is unplugged from the wall (or the computer’s main power switch is turned off), the clock battery continually sneaks enough electricity to the clock/calendar chips to keep them running, so they keep updating the date & time.
After several months or years, the battery will run out, and the chips will forget what the date & time are. Replace the battery, then reset the date & time.
Test your computer’s speed How fast can your computer print the numbers from 1 to 1000? (The answer depends on the speed of your computer’s CPU chip, video card, and other components.) This program makes the computer print all the numbers from 1 to 1000, then brag about how fast it printed them:
Line 2 makes the computer look at the clock’s TIMER and call that time the starting.time. The FOR..NEXT loop makes the computer print all the numbers from 1 to 1000. The line underneath (elapsed.time = TIMER - starting.time) makes the computer look at the clock’s TIMER again, notice how different it is from the starting.time, and call the difference the elapsed.time. The bottom line makes the computer print how much time elapsed.
For example, my 386SX-16 computer usually prints:
My 486DX2-66 computer is faster and usually prints:
How fast is your computer?
Try running the program several times. Sometimes you might get slightly different answers, since the TIMER isn’t very accurate.
For a different speed test, make the computer count up to 10000 instead of 1000. That makes the computer take about 10 times as long.
Try putting a semicolon at the end of the PRINT i line. That lets the computer print faster, since the computer no longer has to press the ENTER key after each number.
Try omitting the PRINT i line altogether, so the computer can just think about the numbers without bothering to print them. That lets the computer finish the program much faster. It tests how fast the CPU can think, rather than how fast the video circuitry can display printed answers.
Midnight problem At midnight, TIMER is 0. At 1 second after midnight, TIMER is 1. At 2 seconds after midnight, TIMER is 2.
Since there are 60 seconds in a minute, 60 minutes in an hour, and 24 hours in a day, there are 86400 seconds in a day. At 1 second before midnight, TIMER is “86400 minus 1”, which is 86399; but when midnight strikes, TIMER becomes 0 again.
To compute elapsed.time, you normally take the current time (TIMER) and subtract the starting.time:
That formula works if TIMER is a bigger number than starting.time.
But suppose a program starts running just before midnight and ends just after midnight. Since the starting.time is nearly 86400 and the TIMER (current time) is just slightly bigger than 0, the formula “TIMER - starting.time” gives a negative number, which is not the correct calculation for elapsed.time, since elapsed.time cannot be negative!
Here’s how to correct the definition of elapsed.time. Instead of giving this one-line definition —
give this two-line definition:
So the program to test your program’s speed should be:
If you omit the shaded line, the program will work usually, but not at midnight. The typical novice programmer forgets to insert that line, thinks the program works fine without it, and gets surprised years later by a midnight phone call from an upset user wondering why the computer reports that the elapsed time is a negative number.
LOOP UNTIL This program prints the letter “x” repeatedly, for .3 seconds:
Line 2 makes the computer look at the clock’s TIMER and call that time the starting.time. The PRINT line makes the computer print an “x”. The other indented lines compute the elapsed.time. The bottom line says: do the loop again and again, until the elapsed time is at least .3.
So that program makes the computer print x’s for about .3 seconds.
Experiment! Run that program, and see how many x’s your computer can print in .3 seconds.
If you run that program several times, you’ll get slightly different answers, since the TIMER isn’t very accurate.
In the bottom line, try changing the .3 to a different number, to see how many x’s your computer can print in a different amount of time. Even if you replace the .3 by a tiny number, the computer will print at least one x, since the computer does the PRINT line before encountering the definition of elapsed.time and the LOOP condition.
Pause loop This program makes the computer print “I’m going to take a nap”, then pause for 5 seconds, then print “Now I woke up”:
This fancier program accomplishes the same goal:
Line 2 makes the computer print “I’m going to take a nap”. The next line (starting.time = TIMER) makes the computer look at the clock’s TIMER and call that time the starting.time. The DO loop makes the computer look at the time repeatedly, until the elapsed.time is at least 5 seconds. After those 5 seconds of at of staring at the clock, the computer finally does the bottom line, which makes the computer print “Now I woke up”. Since the loop’s only purpose is to make the computer pause for 5 seconds, the loop is called a pause loop.
The fancy program (which says LOOP UNTIL) has two advantages over the simple program (which says SLEEP):
In the SLEEP program, if the human presses a key while the computer is SLEEPing, the computer wakes up immediately. In the LOOP UNTIL program, the computer ignores the human until 5 seconds have passed, so the LOOP UNTIL program ensures that the computer really DOES pause for 5 seconds. The only way the human can interrupt the computer’s pause loop is to abort the program (by pressing Ctrl with PAUSE/BREAK).
In the LOOP UNTIL program, you can make the computer loop for 5.1 seconds instead of 5 seconds, by changing the 5 to 5.1. You can’t create a SLEEP program that sleeps for 5.1 seconds, since the SLEEP command prohibits decimals: if you try to say SLEEP 5.1, the computer will do SLEEP 5 instead.
Here’s another way to make the computer take a nap:
The FOR line makes the computer count up to 50000. Since the computer doesn’t print anything while counting, the FOR line acts as a pause. How long will the pause last?
Sometimes the computer prints too much info: you wish the computer would print less, to save yourself the agony of reading excess info irrelevant to your needs. Whenever the computer prints too much info about a numerical answer, use ABS, FIX, INT, CINT, or SGN.
ABS removes any minus sign. For example, the ABS of -3.89 is 3.89. So if you say PRINT ABS(-3.89), the computer will print just 3.89.
FIX removes any digits after the decimal point. For example, the FIX of 3.89 is 3. So if you say PRINT FIX(3.89), the computer will print just 3. The FIX of -3.89 is -3.
CINT rounds to the NEAREST integer. For example, the CINT of 3.89 is 4; the CINT of -3.89 is -4.
INT rounds the number DOWN to an integer that’s LOWER. For example, the INT of 3.89 is 3 (because 3 is an integer that’s lower than 3.89); the INT of -3.89 is -4 (because -4 is lower than -3.89).
SGN removes ALL the digits and replaces them with a 1 — unless the number is 0. For example, the SGN of 3.89 is 1. The SGN of -3.89 is -1. The SGN of 0 is just 0.
ABS, FIX, CINT, INT, and SGN are all called stripping functions or strippers or diet functions or diet pills, because they strip away the number’s excess fat and reveal just the fundamentals that interest you.
Here are more details about those five functions.…
ABS To find the absolute value of a negative number, just omit the number’s minus sign. For example, the absolute value of -7 is 7.
The absolute value of a positive number is the number itself. For example, the absolute value of 7 is 7. The absolute value of 0 is 0.
To make the computer find the absolute value of -7, type this:
The computer will print:
Like SQR, ABS is a function: you must put parentheses after the ABS.
Since ABS omits the minus sign, ABS turns negative numbers into positive numbers. Use ABS whenever you insist that an answer be positive.
For example, ABS helps solve math & physics problems about “distance”, since the “distance” between two points is always a positive number and cannot be negative.
This program computes the distance between two numbers:
When you run that program, suppose you say that the first number is 4 and the second number is 7. Since x is 4, and y is 7, the distance between those two numbers is ABS(4 - 7), which is ABS(-3), which is 3.
If you reverse those two numbers, so that x is 7 and y is 4, the distance between them is ABS(7 - 4), which is ABS(3), which is still 3.
FIX An integer is a number that has no decimal point. For example, these are integers: 17, 238, 0, and -956.
If a number contains a decimal point, the simplest way to turn the number into an integer is to delete all the digits after the decimal point. That’s called the FIX of the number.
For example, the FIX of 3.89 is 3. So if you say PRINT FIX (3.89), the computer will print just 3.
The FIX of -3.89 is -3. The FIX of 7 is 7. The FIX of 0 is 0.
CINT A more sophisticated way to turn a number into an integer is to round the number to the nearest integer. That’s called CINT (which means “Convert to INTeger”). For example, the CINT of 3.9 is 4 (because 3.9 is closer to 4 than to 3).
Like FIX, CINT deletes all the digits after the decimal point; but if the digit just after the decimal point is 5, 6, 7, 8, or 9, CINT “rounds up” by adding 1 to the digit before the decimal point.
Here are more examples:
CINT(3.9) is 4 CINT(-3.9) is -4
CINT(3.1) is 3 CINT(-3.1) is -3
CINT(3.5) is 4 CINT(-3.5) is -4
The highest number CINT can produce is 32767. If you try to go higher than 32767 or lower than -32768, the computer will gripe by saying “Overflow”.
To explore the mysteries of rounding, run this program:
In that program, the INPUT line asks you to type a number x. The bottom line prints your number, but rounded to the nearest integer. For example, if you type 3.9, the bottom line prints 4.
INT Like FIX and CINT, INT turns a number into an integer. Though INT is slightly harder to understand than FIX and CINT, INT is more useful!
INT rounds a number down to an integer that’s lower. For example:
The INT of 3.9 is 3 (because 3 is an integer that’s lower than 3.9).
The INT of -3.9 is -4 (because a temperature of -4 is lower and colder than a temperature of -3.9).
The INT of 7 is simply 7.
To explore further the mysteries of rounding, run this program:
In that program, the INPUT line asks you to type a number x.
The next line prints your number rounded down. For example, if you input 3.9, the computer prints 3.
The next line, PRINT -INT(-x), prints your number rounded up. For example if you input 3.9, the computer prints 4.
The bottom line prints your number rounded to the nearest integer. For example, if you input 3.9, the computer will print 4.
Here’s the rule: if x is a number, INT(x) rounds x down; -INT(-x) rounds x up; INT(x + .5) rounds x to the nearest integer.
Here’s why INT is usually better than CINT and FIX:
In the rest of this book, I’ll emphasize INT.
Rounding down and rounding up are useful in the supermarket:
Suppose some items are marked “30¢ each”, and you have just two dollars. How many can you buy? Two dollars divided by 30¢ is 6.66667; rounding down to an integer, you can buy 6.
Suppose some items are marked “3 for a dollar”, and you want to buy just one of them. How much will the supermarket charge you? One dollar divided by 3 is 33.3333¢; rounding up to an integer, you will be charged 34¢.
By using INT, you can do fancier kinds of rounding:
to round x to the nearest thousand, ask for INT(x / 1000 + .5) * 1000
to round x to the nearest thousandth, ask for INT(x / .001 + .5) * .001
This program rounds a number, so that it will have just a few digits after the decimal point:
Here’s a sample run:
SGN If a number is negative, its sign is -1. For example, the sign of -546 is -1.
If a number is positive, its sign is +1. For example the sign of 8231 is +1.
The sign of 0 is 0.
The computer’s abbreviation for “sign” is “SGN”. So if you say —
the computer will print the sign of -546; it will print -1.
If you say —
the computer will print the sign of 8231; it will print 1.
If you say —
the computer will print the sign of 0; it will print 0.
SGN is the opposite of ABS. Let’s see what both functions do to -7.2. ABS removes the minus sign, but leaves the digits:
ABS(-7.2) is 7.2
SGN removes the digits, but leaves the minus sign:
SGN(-7.2) is -1
The Latin word for sign is signum. Most mathematicians prefer to talk in Latin — they say “signum” instead of “sign” — because the English word “sign” sounds too much like the trigonometry word “sine”. So mathematicians call SGN the signum function.
Usually, the computer is predictable: it does exactly what you say. But sometimes, you want the computer to be unpredictable.
For example, if you’re going to play a game of cards with the computer and tell the computer to deal, you want the cards dealt to be unpredictable. If the cards were predictable — if you could figure out exactly which cards you and the computer would be dealt — the game would be boring.
In many other games too, you want the computer to be unpredictable, to “surprise” you. Without an element of surprise, the game would be boring.
Being unpredictable increases the pleasure you derive from games — and from art. To make the computer act artistic, and create a new original masterpiece that’s a “work of art”, you need a way to make the computer get a “flash of inspiration”. Flashes of inspiration aren’t predictable: they’re surprises.
Here’s how to make the computer act unpredictably.…
RND is a RaNDom decimal, bigger than 0 and less than 1. For example, it might be .6273649 or .9241587 or .2632801. Every time your program mentions RND, the computer concocts another decimal:
The computer prints:
The first time your program mentions RND, the computer chooses its favorite decimal, which is .7055475. Each succeeding time your program mentions RND, the computer uses the previous decimal to concoct a new one. It uses .7055475 to concoct .533424, which it uses to concoct .5795186. The process by which the computer concocts each new decimal from the previous one is weird enough so we humans cannot detect any pattern.
This program prints lots of decimals — and pauses a second after each decimal, so you have a chance to read it:
About half the decimals will be less than .5, and about half will be more than .5.
Most of the decimals will be less than .9. In fact, about 90% will be.
About 36% of the decimals will be less than .36; 59% will be less than .59; 99% will be less than .99; 2% will be less than .02; a quarter of them will be less than .25; etc. You might see some decimal twice, though most of the decimals will be different from each other. When you get tired of running that program and seeing decimals, abort the program (by pressing Ctrl with PAUSE/BREAK).
If you run that program again, you’ll get exactly the same list of decimals again, in the same order.
RANDOMIZE TIMER If you’d rather see a different list of decimals, say RANDOMIZE TIMER at the beginning of the program:
When the computer sees RANDOMIZE TIMER, the computer looks at the clock and manipulates the time’s digits to produce the first value of RND.
So the first value of RND will be a number that depends on the time of day, instead of the usual .7055475. Since the first value of RND will be different than usual, so will the second, and so will the rest of the list.
Every time you run the program, the clock will be different, so the first value of RND will be different, so the whole list will be different — unless you run the program at exactly the same time the next day, when the clock is the same. But since the clock is accurate to a tiny fraction of a second, the chance of hitting the same time is extremely unlikely.
Love or hate? Who loves ya, baby? This program tries to answer that question:
The RANDOMIZE TIMER line makes the value of RND depend on the clock. The INPUT line makes the computer wait for the human to type a name. Suppose he types Suzy. Then name$ is “Suzy”. The IF line says there’s a 67% chance that the computer will print “Suzy loves you, too”, but there’s a 33% chance the computer will instead print “Suzy hates your guts”. The words DO and LOOP make the computer do the routine again and again, until the human aborts the program. The run might look like this:
Coin flipping This program makes the computer flip a coin:
The IF line says there’s a 50% chance that the computer will print “heads”; if the computer does not print “heads”, it will print “tails”.
Until you run the program, you won’t know which way the coin will flip; the choice is random. Each time you run the program, the computer will flip the coin again; each time, the outcome is unpredictable.
Here’s how to let the human bet on whether the computer will say “heads” or “tails”:
The line numbered 10 makes the computer ask:
The next line makes sure the human says “heads” or “tails”: if the human’s answer isn’t “heads” and isn’t “tails”, the computer gripes. The bottom three lines make the computer flip a coin and determine whether the human won or lost the bet.
Here’s a sample run:
Here’s how to let the human use money when betting:
Line 3 (bankroll = 100) gives the human a $100 bankroll, so the human starts with $100. The next line makes the computer say:
The line numbered 5 makes the computer ask:
The number that the human inputs (the number of dollars that the human bets) is called the human’s stake. The next three lines (which say “IF stake”) make sure the stake is reasonable.
The line numbered 10 gets the human to bet on heads or tails. The next few lines flip the coin, determine whether the human won or lost the bet, and then send the computer back to line 4 for another round (if the human isn’t broke yet). The bottom three lines say good-bye to the human.
Here’s a sample run:
To make the output prettier, replace line 4 by this group of lines:
Now the run looks like this:
Random integers If you want a random integer from 1 to 100, ask for 1 + INT(RND * 100). Here’s why:
RND is a decimal, bigger than 0 and less than 1.
So RND * 10 is a decimal, bigger than 0 and less than 10.
So INT(RND * 10) is an integer, at least 0 and no more than 9.
So 1 + INT(RND * 10) is an integer, at least 1 and no more than 10.
Guessing game This program plays a guessing game:
Line 3 makes the computer say:
The next line makes the computer think of a random number from 1 to 10; the computer’s number is called “computer.number”. The INPUT line asks the human to guess the number.
If the guess is less than the computer’s number, the first IF line makes the computer say “Your guess is too low” and then GOTO 10, which lets the human guess again. If the guess is greater than the computer’s number, the bottom IF line makes the computer say “Your guess is too high” and then GOTO 10.
When the human guesses correctly, the computer arrives at the bottom line, which prints:
Here’s a sample run:
Dice This program makes the computer roll a pair of dice:
Line 3 makes the computer say:
Each of the dice has 6 sides. The next line, a = 1 + INT(RND * 6), rolls one of the dice, by picking a number from 1 to 6. The line saying “b = 1 + INT(RND * 6)” rolls the other. The bottom line prints the total.
Here’s a sample run:
Here’s another run:
Daily horoscope This program predicts what will happen to you today:
The computer will say —
or some in-between comment. That’s because the SELECT CASE line makes the computer pick a random integer from 1 to 5.
For inspiration, run that program when you get up in the morning. Then notice whether your day turns out the way the computer predicts!
Alt key Here’s how to type the symbol ñ, whose code number is 164. Hold down the Alt key; and while you keep holding down the Alt key, type 164 by using the numeric keypad (the number keys on the far right side of the keyboard). When you finish typing 164, lift your finger from the Alt key, and you’ll see ñ on your screen!
The Alt key works reliably for most numbers in that chart but not for numbers 1-27 and 127.
You can use the Alt key in your program. For example, try typing this program:
While typing that program, make the symbol ¤ by typing 164 on the numeric keypad while holding down the Alt key. When you run that program, the computer will print:
CHR$ Here’s another way to type the symbol ñ:
When you run that program, the computer will print the CHaRacter whose code number is 164. The computer will print:
This program makes the computer print “In Spanish, tomorrow is mañana”:
That PRINT line makes the computer print “In Spanish, tomorrow is ma”, then print character 164 (which is ñ), then print “ana”.
Since character 34 is a quotation mark, this program prints a quotation mark:
Suppose you want the computer to print:
To make the computer print the quotation marks around “Hamlet”, use CHR$(34), like this:
CHR$ works reliably for all numbers in that chart. This program prints, on your screen, all the symbols in the chart:
That chart shows most code numbers from 1 to 254 but skips the following mysterious code numbers: 7, 9-13, and 28-32. Here’s what those mysterious code numbers do.…
In a PRINT statement, CHR$(7) makes the computer beep. Saying —
has the same effect as saying:
If you say —
the computer will print “hot”, then beep, then turn the “hot” into “hotdog”.
CHR$(9) makes the computer press the TAB key, so your writing is indented. For example, if you say —
the computer will print “hot”, then indent by pressing the TAB key, then print “dog”, so you see this:
CHR$(31) makes the computer move the cursor (the blinking underline) down to the line below. For example, if you say —
the computer will print “hot”, then move down, then print “dog” on the line below, so you see this:
You can move the cursor in all four directions:
CHR$(28) moves the cursor toward the right
CHR$(29) moves the cursor toward the left
CHR$(30) moves the cursor up
CHR$(31) moves the cursor down
CHR$(11) moves the cursor all the way to the screen’s top left corner, which is called the home position.
CHR$(32) is a blank space. It’s the same as “ ”.
CHR$(12) erases the entire screen. Saying —
has the same effect as saying:
CHR$(10) and CHR$(13) each make the computer press the ENTER key.
Printing on paper When printing onto paper, make your program’s bottom line say:
That makes the printer eject the paper.
Codes 33-126 print on paper okay. As on the screen, code 32 prints a blank space. Other codes print okay on some printers but wrong on other printers. Experiment, and see which codes your printer can print correctly.
If you want to print codes 128-254 on a typical laser printer (such as a Hewlett-Packard Laserjet 2), put this line at the top of your program (just under the CLS):
Type that line carefully. In the quotation marks, make sure you type just a single parenthesis, then the number 10, then a capital U.
A typical dot-matrix printer (such as an Epson LQ-570) normally prints 10 characters per inch. To make the characters thinner, so you get 17 characters per inch, say:
To cancel that 17-characters-per-inch command, say:
To make the characters wider, so you get 5 characters per inch, say:
To cancel that command, say:
ASC The code numbers from 32 to 126 are for characters that you can type on the keyboard easily. Established by a national committee, those code numbers are called the American Standard Code for Information Interchange, which is abbreviated ASCII, which is pronounced “ass key”.
Programmers say, “the ASCII code number for A is 65”. If you say —
the computer will print the ASCII code number for “A”. It will print:
If you say PRINT ASC(“B”), the computer will print 66. If you say PRINT ASC(“b”), the computer will print 97.
If you say PRINT ASC(“ñ”), the computer will print 164 (which is the code number for ñ), even though ñ isn’t an ASCII character.
Let’s analyze the word “smart”.
Length Since “smart” has 5 characters in it, the length of “smart” is 5. If you say —
the computer will print the LENgth of “smart”; it will print:
Left, right, middle The left two characters of “smart” are “sm”. If you say —
the computer will print:
Try this program:
Line 2 says a$ is “smart”. The bottom line says to print the left 2 characters of a$, which are “sm”. The computer will print:
If a$ is “smart”, here are the consequences.…
LEN(a$) is the LENgth of a$. It is 5.
LEFT$(a$, 2) is the LEFT 2 characters of a$. It is “sm”.
RIGHT$(a$, 2) is the RIGHT 2 characters of a$. It is “rt”.
MID$(a$, 2) begins in the MIDdle of a$, at the 2nd character. It’s “mart”.
MID$(a$, 2, 3) begins at 2nd character and includes 3 characters. It’s “mar”.
You can change the middle of a string, like this:
Line 2 says a$ is “bunkers”. The MID$ line changes the middle of a$ to “owl”; the change begins at the 2nd character of a$. The bottom line prints:
Here’s a variation:
Line 2 says a$ is “bunkers”. The MID$ line says to change the middle of a$, beginning at the 2nd character of a$. But “ad agency” is too long to become part of “bunkers”. The computer uses as much of “ad agency” as will fit in “bunkers”. The computer will print:
Line 2 says a$ is “bunkers”. The MID$ line says to change the middle of a$, beginning at the 2nd character of a$. But the “,1” makes the computer use just 1 letter from “owl”. The bottom line prints:
Capitals Capital letters (such as X, Y, and Z) are called upper-case letters. Small letters (such as x, y, and z) are called lower-case letters.
If you say —
the computer will print an upper-case (capitalized) version of “We love America”), like this:
If you say —
the computer will print a lower-case version of “We love America”, like this:
Unfortunately, the computer doesn’t know how to capitalize an accented letter (such as ñ). For example, suppose you say:
Since the computer doesn’t know how to capitalize the ¤, the computer prints:
If you say PRINT LCASE$(“MAÑANA”), the computer doesn’t know how to uncapitalize Ñ, so the computer prints:
This program measures geographical emotions:
Line 2 asks:
Line 3 checks whether the person’s answer is “Africa”. If the person’s answer is “Africa”, the computer prints “Yes, it’s the dark continent!”; otherwise, the computer prints “I disagree!”
But instead of typing “Africa”, what if the person types “africa” or “AFRICA”? We still ought to make the computer print “Yes, it’s the dark continent!” Here’s how:
The new version of the IF statement says: if the person’s answer, after being capitalized, becomes “AFRICA”, then print “Yes, it’s the dark continent!” So the computer will print “Yes, it’s the dark continent!” even if the person types “Africa” or “africa” or “AFRICA” or “AfRiCa”.
Suppose you ask the person a yes/no question. If the person means “yes”, the person might type “yes” or “Yes” or “YES” or “YES!” or just “y” or just “Y”. So instead of saying —
That tests whether the first letter of the person’s answer, after being capitalized, is “Y”.
Trim Some folks accidentally press the SPACE bar at the beginning or end of a string. For example, instead of typing “Sue”, the person might type “ Sue” or “Sue “.
You want to get rid of those accidental spaces. Getting rid of them is called trimming the string.
The function LTRIM$ will left-trim the string: it will delete any spaces at the string’s beginning (left edge). For example, if a$ is “ Sue Smith”, LTRIM$(a$) is “Sue Smith”.
RTRIM$ will right-trim the string: it will delete any spaces at the string’s end (right edge). If a$ is “Sue Smith “, RTRIM$(a$) is “Sue Smith”.
To trim both edges of a$ and make the trimmed result be the new a$, say this:
Spaces at the string’s beginning (which are deleted by LTRIM$) are called leading spaces. Spaces at the string’s end (which are deleted by RTRIM$) are called trailing spaces.
Adding strings You can add strings together, to form a longer string:
Line 2 says a$ is “father”. The bottom line makes the computer print:
Searching in a string You can make the computer search in a string to find another string. To make the computer search IN the STRing “needed” to find “ed”, say:
Since “ed” begins at the third character of “needed”, the computer will print:
If you say —
the computer will search in the string “needed” for “ey”. Since “ey” is not in “needed”, the computer will print:
If you say —
the computer will hunt in the string “needed” for “ed”; but the hunt will begin at the 4th character of “needed”. The computer finds the “ed” that begins at the 5th character of “needed”. The computer will print:
String-number conversion This program converts a string to a number:
Line 2 says a$ is the string “52.6”. The next line says b is the numeric VALue of a$, so b is the number 52.6. The bottom line prints:
VAL converts a string to a number. The opposite of VAL is STR$, which converts a number to a string. For example, STR$(-7.2) is the string “-7.2”. STR$(81.4) is the string “ 81.4”, in which the 8 is preceded by a space instead of a minus sign.
Repeating characters Suppose you love the letter b (because it stands for big, bold, and beautiful) and want to print “bbbbbbbbbbbbbbbbbbbb”. Here’s a short-cut:
That tells the computer to print a string of 20 b’s.
Here’s a different way to accomplish the same goal:
That tells the computer to print, 20 times, the character whose ASCII code number is 98.
STRING$ can make the computer repeat a single character, but not a whole word. So if you say STRING$(20, “blow”), the computer will not repeat the word “blow”; instead, the computer will repeat just the first character of “blow” (which is “b”).
Let’s make the computer draw a dashed line containing 50 dashes, like this:
Here’s how: just say PRINT STRING$(50, “-”).
Let’s make the computer print this triangle:
To do that, we want the computer to print 1 asterisk on the first line, then 2 asterisks on the next line, then 3 asterisks on the next line, and so on, until it finally prints 20 asterisks on the bottom line. Here’s the program:
The FOR line makes i be 1, then 2, then 3, and so on, up to 20. When i is 1, the PRINT line makes the computer print one asterisk, like this:
When i is 2, the PRINT line makes the computer print a line of 2 asterisks, like this:
The FOR line makes i be every number from 1 up to 20, so computer will print 1 asterisk, then underneath print a line of 2 asterisks, then underneath print a line of 3 asterisks, and so on, until the entire triangle is printed.
The study of triangles is called trigonometry — and the computer can do it for you!
To find out the sine and cosine, you can use a ruler but a faster and more accurate way is to let the computer do it! Yes, the computer can calculate triangles in its mind!
This program makes the computer measure the sine and cosine of 30°:
Line 2 is a special formula that defines the word degrees. The first PRINT line prints the sine of 30 degrees:
The bottom line prints the cosine of 30°, which is a decimal that’s slightly less than .87.
The computer can measure the sine and cosine of any size angle. Try it! For example, to make the computer print the sine and cosine of a 33° angle, say:
If you choose an angle of -33° instead of 33°, the triangle will dip down instead of rising up, and so the sine will be a negative number instead of positive.
In those PRINT lines, the “* degrees” is important: it tells the computer that you want the sine of 33 degrees. If you accidentally omit the “* degrees”, the computer will print the sine of 33 radians instead. (A radian is larger than a degree. A radian is about 57.3 degrees. More precisely, a radian is 180/p degrees.)
Tangent The sine divided by the cosine is called the tangent. For example, to find the tangent of 33°, divide the sine of 33° by the cosine of 33°.
To make the computer print the tangent of 33°, you could tell the computer to PRINT SIN(33 * degrees) / COS(33 * degrees). But to find the tangent more quickly and easily, just say PRINT TAN(33 * degrees).
Arc functions The opposite of the tangent is called the arctangent:
the tangent of 30° is about .58
the arctangent of .58is about 30°
Similarly, the opposite of the sine is called the arcsine, and the opposite of the cosine is called the arccosine.
This program prints the arctangent of .58, the arcsine of .5, and the arccosine of .87:
Line 3 prints the arctangent of .58, in degrees. (If you omit the “/ degrees”, the computer will print the answer in radians instead of degrees.) Line 4 sets x equal to .5 and then prints its arcsine (by using a formula that combines ATN with SQR). The bottom line sets x equal to .87 and then prints its arccosine (by using a formula that combines 90 with ATN and SQR). The answer to each of the three problems is about 30 degrees.
Types of numbers
QBASIC can handle several types of numbers.
Here are the general rules about types of numbers. I’ll explain exceptions later.
Real numbers versus integers:
If a number contains a decimal point, it’s called a real number.
For example, 27.1 is a real number. So is -27.1. So is 27.0.
A number without a decimal point is called an integer.
For example, 27 is an integer. So is -27.
27.0 is not an integer, since it contains a decimal point; 27.0 is a real number instead.
The computer handles integers faster than real numbers.
To make your program run faster, use integers.
Long integers versus short integers:
Tiny integers are called short integers.
For example, 0, 1, and 2 are short integers. So is 27. So is 589.
The biggest permissible short integer is 32767.
The lowest permissible short integer is -32768.
An integer that’s not short is called long.
For example, 50000 is a long integer, since it’s an integer bigger than 32767.
Another long integer is -50000.
The biggest permissible long integer is 2147483647
(which is about 2 billion, using the American definition of billion).
The lowest permissible long integer is -2147483648.
If you try to create an integer bigger than 2147483647, the computer will refuse. Instead, put a decimal point in the number, so the number becomes a real number. For example, if you want to deal with 5000000000, which is too big to be an integer, say 5000000000.0 instead, so the number is real.
The computer handles short integers faster than long integers, and handles long integers faster than real numbers.
To store a short integer in the computer’s RAM chips, the computer uses a special trick that lets the short integer fit into 2 bytes of RAM. So each short integer consumes just 2 bytes. For example, 589 consumes just 2 bytes. 32767 consumes just 2 bytes. -32768 consumes just 2 bytes.
To store a long integer, the computer uses a different trick, which consumes 4 bytes of RAM. For example, -2147483648 consumes 4 bytes.
Single-precision versus double-precision:
A real number contains a decimal point. It can also contain a negative sign and lots of digits.
If it contains at least 8 digits, it’s called a double-precision number. For example, 725.14592 is a double-precision number, since it contains 8 digits. 2943423.0 is double-precision. So is .00000001. So are -52341523092342.31 and -6.269549374523423, since each contains at least 8 digits. But .0000001 is not double-precision, since it contains just 7 digits.
A real number containing fewer than 8 digits is called single-precision. For example, .0000001 is single-precision. So is 5.2. So is -27.1.
A single-precision number can be up to 7 digits long.
A double-precision number can be up to 16 digits long.
A single-precision number consumes 4 bytes of RAM.
A double-precision number consumes 8 bytes of RAM.
The computer handles single-precision numbers faster than double-precision.
At the end of a number, you can put a suffix:
% short integer
& long integer
! single-precision real
# double-precision real
For example, the number 27 is a short integer. If you want to turn it into a single-precision real, write “27.0” or “27!” instead of “27”. If you want to turn it into a double-precision real, write “27.000000” or “27#”. If you want to turn it into a long integer, write “27&”.
In your program, if you write a double-precision real, the computer will automatically put the symbol # afterwards when you press the ENTER key. For example, if you write —
and then press the ENTER key, the computer will automatically turn your typing into this:
If you write a single-precision real that ends in .0, the computer will automatically change .0 to “!”. For example, if you write —
and then press the ENTER key, the computer will automatically turn your typing into this:
For single-precision real numbers, you can use E notation. For example, instead of writing 27945.86, you can write 2.794586E4. The “E4” means “move the decimal point 4 places to the right.” Instead of writing .0006829, you can write 6.829E-4, in which the “E-4” means “move the decimal point 4 places to the left.”
For double-precision real numbers, write a D instead of an E. For example, 2.794586D4 is the double-precision version of 2.794586E4.
The number before the E or D is called the mantissa; the number after the E or D is called the exponent. For example, in the number 2.794586E4, the mantissa is 2.794586; the exponent is 4.
For a single-precision numbers, the mantissa can contain up to 7 digits. For double-precision numbers, the mantissa can contain up to 16 digits.
A number that contains a D is double-precision, even if the mantissa contains few digits or no decimal point. A number that contains an E is single-precision, even if the mantissa contains no decimal point; but if the mantissa contains more than 7 digits, the computer will turn the E into a D when you press ENTER.
Biggest real numbers
The biggest permissible single-precision number is about 3.000000E38. More precisely, it’s 3.402823E38.
The biggest permissible double-precision number is about 1.000000000000000D308. More precisely, it’s 1.797693134862315D308.
If you try to go higher than those numbers, the computer will gripe by saying “Overflow”.
The computer handles integers accurately. The computer tries to handle real numbers accurately but sometimes makes slight mistakes with the real number’s last digit.
For a single-precision real number, the computer makes slight mistakes with the 7th digit. For a double-precision real number, the computer makes slight mistakes with the 16th digit.
You’ve seen that the biggest permissible double-precision number is about 1D308. The tiniest double-precision decimal that the computer can handle well is about 1D-308. If you try to go much tinier, the computer will usually botch the last few digits of the number (and replace those digits by different digits instead!) or else round the entire number to zero.
You’ve seen that the biggest permissible single-precision number is slightly bigger than 1E38. The tiniest single-precision decimal that the computer can handle well is about 1E-38. If you try to go much tinier, the computer will usually botch the last few digits of the number (and replace those digits by different digits instead!) or else round the entire number to zero.
Usually, each ordinary variable (such as x) stands for a single-precision real number. For example, you can say x=3.7, which makes x be the single-precision number 3.7.
If you say x=3, the computer will make x be 3.0 instead, to make x be a single-precision number. Though the screen will still say x=3, the x box in the computer’s RAM will contain 3.0 instead.
You can create five kinds of variables:
A variable that’s ordinary (such as x) or ends in an exclamation (such as x!)
is single-precision real.
A variable that ends in a dollar sign (such as x$) is a string.
A variable that ends in a percent sign (such as x%)is an short integer.
A variable that ends in an ampersand (such as x&)is a long integer.
A variable that ends in a number sign (such as x#) is double-precision real.
If you begin your program by saying —
all ordinary variables (such as x) will be short integers instead of single-precision real. (The word “DEFINT” means “DEFine to be INTegers”.) If instead you say —
all ordinary variables will be LoNG integers. If instead you say —
all ordinary variables will be DouBLe-precision real.
What to do
Write your program simply, without worrying about which numbers and variables are short integers, long integer, single-precision real numbers, and double-precision real numbers. But after your program is written and you’ve removed any errors, edit the program by making the following changes, which improve the program’s speed and accuracy:
All short integers: if your program doesn’t involve any decimals or big numbers, make the top line say DEFINT A-Z. That will turn every variable into a short integer, so the program runs faster and consumes less RAM.
Mostly short integers: if your program involves just a few decimals or big numbers, make the top line say DEFINT A-Z; then put an exclamation point (!) after every variable standing for a decimal, and put an ampersand (&) after every variable standing for a long integer.
Avoid round-off errors
The computer cannot handle decimals accurately. If you say x=.1, the computer can’t set x equal to .1 exactly; instead, it will set x equal to a number very, very close to .1. The reason for the slight inaccuracy is that the computer thinks in “binary”, not decimals; and .1 cannot be expressed in binary exactly.
Usually you won’t see the slight inaccuracy: when you ask the computer to PRINT a number, the computer prints it rounded to six significant figures, and the inaccuracy is so small it doesn’t show up in the rounded result. But there are three situations in which the inaccuracy can be noticed:
1. You’ll get wrong digits if you make the computer do x minus y, where x is almost equal to y (so the first several digits of x are the same as the first several digits of y). For example, if you say —
the computer will print .1000004 instead of .1. The same thing happens if you say:
If you say —
the computer will print .1015625 instead of .1.
If you say —
the computer will print .125 instead of .1.
The error can get magnified: if you ask the computer to multiply 800000.1-800000 by 1000, it will print .125*1000, which is 125, instead of .1*1000, which is 100. If you ask it to find the reciprocal of 800000.1-800000, it will print 1/.125, which is 8, instead of 1/.1, which is 10.
2. You’ll get wrong looping if you say “FOR x = a TO b STEP c”, where c is a decimal and the loop will be done many times. For example:
Theoretically, the computer should print 1, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, and 2. But that’s not what actually happens. In the FOR line, the computer can’t handle the decimal .1 accurately. The last few numbers the computer thinks of are:
slightly more than 1.7
slightly more than 1.8
slightly more than 1.9
The computer does not think of the next number, slightly more than 2.0, because the FOR line says not to go past 2. The PRINT line makes the computer print the numbers rounded to seven significant digits, so it prints:
It does not print 2.
If you want to compute 1 + 1.1 + 1.2 + 1.3 + 1.4 + 1.5 + 1.6 + 1.7 + 1.8 + 1.9 + 2, you might be tempted to write this program:
The computer will print a reasonable-looking answer: 14.5. But the computer’s “answer” is wrong, since the last number the computer added was slightly more than 1.9; it never added 2. The correct answer is 16.5.
To fix those FOR loops, you can change the FOR line to this
The .05 after the 2 allows for the margin of error. The general strategy is to change —
An alternative fix is to replace —
by this pair of lines:
As i goes from 10 to 20, x will go from 1 to 2 in steps of .1. This fix is the most accurate of all, since it eliminates decimals from the FOR line. But the new indented line (x = i / 10) makes the program run very slowly, since that line requires the computer to perform division, and the division is performed repeatedly (since it’s in the FOR loop).
3. You’ll get wrong testing if you ask the computer whether two numbers x and y are equal. It’s unwise to ask whether x is exactly equal to y, since both x and y have probably been affected by some slight error. Instead, ask the computer whether the difference between x and y is much tinier than y.
The .000001 is requesting that the first six significant digits of x be the same as the first six significant digits of y (except that the sixth significant digit might be off by one).
Why binary? From those discussions, you might think computers should be made differently, and that they should use the decimal system instead of binary. There are two counterarguments:
1. Binary arithmetic is faster.
2. Even if computers were using the decimal system, inaccuracy would still occur. To store the fraction 2/3 accurately by using the decimal system, the computer would have to store a decimal point followed by infinitely many 6’s. That would require an infinite amount of space in memory, which is impossible — unless you know how to build an infinitely large computer? So even in the decimal system, some fractions must be approximated instead of handled exactly.
According to mathematicians, addition is supposed to obey these laws:
x+0 is exactly the same as x
x+y is exactly the same as y+x
x+-x is exactly the same as 0
(x+y)+zis exactly the same as x+(y+z)
On the computer, the first three laws hold, but the last does not. If x is a decimal tinier than z, the computer does (x+y)+z more accurately than x+(y+z). So to add a list of numbers accurately, begin by adding together the tiniest decimals in the list.
When you add, subtract, or multiply integers together, the answer is an integer:
When you divide integers by using a slash (/), the answer is a real number:
If you divide integers by using a backslash (\), the computer will ignore any decimal digits and give you just an integer:
When you divide 11 by 4, the remainder is 3:
If you ask for 11 MOD 4, the computer will tell you the remainder when you divide 11 by 4:
So if you say —
the computer will print:
An integer is called composite if it’s the product of two other integers:
35 is composite because it’s 5 * 7
9 is composite because it’s 3 * 3
12 is composite because it’s 2 * 6
13 is not composite, so it’s called prime
This program tells whether a number is prime or composite:
To make the program run faster, we want all variables to be integers instead of reals. To let the program handle big numbers, we want the integers to be long. The DEFLNG line accomplishes all that: it makes all variables be long integers.
Here’s how the program works. The INPUT line waits for you to type an integer n. The IF line checks whether n is the product of two other integers; if it is, the computer says n is composite.
How fast does that program run? If n turns out to be prime, the IF line is encountered once for every i and once for every j; altogether it’s encountered (n-1)2 times. If n is a big number, around a billion, (n-1)2 is around a quintillion. (I’m using the American definitions of billion and quintillion. An American billion is 1,000,000,000; an American quintillion is 1,000,000,000,000,000,000. British definitions of billion and quintillion are different.) To do the IF line a quintillion times will take a typical microcomputer many years. For example, if you say that your favorite number is 999999929 (which is close to a billion), the typical 486DX2-66 computer will take about 400,000 years before it comes to the conclusion that your number is prime! By the time the program finishes running, you’ll be dead and so will many generations of your decendents! Probably your computer or its electricity will have died by then too! The program’s very slow.
Some small improvements are possible; for example, i and j can start at 2 instead of 1. But so long as you have a loop inside a loop, the time will remain very huge.
The following strategy requires just one loop: divide n by every integer less than it, to see whether the quotient is ever an integer. Here’s the program:
The IF line makes the computer divide n by i, compute the remainder (which is called “n MOD i”), and check whether that remainder is 0. If the remainder is 0, then n divided evenly by i, so n is divisible by i, so n is composite.
How fast is our new program? If n turns out to be prime, the IF line is encountered once for every i; altogether it’s encountered n-2 times. That’s less than in the previous program, where it was encountered (n-1)2 times. If n is about a billion, our new program does the IF line about a billion times, which is much fewer than the quintillion times required by the previous program! It’s nearly a billion times faster than the previous program! To determine whether 999999929 is prime, the new program takes a 486DX2-66 computer about 5 hours instead of 400,000 years.
We can improve the program even further. If an n can’t be divided by 2, it can’t be divided by any even number; so after checking divisibility by 2, we have to check divisibility by just 3, 5, 7, …, n-2. Let’s put that short-cut into our program, and also say that every n less than 4 is prime:
Line 5 checks divisibility by 2; the FOR loop checks divisibility by 3, 5, 7,… , n-2. If n is prime, the indented IF line is encountered n/2 - 2 times, which is about half as often as in the previous program; so our new program takes about half as long to run. On a 486DX2-66 computer, it takes about 2½ hours to handle 999999929.
Our goal was to find a pair of integers whose product is n. If there is such a pair of integers, the smaller one will be no more than the square root of n, so we can restrict our hunt to the integers not exceeding the square root of n:
The “1.00001” is to give a margin of safety, in case the computer rounds SQR(n) a bit down. If n is near a billion, the indented IF line is encountered about 15,000 times, which is much less than the 500,000,000 times encountered in the previous program and the 1,000,000,000,000,000,000 times in the original. This program lets a 486DX2-66 computer handle 999999929 in about ¼ of a second. That’s much quicker than earlier versions, which required 2½ hours, or 5 hours, or 400,000 years!
Moral: a few small changes in a program can make the computer take ¼ of a second instead of 400,000 years.
The frightening thing about this example is that the first version we had was so terrible, but the only way to significantly improve it was to take a totally fresh approach. To be a successful programmer, you must always keep your mind open and hunt for fresh ideas.
|all content copyright © 2002 / web design by josh feingold|