- •About the Author
- •Dedication
- •Author’s Acknowledgments
- •Contents at a Glance
- •Table of Contents
- •Introduction
- •Who Should Buy This Book
- •How This Book Is Organized
- •Part I: Programming a Computer
- •Part II: Learning Programming with Liberty BASIC
- •Part III: Advanced Programming with Liberty BASIC
- •Part VI: Internet Programming
- •Part VII: The Part of Tens
- •How to Use This Book
- •Foolish assumptions
- •Icons used in this book
- •Why Learn Computer Programming?
- •How Does a Computer Program Work?
- •What Do I Need to Know to Program a Computer?
- •The joy of assembly language
- •C: The portable assembler
- •High-level programming languages
- •Database programming languages
- •Scripting programming languages
- •The program’s users
- •The target computer
- •Prototyping
- •Choosing a programming language
- •Defining how the program should work
- •The Life Cycle of a Typical Program
- •The development cycle
- •The maintenance cycle
- •The upgrade cycle
- •Writing Programs in an Editor
- •Using a Compiler or an Interpreter
- •Compilers
- •Interpreters
- •P-code: A combination compiler and interpreter
- •So what do I use?
- •Squashing Bugs with a Debugger
- •Writing a Help File
- •Creating an Installation Program
- •Why Learn Liberty BASIC?
- •Liberty BASIC is easy
- •Liberty BASIC runs on Windows
- •You can start using Liberty BASIC today
- •Installing Liberty BASIC
- •Loading Liberty BASIC
- •Your First Liberty BASIC Program
- •Running a Liberty BASIC program
- •Saving a Liberty BASIC program
- •Getting Help Using Liberty BASIC
- •Exiting Liberty BASIC
- •Getting input
- •Displaying output
- •Sending Data to the Printer
- •Storing Data in Variables
- •Creating a variable
- •Assigning a value to a variable
- •Declaring your variables
- •Using Constants
- •Commenting Your Code
- •Using variables
- •Working with precedence
- •Using parentheses
- •Manipulating Strings
- •Declaring variables as strings
- •Smashing strings together
- •Counting the length of a string
- •Playing with UPPERCASE and lowercase
- •Trimming the front and back of a string
- •Inserting spaces
- •Yanking characters out of a string
- •Looking for a string inside another string
- •Using Boolean Expressions
- •Using variables in Boolean expressions
- •Using Boolean operators
- •Exploring IF THEN Statements
- •IF THEN ELSE statements
- •Working with SELECT CASE Statements
- •Checking a range of values
- •Checking a relational operator
- •Boolean expression inside the loop
- •Looping a Fixed Number of Times
- •Counting with different numbers
- •Counting in increments
- •Anatomy of a Computer Bug
- •Syntax Errors
- •Fun with Logic Errors
- •Stepping line by line
- •Tracing through your program
- •Designing a Window
- •Creating a new window
- •Defining the size and location of a window
- •Adding color to a window
- •Putting Controls in a Window
- •Creating a command button
- •Displaying text
- •Creating a check box
- •Creating a radio button
- •Creating text boxes
- •Creating list boxes
- •Creating combo boxes
- •Creating group boxes
- •Storing Stuff in Text Files
- •Creating a new text file
- •Putting stuff in a text file
- •Adding new stuff to an existing text file
- •Retrieving data from a text file
- •Creating a new binary file
- •Saving stuff in a binary file
- •Changing stuff in a binary file
- •Retrieving stuff from a binary file
- •Creating a Graphics Control
- •Using Turtle Graphics
- •Defining line thickness
- •Defining line colors
- •Drawing Circles
- •Drawing Boxes
- •Displaying Text
- •Making Sounds
- •Making a beeping noise
- •Playing WAV files
- •Passing Data by Value or by Reference
- •Using Functions
- •Defining a function
- •Passing data to a function
- •Calling a function
- •Exiting prematurely from a function
- •Using Subroutines
- •Defining a subroutine
- •Passing data to a subroutine
- •Calling a subroutine
- •Exiting prematurely from a subroutine
- •Writing Modular Programs
- •Introducing Structured Programming
- •Sequential instructions
- •Branching instructions
- •Looping instructions
- •Putting structured programming into practice
- •The Problem with Software
- •Ways to Make Programming Easier
- •Breaking Programs into Objects
- •How to use objects
- •How to create an object
- •Creating an object
- •Starting with a Pointer
- •Defining the parts of a linked list
- •Creating a linked list
- •Managing a linked list
- •Making Data Structures with Linked Lists
- •Stacks
- •Queues
- •Trees
- •Graphs
- •Creating a Record
- •Manipulating Data in Records
- •Storing data in a record
- •Retrieving data from a record
- •Using Records with Arrays
- •Making an Array
- •Making a Multidimensional Array
- •Creating Dynamic Arrays
- •Insertion Sort
- •Bubble Sort
- •Shell Sort
- •Quicksort
- •Sorting Algorithms
- •Searching Sequentially
- •Performing a Binary Search
- •Hashing
- •Searching by using a hash function
- •Dealing with collisions
- •Picking a Searching Algorithm
- •Choosing the Right Data Structure
- •Choosing the Right Algorithm
- •Put the condition most likely to be false first
- •Put the condition most likely to be true first
- •Clean out your loops
- •Use the correct data types
- •Using a Faster Language
- •Optimizing Your Compiler
- •Programming Computer Games
- •Creating Computer Animation
- •Making (And Breaking) Encryption
- •Internet Programming
- •Fighting Computer Viruses and Worms
- •Hacking for Hire
- •Participating in an Open-Source Project
- •Niche-Market Programming
- •Teaching Others about Computers
- •Selling Your Own Software
- •Trying Commercial Compilers
- •Windows programming
- •Macintosh and Palm OS programming
- •Linux programming
- •Testing the Shareware and
- •BASIC compilers
- •C/C++ and Java compilers
- •Pascal compilers
- •Using a Proprietary Language
- •HyperCard
- •Revolution
- •PowerBuilder
- •Shopping by Mail Order
- •Getting Your Hands on Source Code
- •Joining a Local User Group
- •Frequenting Usenet Newsgroups
- •Playing Core War
- •Programming a Battling Robot
- •Toying with Lego Mindstorms
- •Index
- •End-User License Agreement
Chapter 15
Debugging Programs
In This Chapter
Understanding computer bugs
Finding syntax errors
Discovering run-time errors
Figuring out logic errors
Nobody writes programs that work 100 percent correctly all the time. The problem is that programming means giving the computer extremely
detailed instructions. Give the computer one wrong instruction or one misplaced instruction, make one wrong assumption or omit one necessary instruction, and the computer has no idea what to do next, which can cause your program to fail or, in programming lingo, to crash.
If a program doesn’t work correctly, programmers never say, “My program has a problem.” Instead, programmers use their own lingo and say, “My program has a bug.” Although eliminating all bugs from a program is impossible, Liberty BASIC (and many other language compilers) provides special features to help you track down the obvious bugs and wipe them out so that your program works well enough for people to actually use it.
Anatomy of a Computer Bug
Computer bugs tend to fall into the following three categories:
Syntax errors: This type of error occurs if you spell something wrong or type a command incorrectly, such as misspelling PRINT as PRRINT or typing too many commas.
Run-time errors: These errors occur if your program runs into something unexpected, such as if you ask the user to input an age and the user types a negative number.
Logic errors: These bugs occur if your instructions don’t work as you intend them to, but the computer performs these flawed instructions anyway, creating unpredictable results.
216 Part III: Advanced Programming with Liberty BASIC
Although bugs riddle every program, most bugs are relatively harmless or cause only minor problems, such as displaying a menu incorrectly at unpredictable times. Bugs that keep a program from working at all are more serious. Any bug that keeps a company from shipping (and selling) a program is known as a showstopper.
Syntax Errors
Syntax errors are often misspellings of valid commands or omissions (or misplacement) of crucial characters such as a comma or a left parenthesis. If you misspell a BASIC command such as PRINT, Liberty BASIC is usually smart enough to highlight the line where the syntax error occurs so that you can fix it later. If Liberty BASIC finds a syntax error, it highlights the line causing the problem and displays a message in the bottom left corner of the screen, as shown in Figure 15-1.
Syntax error in code
Figure 15-1:
Liberty BASIC highlights lines containing syntax errors, such as misspelling a command as buttton instead of button.
Error message
Chapter 15: Debugging Programs 217
The Destruction of Mariner 1
Syntax errors are usually caught because they give an invalid command to the computer, which immediately keeps the program from running at all. The worst syntax errors, however, are those that somehow give a valid but unintended command to the computer. Thus, the program keeps working — but not the way you want it to.
Back in 1962, NASA sent the Mariner 1 probe to study Venus, but before the rocket carrying the probe could make its way into outer space, it veered off course and NASA had to prematurely detonate the rocket. According to one story, the program was supposed to contain a FOR NEXT
loop that told the computer to loop three times, as in the following example:
FOR I = 1, 3
But instead of a comma, the programmer had accidentally typed in a period, as follows:
FOR I = 1.3
So instead of telling the computer to loop three times, this command told the computer to set the value of the variable I to 1.3. The end result was that this error managed to give the computer a valid but incorrect command, causing NASA to lose a multimillion dollar rocket and payload as a result.
Although syntax errors usually prevent a program from working at all, watch out for your own misspellings because the computer will assume that you know what you’re doing, even if you make a mistake. Especially troublesome are those times that you misspell a variable name. Consider, for example, the following program:
PROMPT “How many times do I need to tell you no”; Answeer$ PRINT “Your reply = “; Answer$
END
The preceding program asks the user, “How many times do I need to tell you no?” Then the program stores whatever the user types into the variable Answeer$ (the misspelling of Answer$). Because Liberty BASIC considers Answer$ and Answeer$ as two completely different variable names, the Answer$ variable doesn’t contain any data. If you run this program, it doesn’t print out what the user types, simply because of a single misspelling.
Liberty BASIC can detect syntax errors in misspelled commands, but it cannot detect misspelled variable names. If you insert a space between a function or subroutine name and any parentheses that follow it, Liberty BASIC may treat that as a syntax error, too, although it won’t necessarily tell you so.
Besides misspelling a variable name, watch out for mixing upperand lowercase letters in variable names. Liberty BASIC considers the variable Answer$ as completely different from the variable answer$ simply because one starts with an uppercase letter A and the second one doesn’t.
218 Part III: Advanced Programming with Liberty BASIC
Death from the Therac-25
The Therac-25 was a radiation-therapy machine designed to adminster radiation doses to patients. To prevent excessive doses of radiation, the Therac-25 included a safety mechanism that relied completely on its software to prevent any problems — but the software contained a fatal run-time error.
The Therac-25 offered two modes of operation: X-ray and electron beam. If the technician accidentally selected the X-ray mode first, the Therac-25 would select a high-intensity energy level. If the technician then switched to electronbeam mode right away without completing the
X-ray mode, the Therac-25 would maintain its higher energy intensity level for electron-mode operation, which meant delivering a fatal radiation burn to any unlucky patient lying underneath.
Only after several people suffered severe radiation burns at the hands of the Therac-25 did someone finally discover this hidden run-time error, but by then, it was too late for all the people who’d already been irreparably burned by the Therac-25 and its supposedly fail-safe software safety mechanism.
Because a single misspelling of a variable name can mess up your program, many programmers take shortcuts and choose short, cryptic variable names. Don’t take this route! The time that you save in using short variable names is lost in comparison with the time that you need to decipher what those short variable names represent.
Such errors can prove hard to detect because a misspelling can still enable the program to run, albeit incorrectly. Anytime that your program runs but doesn’t seem to work right, start looking for misspellings or missing elements such as quotation marks, commas, upper and lowercase variable names, and parentheses, any of which may cause the program to fail.
Run-Time Errors
Run-time errors are sneaky little bugs that hide in programs. A program may work correctly right up until it receives data that the programmer never expected, such as a negative number that the user types for his year of birth. Unfortunately, the only time that you can find run-time errors is after they cause the program to crash.
Because run-time errors occur only after your program receives data that it doesn’t know how to handle, the best way to hunt down run-time errors is to run your program over and over, feeding the program extreme values of different data each time.