textfiles/programming/writprog.pro

378 lines
15 KiB
Prolog
Raw Permalink Normal View History

2021-04-15 11:31:59 -07:00
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<20> HOW TO PROGRAM <20>
<20> <20>
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
INTRODUCTION
Writing small programs is pretty easy stuff. True, there were some details
that had to be learned, as well as new concepts. But, the basic mechanics
were simple.
Writing large programs is quite another matter. There are several reasons
why long programs are more difficult to write. One is that short programs
are often used just once, and then discarded. Long programs, on the other
hand, are often designed for use by others. Consequently, they have to be
written more carefully, to anticipate all forms of misuse. They must also
be provided with elaborate documentation and manuals.
Another reason, many believe, is the limitation of a human being's short
term memory. Most persons can understand or grasp a short 10-line program
in a few seconds. And they can keep it in mind while they contemplate
changes. With large programs, the programmer must have all useful inform-
ation written down so it can be referred to when attempting to understand
or change the program.
Still another reason is the limit of what can appear on single screen or
page. Short programs that in their entirety occupy but one page, or one
screenful, are easier to understand than longer programs, which require
page-turning or screen-scrolling.
Whatever the reasons, writing large programs is not easy. Even profes-
sional programmers have trouble. One hears about rockets crashing because
of programming errors. And one hears that large programs may have hun-
dreds, or even thousands, of errors many months after they were allegedly
completed.
It is almost impossible to write a program that has no errors. If for no
other reason, we often do not know exactly what the program is supposed to
do, to the last detail, until after we have built it. But there is much
when can do to bring us closer to that error-free goal. The first step is
to understand the stages in developing a large program. These stages are
often referred to as the Software Development Life Cycle.
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ
<20> <20>
<20> 1. SPECIFICATION <20>
<20> 2. PROGRAM DESIGN <20>
<20> 3. CODE DESIGN <20>
<20> 4. CONSTRUCTION AND DESIGN <20>
<20> <20>
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
If, despite all our efforts with these four stages, errors still exist in
our program, then we will have to consider techniques to isolate errors.
This process is often call DEBUGGING, and is usually considered to be part
of STEP 4.
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͻ
<20> SPECIFICATION <20>
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼ
It is important to know what the program is supposed to do before starting
to build it. This is especially true if the program is being built for
someone else.
Matters to be determined during this stage include the user interface,
algorithms, data structures, generality, and robustness.
USER INTERFACE
What should the user have to do to interact with the program? Should there
be commands to be typed in? Should one use menus? How much freedom should
be allowed the user, with respect to, say, spelling errors? What should the
output displays look like?
It is at this stage that you should decide how best to PROMPT the user for
proper input, and how best to label the output. This is not always as easy
as it sounds.
ALGORITHMS
If the program requires extensive computation, what methods should be used?
For example, if a list of names needs sorting, which sorting ALGORITHM
should be used. ALGORITHM is merely the name given to a computational method
that (a) might require input, (b) always produces some output, (c) completes
its work in a fnite amount of time, and (d) does what it is supposed to do.
DATA STRUCTURES
How should the data of a problem be organized? Should one use lists or
tables? Should the data itself be sorted, or should use be made of an
indexed sort? Which, if any, data should be stored in files? One should
spend as much time answering questions like these as questions of what
algorithms to use. For, the efficiency of a well-written sorting algorithm
will be lost if the data are stored clumsily.
GENERALITY
Should a program be a special purpose program limited for use in a small
number of situations? Or should the program be general purpose, of use in
a wider variety of circumstances? There are arguments to be made in each
choice. A special purpose program is almost always easier to use. Fewer
commands have to be given, and fewer choices have to be made, to get it
to do its job. More general programs, besides being much longer, require
the user to make more choices and issue more commands to get it work.
And, the user may have to study a much larger manual before using the
program.
On the other hand, a general purpose program will do more things for the
user. And perhaps, only one general purpose program might be needed for
a series of tasks, whereas several special purpose programs would be
needed.
ROBUSTNESS
Robustness is the degree to which a program responds "gracefully" to being
fed bad data or bad commands. For example, does it give the user a second
chance if the user misspells the filename? These are but a few of the kinds
of questions that must be during the specification or planning stages of
building a large program.
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͻ
<20> PROGRAM DESIGN <20>
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼ
Program design is the most difficult part of building a large program.
For the most part, it involves deciding how a large program should be
divided into subroutines. A design is often represented by a structure
chart, which is simply a chart that shows which subroutines call which
other subroutines.
For example, a top-level subroutine, which is actually the main program,
calls three other subroutines. Thats all there is, as the three other
subroutines do not call other subroutines.
Structure charts shows the names of the data that are used and produced
by each subroutine. If the data are passed to and from the subroutine as
parameters, their names appear next to small arrows close to the line
connecting the subroutines. If the data are not passed, we use arrows
that originate and terminate inside the rectangles that represent the
subroutines.
Given a particular design (a particular structure chart), there are
two important questions that need to be raised. First, how does one
evaluate the design? And second, how does one develop a design in the
first place? Although there are design methodologies whose purpose is
to come up with a design, suffice to say, they require a careful and
thorough understanding of the underlying problem, and take sometime to
explain and understand.
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ
<EFBFBD> <20>
 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ SALES4 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ
 <20> <20> <20> <20>
 <20> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>
 ITEMS <20> ITEMS o <20> ITEMS o<EFBFBD> <20>
 PERSONS<EFBFBD> PERSONS <20> <20> PERSONS  <20>
 PRICE() <20> PRICE()  <20> PRICE()  <20>
 SALES(,) <20> SALES(,)  <20> SALES(,)  <20>
 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ
<20><><EFBFBD><EFBFBD><EFBFBD>o <20> <20> PERSONRESULT <20> <20>ITEMRESULT <20>
<20> READDATA <20> <20> <20> <20> <20>
<20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
The following are a few ideas that can be used to evaluate a design,
once one has been made. These ideas are heuristic because following
them usually, but not necessarily, leads to a good design.
KEEP SUBROUTINES SHORT
It is better to keep subroutines shorter than one page, or one screenful,
in length. If that is not possible, then so be it. But it is much harder
understand a subroutine if you must constantly shift pages or screens
back and forth.
One exception to this principle occurs when a subroutine consist of,
say an IF structure with a large number of ELSEIF parts. Here, the cure
(having several short subroutines) is worse than the illness (having one
long subroutine.)
KEEP SUB-ROUTINES SINGLE-PURPOSE
A subroutine that does one single task is almost always easier to write
and test than a subroutine that does several tasks. A single task may,
however, be quite complicated. For example, a subroutine that solves
a linear programming problem is necessarily quite complicated, and may
indeed call other subroutines. But it still has its purpose, a single
task.
Software engineers use the term (cohesion) to describe the degree to which
subroutines can range from being single-purpose (functional Cohesion) to
being a disjointed collection of unrelated tasks (coincidental cohesion).
KEEP CALLING SEQUENCES SHORT
If a subroutine needs four data elements to do its work, then the calling
sequence must contain four parameters. For example, the subroutine person-
result needs four parameters (the number of persons, the number of items
the price list, and the sales table). Four is not too many, but if a
calling sequence contains ten or more parameters, perhaps it is time to
reconsider the design.
COMMUNICATE DATA THROUGH CALLING SEQUENCES
As much as it is possible, one should supply the data needed by subroutines
through their calling sequences. The reason is that it is then clearer what
data are needed by the subroutine and therefore less likely that errors will
occur. This goal seems like the antithesis of our third goal. If we commun-
icate the data through calling sequences, then the calling sequences will be
longer. One recommendation is the use of internal subroutines without para-
meters to subdivide a large program into smaller pieces. This is still a
good idea. But if all the data needed by a subroutine is provided through
its calling sequence, then the subroutine can be made external. External
subroutines are much less likely to contribute to errors than internal sub-
routines that share data. Furthermore, an internal subroutine that has no
parameters, but that uses ten or Ffteen chunks of data, is likely to be
quite complicated.
Software engineers use the term "coupling" to measure the degree to which
two subroutines are interrelated. Subroutines are (loosely coupled) if they
share only a few data elements, and then only as parameters in their calling
sequences. Subroutines that have long calling sequences or share data with
other subroutines outside the calling sequences are said to be "tightly -
coupled". Loose coupling is generally better inasmuch as changes made to
one subroutine are then less likely to require changes to other subroutines.
As with cohesion, coupling is an important matter in rating a particular
design, but a more detailed discussion is beyond the scope of this text.
LIMIT USE OF FLAGS
FLAGS are signals that one subroutine sends to another. The first subroutine
decides something or other. It then sets a flag so that a different sub-
routine can know what the first subroutine decided. In BASIC flags are
usually variables that are set to either O or 1. For example, setting the
variable ERROR to O may mean that no errors have occurred, whereas setting
error to 1 may mean that one or more errors have occurred.
Programs that contain many flags are extremely difficult to write and to
test. And it is very difficult to make sure they are free from error.
Sometimes it is hard to avoid the use of FLAGS. Examples are subroutines
that test for errors. If these subroutines occur at a lower level, they
must communicate their results (errors versus no errors) back to the higher
level through a FLAG. Another occurs when a lower-level subroutine is
assigned the job of reading information from a file. When the end of the
file is reached, this subroutine must use a flag (or its equivalent) to
inform the higher-level routines.
MAKE DESIGN HIERACHICAL
The structure chart of a large program should usually look like an upside
down tree. That is, there is one box at the top (the main program) that
calls several subroutines at the second level. The second-level subroutines
often call more subroutines at the third level, and so on.
A good design idea is to have the high-level subroutines deal in high-
level concepts, like the top executives in a company. The often messy
details should be left to the lower-level subroutines. In this way it is
more likely that you will be able to separate the "forest from the trees",
to separate the general concepts from the specific details.
TO BE CONTINUED
X-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-X
Another file downloaded from: NIRVANAnet(tm)
& the Temple of the Screaming Electron Jeff Hunter 510-935-5845
Rat Head Ratsnatcher 510-524-3649
Burn This Flag Zardoz 408-363-9766
realitycheck Poindexter Fortran 415-567-7043
Lies Unlimited Mick Freen 415-583-4102
Specializing in conversations, obscure information, high explosives,
arcane knowledge, political extremism, diversive sexuality,
insane speculation, and wild rumours. ALL-TEXT BBS SYSTEMS.
Full access for first-time callers. We don't want to know who you are,
where you live, or what your phone number is. We are not Big Brother.
"Raw Data for Raw Nerves"
X-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-X