SD 500
SD 500
YEAR 1 SEMESTER 1
Registered with the Department of Higher Education as a Private Higher Education Institution under the Higher Education Act, 1997.
Registration Certificate No. 2000/HE07/008
LEARNER GUIDE
MODULE: SOFTWARE'(9(/230(17500 (1ST SEMESTER)
PREPARED ON BEHALF OF
RGI (PTY) LTD
Copyright © 2018
Richfield Graduate Institute of Technology
(Pty) Ltd
Registration Number: 2000/000757/07
All rights reserved; no part of this publication may be reproduced in any form or by any
means, including photocopying machines, without the written permission of the
Institution.
2
TABLE OF CONTENTS
1. Welcome 4
2. Title of Modules, Course, Code, NQF Level, Credits & Mode of Delivery 4
3. Purpose of Module 4
4. Learning Outcomes 5
5. Method of Study 5
7. Notices 5
2. Working with Data, Creating Modules and Designing High Quality Programs 26-44
4. Modularization 62-75
7. Looping 145-183
8. Arrays 184-222
3
SECTION A: PREFACE
1. WELCOME
This section of the study guide is intended to orientate you to the module before the commencement of
formal lectures.
The following lectures will focus on the common study units described:
2. TITLE OF MODULES, COURSE, CODE, NQF LEVEL, CREDITS & MODE OF DELIVERY
4
3. PURPOSE OF MODULE
The purpose of the course is to introduce the learner to various basic programming concepts. IT
provides an introduction to a programming environment, assuming that the learner does not have any
previous knowledge or experience of any programming languages. This course is meant for beginner
programmers and allows students to quickly build useful programs while learning the basics of
structured and object-oriented programming concepts. The course is aimed at developing the students
programming and logic abilities.
4. LEARNING OUTCOMES
5. METHOD OF STUDY
The sections that have to be studied are indicated under each topic. These form the basis for tests,
assignments and examination. To be able to do the activities and assignments for this module, and to
achieve the learning outcomes and ultimately to be successful in assignments and examinations, you will
need an in-depth understanding of the content of these sections in the learning guide and
prescribed book. In order to master the learning material, you must accept responsibility for your own
studies.
6. LEARNER MATERIALS
This programme is a self-study programme; the study material for each of the learner guides has been
uploaded onto the PC Tablet. These can be accessed electronically.
7. NOTICES
All information pertaining to this module such as dates for workshops, assignments, examinations,
Portfolio of Evidence (POE), etc shall be available in the ODL Prospectus. Any additional notices and/or
information shall be posted on the website.
5
8. PRESCRIBED & RECOMMENDED MATERIAL
8.1.1. Joyce Farrell: Programming Logic & Design Introductory, 6th Edition.
The purchasing of prescribed books is for the learners own account and is compulsory for all learners. This
guide will have limited value if not accompanied by the prescribed text books.
NB: Learners please note that there will be a limited number of copies of the recommended texts and
reference material that will be made available at your campus library. Learners are advised to make copies
or take notes of the relevant information, as the content matter is examinable.
8.3. Independent Research
8.4.1. Each campus keeps a limited quantity of the recommended reading titles and a larger variety of
similar titles which you may borrow. Please note that learners are required to purchase the
prescribed materials.
8.4.2. Arrangements have been made with municipal, state and other libraries to stock our recommended
reading and similar titles. You may use these on their premises or borrow them if available. It is
your responsibility to safe keeps all library books
8.4.3. ZŝĐŚĨŝĞůĚ has also allocated one library period per week as to assist you with your formal research
under professional supervision.
8.4.4. The computers laboratories, when not in use for academic purposes, may also be used for research
purposes. Booking is essential for all electronic library usage.
9. ASSESSMENT
Final Assessment for this module will comprise two Continuous Assessment tests, an assignment and an
examination. Your lecturer will inform you of the dates, times and the venues for each of these. You may
also refer to the notice board on your campus or the Academic Calendar which is displayed in all lecture
rooms.
There is one compulsory test for each module (in each semester).
6
9.2. Assignment
There are two compulsory assignments for each module in each semester. Your lecturer will inform you
of the Assessment questions at the commencement of this module.
9.3. Examination
There is one 2 hour examination for each module. Make sure that you diarize the correct date, time and
venue. The examinations department will notify you of your results once all administrative matters are
cleared and fees are paid up.
The examination may consist of multiple choice questions, short questions and essay type questions. This
requires you to be thoroughly prepared as all the content matter of lectures, tutorials, all references
to the prescribed text and any other additional documentation/reference materials is examinable in both
your tests and the examinations.
The examination department will make available to you the details of the examination (date, time and
venue) in due course. You must be seated in the examination room 15 minutes before the
commencement of the examination. If you arrive late, you will not be allowed any extra time. Your learner
registration card must be in your possession at all times.
9.4. Final Assessment
Assignment One
Assignment Two 40%
Assignment Three
Total Continuous Assessments 40% Semester
Examination 60%
Total 100%
In assignment and examination questions you will notice certain key concepts (i.e. words/verbs) which
tell you what is expected of you. For example, you may be asked in a question to list, describe, illustrate,
demonstrate, compare, construct, relate, criticize, recommend or design particular information /
aspects / factors /situations. To help you to know exactly what these key concepts or verbs mean so that
you will know exactly what is expected of you, we present the following taxonomy by Bloom, explaining
the concepts and stating the level of cognitive thinking that theses refer to.
7
Observation and recall of information
Knowledge of dates, events, places
Knowledge of major ideas
Mastery of subject matter
Question Cues list, define, tell, describe, identify, show, label, collect, examine,
Knowledge tabulate, quote, name, who, when, where, etc.
Understanding information
Grasp meaning
Translate knowledge into new context
Interpret facts, compare, contrast
Order, group, infer causes predict
consequences
Question Cues
Comprehension summarize, describe, interpret, contrast, predict, associate,
estimate, differentiate, discuss, extend
distinguish,
Use information
Use methods, concepts, theories in new situations Solve
problems using required skills or knowledge
Questions Cues
Application apply, demonstrate, calculate, complete, illustrate, show, solve,
modify, relate, change, classify, experiment, discover
examine,
Seeing patterns
Organization of parts
Recognition of hidden meanings
Identification of components
Question Cues
Analysis analyze, separate, order, explain, connect, classify, arrange, divide, compare,
select, explain, infer
8
Compare and discriminate between ideas
Assess value of theories, presentations Make
choices based on reasoned argument Verify
value of evidence recognize subjectivity
Question Cues
Evaluation assess, decide, rank, grade, test, measure, recommend, convince, select, judge,
explain, discriminate, support, conclude, compare, summarize
9
10. SPECIMEN ASSIGNMENT COVER SHEET
ZŝĐŚĨŝĞůĚ͘'ƌĂĚƵĂƚĞ͘/ŶƐƚŝƚƵƚĞ͘ŽĨ͘dĞĐŚŶŽůŽŐLJ
SOFTWARE s>KWDEd͘(1st Semester)
Assignment Cover Sheet(To be attached to all Assignments – hand written or typed)
Name of Learner:………………………… Student No: …………………………
Module:…………………………………… Date: …………………………………
ICAS Number ………………………… ID Number …………………………
ASSESSMENT CRITERIA
(NB: The allocation of marks below may not apply to certain modules like EUC and Accounting)
A. Content- Relevance.
Mark Examiner’s Moderator’s
Question Number Allocation Mark Marks Remarks
1
2
3
4
5
6
7
8
9
10
Sub Total 70 Marks
B. Research (A minimum of “TEN SOURCES” is recommended)
Library, EBSCO, Emerald Journals, Internet, Newspapers, Journals, Text Books, Harvard method of
referencing
Sub Total 15 Marks
C. Presentation
10
Introduction, Body, Conclusion, Paragraphs, Neatness, Integration, Grammar / Spelling, Margins on
every page, Page Numbering, Diagrams, Tables, Graphs, Bibliography
Sub Total 15 Marks
Grand Total 100 Marks
NB: All Assignments are compulsory as it forms part of continuous assessment that goes towards the
final mark.
11. WORK READINESS PROGRAMME (WRP)
In order to prepare learners for the world of work, a series of interventions over and above the formal
curriculum, are concurrently implemented to prepare learners.
These include:
Soft skills
Employment skills
Life skills
End –User Computing (if not included in your curriculum)
The illustration below outlines some of the key concepts for Work Readiness that will be included in your
timetable.
It is in your interest to attend these workshops, complete the Work Readiness Log Book and prepare for
the Working World.
12. WORK INTEGRATED LEARNING (WIL)
11
Work Integrated Learning forms a core component of the curriculum for the completion of this
programme. All modules making of the Higher Certificate in Information Technology will be assessed in
an integrated manner towards the end of the programme or after completion of all other modules.
Learners will be fully inducted on the Work Integrated Learning Module, the Workbooks & assessment
requirements before placement with employers.
12
FACULTY OF MEDIA, INFORMATION AND
COMMUNICATION TECHNOLOGY
LEARNER GUIDE
MODULE: SOFTWARE '(9(/230(17500 (1ST SEMESTER)
TOPIC 4 : MODULARIZATION
TOPIC 5 :
MAKING DECISIONS
TOPIC 6 : DESIGNING AND WRITING A COMPLETE PROGRAM
TOPIC 7 : LOOPING
TOPIC 8 :
ARRAYS
TOPIC 9 : FILE HANDLING AND APPLICATIONS
Diploma in Information
Topic 1: An overview of computers and programming Technology
1.1 Understanding Computer Components and Operations
1.2 Understanding the Programming Process
1.2.1 Understanding the Program
1.2.2 Planning the Logic
1.2.3 Coding the Program
1.2.4 Using Software to Translate the Program into Machine Language
Lecture
1.2.5 Testing the Program
6-10
1.2.6 Putting the Program into Production
Topic Summary
Key Terms
Review Questions
Topic 2: Working with Data, Creating Modules and Designing High Quality Programs
2.1 Understanding the Data Hierarchy
13
2.2 Using Flowchart Symbols and Pseudocode Statements
2.3 Using and Naming Variables
2.4 Ending a Program by Using Sentinel Values
2.5 Using the Connector
2.6 Assigning Values to Variables
2.7 Understanding Data Types
2.8 Understanding the Evolution of Programming Techniques
2.8.1 Problem Solving Approach
Lecture
Topic Summary
11-14
Key Terms
Review Questions
Find The Errors
Exercises
Topic 3: Understanding Structure
3.1 Understanding the Three Basic Structures
3.2 Understanding the Reasons for Structure
3.3 THREE SPECIAL STRUCTURES—CASE, DO WHILE, AND DO UNTIL
Topic Summary
Key Terms Lecture
Review Questions 15-16
Find the Errors
Topic 4: Modularization
4.1 Modules, Subroutines, Procedures, Functions, or Methods
4.2 Modularization Allows Multiple Programmers to Work on a Problem
4.3 Modularization Allows You to Reuse Your Work
4.4 Modularization Makes it Easier to Identify Structures
4.5 Modularizing a Program
4.6 Modules Calling Other Modules
4.7 Declaring Variables
Lecture
Topic Summary
17-20
Key Terms
Review Questions
Find the Errors
Exercise
Topic 5:Designing and Writing a Complete Program
5.1 Understanding the Mainline Logical Flow Through a Program
5.2 Declaring Variables
5.3 Opening Files
5.4 A One-Time-Only-Task—Printing Headings
5.5 Reading the First Input Record
5.6 Checking for the End of the File
14
5.6.1 Writing the Main Loop
5.6.2 Performing End-Of-Job Tasks
5.6.3 Understanding the Need for Good Program Design
5.6.4 Storing Program Components in Separate Files
5.6.5 Selecting Variable and Module Names
5.6.6 Designing Clear Module Statements
5.7 Avoiding Confusing Line Breaks
5.8 Using Temporary Variables to Clarify Long Statements
Lecture
5.9 Using Constants Where Appropriate 21 - 25
5.9.1 Maintaining Good programming Habits
Chapter Summary
Key Terms
Review Questions
Find the Bugs
Exercise
Topic 6: Making Decisions
6.1 Evaluating Boolean Expressions to Make Comparisons
6.2 Using the Relational Comparison Operators
6.3 Writing Nested and Decisions for Efficiency
6.4 Combining Decisions in an AND Selection
6.5 Avoiding Common Errors in an AND Selection
6.5.1 Understanding OR Logic
6.6 Avoiding Common Errors in an OR Selection
6.7 Writing OR Decisions for Efficiency
6.8 Combining Decisions in an OR Selection
6.8.1 Using Selections within Ranges
6.9 Common Errors Using Range Checks
6.9.1 Understanding Precedence When Combining AND and OR Selections
6.9.2 Understanding the Case Structure Lecture
6.9.3 Using Decision Tables 26 - 30
Chapter Summary
Key Terms
Review Questions
Find the Bugs
Exercise
Topic 7: Looping
7.1 Understanding the Advantages of Looping
7.2 using a While loop with a Loop Control Variable
7.2.1 Using a Counter to Control Looping Lecture
7.2.2 Looping with a Variable Sentinel Value 31-35
15
7.3 Neglecting to Initialize the Loop Control Variable
7.4 Neglecting to Alter the loop Control Variable
7.5 Using the Wrong Comparison with the Loop Control Variable
7.6 Including Statements Inside the Loop that Belong Outside the Loop
7.7 Initializing a Variable that does Not Require Initialization
7.7.1 Using the For Statement
7.7.2 Using the Do While and Do until Loops
7.7.3 Recognizing the Characteristics Shared by All Loops
7.7.4 Nesting Loops
7.7.5 Using a Loop to Accumulate Totals
7.8 Understanding Control Break Logic
7.8.1 Performing a Single-Level Control Break to Start a New Page
7.8.2 Performing Multiple-Level Control Breaks
Chapter Summary
Key Terms
Review Questions
Find the Bugs
Exercise
Topic 8: Arrays
8.1 Understanding Arrays
8.2 How Arrays Occupy Computer Memory
8.3 Manipulating an Array to Replace Nested Decisions
8.4 Array Declaration and Initialization
8.5 Declaring and Initializing Constant Arrays
8.6 Loading an Array from a File
8.7 Searching for an Exact Match in an Array
8.8 Using Parallel Arrays
8.9 Remaining Within Array Bounds
8.10 Improving Search Efficiency using an Early Exit
8.11 Searching an Array for a Range Match Lecture
Chapter Summary 36-40
Key Terms
Review Questions
Find the Bugs
Exercise
Topic 9: File Handling and Applications
9.1 Understanding Sequential Data Files and the Need for Merging Files
9.2 Creating the Mainline and housekeeping() Logic for a Merge Program
9.3 Creating the mergeFiles() nad finishUp() Modules for a Merge program
9.4 Modifying the housekeeping() Module in the Merge Program to Check
for eof
16
9.5 Master and Transaction File Processing
9.6 Matching Files to Upgrade Fields in Master File Records
9.7 Allowing Multiple Transactions for a Single Master File Record Lecture
9.8 Updating Records in Sequential Files 41-44
Chapter Summary
Key Terms
Review Questions
Find the Bugs
Exercise
Review and Mock Exam Lecture 45
17
TOPIC 1
LEARNING OUTCOMES
After Studying this topic you should be able to:
Understand computer components and operations
Describe the steps involved in the programming process
Hardware and software are the two major components of any computer system. Hardware is the
equipment, or the devices, associated with a computer. For a computer to be useful, however, it needs
more than equipment; a computer needs to be given instructions. The instructions that tell the
computer what to do are called software, or programs, and are written by programmers.
Software can be classified as application software or system software. Application software comprises all
the programs you apply to a task—word-processing programs, spread sheets, payroll and inventory
programs, and even games. System software comprises the programs that you use to manage your
computer—operating systems, such as Windows, Linux, or UNIX. Understanding the evolution of
programming techniques together, computer hardware and software accomplish four major operations:
1. Input
2. Processing
3. Output
4. Storage
Hardware devices that perform input include keyboards and mouse. Through these devices, data, or facts,
enter the computer system. Processing data items may involve organizing them, checking them for
accuracy, or performing mathematical operations on them. The piece of hardware that performs these
sorts of tasks is the central processing unit, or CPU. After data items have been processed, the resulting
information is sent to a printer, monitor, or some other output device so people can view, interpret, and
use the results. Often, you also want to store the output information on storage hardware, such
as magnetic disks, tapes, compact discs, or flash media. Computer software consists of all the instructions
that control how and when the data items are input, how they are processed, and the form in which they
are output or stored.
Data includes all the text, numbers, and other information that are processed by a computer. However,
many computer professionals reserve the term “information” for data that has been processed. For
example, your name, Social Security number, and hourly pay rate are data items, but your pay check holds
information.
18
Computer hardware by itself is useless without a programmer’s instructions, or software, just as your
stereo equipment doesn’t do much until you provide music on a CD or tape. You can buy prewritten
software that is stored on a disk or that you download from the Internet or you can write your own
software instructions. You can enter instructions into a computer system through any of the hardware
devices you use for data; most often, you type your instructions using a keyboard and store them on a
device such as a disk or CD.
You write computer instructions in a computer programming language, such as Visual Basic, C#, C++, Java,
or COBOL. Just as some people speak English and others speak Japanese, programmers also write
programs in different languages. Some programmers work exclusively in one language, whereas others
know several and use the one that seems most appropriate for the task at hand.
No matter which programming language a computer programmer uses, the language has rules
governing its word usage and punctuation.
Unless the syntax is perfect, the computer cannot interpret the programming language instruction at all.
Every computer operates on circuitry that consists of millions of on/off switches. Each programming
language uses a piece of software to translate the specific programming language into the computers
on/off circuitry language, or machine language. The language translation software is called a compiler or
interpreter, and it tells you if you have used a programming language incorrectly. Therefore, syntax errors
are relatively easy to locate and correct—the compiler or interpreter you use highlights every syntax error.
If you write a computer program using a language such as C++ but spell one of its words incorrectly or
reverse the proper order of two words, the translator lets you know that it found a mistake by displaying
an error message as soon as you try to translate the program.
Although there are differences in how compilers and interpreters work, their basic function is the same—
to translate your programming statements into code the computer can use. When you use a compiler, an
entire program is translated before it can execute; when you use an interpreter, each instruction is
translated just prior to execution. Usually, you do not choose which type of translation to use—it depends
on the programming language. However, there are some languages for which both compilers and
interpreters are available. A program without syntax errors can be executed on a computer, but it might
not produce correct results. For a program to work properly, you must give the instructions to the
computer in a specific sequence, you must not leave any instructions out, and you must not add
extraneous instructions. By doing this, you are developing the logic of the computer program.
Programmers often call logical errors semantic errors. For example, if you misspell a programming
language word, you commit a syntax error, but if you use an otherwise correct word that does not make
any sense in the current context, you commit a semantic error.
Once instructions have been input to the computer and translated into machine language, a program can
be run, or executed. You can write a program that takes a number (an input step), doubles it (processing),
and tells you the answer (output) in a programming language such as Java or C++, but if you were to write
it using English-like statements, it would look like this:
Get inputNumber.
Compute calculatedAnswer as inputNumber times 2. Print
calculatedAnswer.
19
The instruction to Get inputNumber is an example of an input operation. When the computer interprets
this instruction, it knows to look to an input device to obtain a number. Computers often have several
input devices, perhaps a keyboard, a mouse, a CD drive, and two or more disk drives.
Logically, however, it doesn’t really matter which hardware device is used, as long as the computer knows
to look for a number. The logic of the input operation—that the computer must obtain a number for input,
and that the computer must obtain it before multiplying it by two—remains the same regardless of any
specific input hardware device.
Many computer professionals categorize disk drives and CD drives as storage devices rather than input
devices. Such devices actually can be used for input, storage, and output.
Processing is the step that occurs when the arithmetic is performed to double the inputNumber; the
statement Compute calculatedAnswer as inputNumber times 2 represents processing. Mathematical
operations are not the only kind of processing, but they are very typical. After you write a program, the
program can be used on computers of different brand names, sizes, and speeds. Whether you use an IBM,
Macintosh, Linux, or UNIX operating system, and whether you use a personal computer that sits on your
desk or a mainframe that costs hundreds of thousands of dollars and resides in a special building in a
university, multiplying by 2 is the same process. The hardware is not important; the processing will be the
same. In the number-doubling program, the Print calculatedAnswer statement represents output. Within
a particular program, this statement could cause the output to appear on the monitor (which might be a
flat panel screen or a cathode-ray tube), or the output could go to a printer (which could be laser or ink-
jet), or the output could be written to a disk or CD. The logic of the process called “Print” is the same no
matter what hardware device you use.
Besides input, processing, and output, the fourth operation in any computer system is storage. When
computers produce output, it is for human consumption. For example, output might be displayed on a
monitor or sent to a printer. Storage, on the other hand, is meant for future computer use (for example,
when data items are saved on a disk). Computer storage comes in two broad categories. All computers
have internal storage, often referred to as memory, main memory, primary memory, or random access
memory (RAM). This storage is located inside the system unit of the machine. (For example, if you own a
microcomputer, the system unit is the large case that holds your CD or other disk drives. On a laptop
computer, the system unit is located beneath the keyboard.)
Computers also use external storage, which is persistent (relatively permanent) storage on a device such
as a floppy disk, hard disk, flash media, or magnetic tape. In other words, external storage is outside the
main memory, not necessarily outside the computer. Both programs and data sometimes are stored on
each of these kinds of media. To use computer programs, you must first load them into memory. You
might type a program into memory from the keyboard, or you might use a program that has already been
written and stored on a disk. Either way, a copy of the instructions must be placed in memory before the
program can be run.
A computer system needs both internal memory and external storage. Internal memory is needed to run
the programs, but internal memory is volatile—that is, its contents are lost every time the computer loses
power. Therefore, if you are going to use a program more than once, you must store it, or save it, on some
non-volatile medium. Otherwise, the program in main memory is lost forever when the computer is
turned off. External storage (usually disks or tape) provides a non-volatile (or persistent)
medium.
20
Even though a hard disk drive is located inside your computer, the hard disk is not main, internal memory.
Internal memory is temporary and volatile; a hard drive is permanent, non-volatile storage. After one or
two “tragedies” of losing several pages of a typed computer program due to a power failure or other
hardware problem, most programmers learn to periodically save the programs they are in the process of
writing, using a non-volatile medium such as a disk.
Once you have a copy of a program in main memory, you want to execute, or run, the program. To do so,
you must also place any data that the program requires into memory. For example, after you place the
following program into memory and start to run it, you need to provide an actual inputNumber—for
example, 8—that you also place in main memory.
Get inputNumber.
Compute calculatedAnswer as inputNumber times 2. Print
calculatedAnswer.
The inputNumber is placed in memory at a specific memory location that the program will call
inputNumber. Then, and only then, can the calculatedAnswer, in this 16, be calculated and printed.
A programmer’s job involves writing instructions, but a professional programmer usually does not just sit
down at a computer keyboard and start typing. The programmer’s job can be broken down into six
programming steps:
Professional computer programmers write programs to satisfy the needs of others. Examples could
include a Human Resources Department that needs a printed list of all employees, a Billing Department
that wants a list of clients who are 30 or more days overdue on their payments, and an office manager
who wants to be notified when specific supplies reach the reorder point. Because programmers are
providing a service to these users, programmers must first understand what it is the users want.
The heart of the programming process lies in planning the program’s logic. During this phase of the
programming process, the programmer plans the steps of the program, deciding what steps to include
and how to order them. You can plan the solution to a problem in many ways. The two most common
planning tools are flowcharts and pseudocode.
21
You may hear programmers refer to planning a program as “developing an algorithm.” An algorithm is
the sequence of steps necessary to solve any problem.
The programmer doesn’t worry about the syntax of any particular language at this point, just about
figuring out what sequence of events will lead from the available input to the desired output. Planning
the logic includes thinking carefully about all the possible data values a program might encounter and
how you want the program to handle each scenario. The process of walking through a program’s logic on
paper before you actually write the program is called desk-checking.
1.2.3 CODING THE PROGRAM
Once the programmer has developed the logic of a program, only then can he or she write the program
in one of more than 400 programming languages. Programmers choose a particular language because
some languages have built-in capabilities that make them more efficient than others at handling certain
types of operations. Despite their differences, programming languages are quite alike—each can handle
input operations, arithmetic processing, output operations, and other standard functions. The logic
developed to solve a programming problem can be executed using any number of languages. It is only
after a language is chosen that the programmer must worry about each command being spelled
correctly and all of the punctuation getting into the right spots—in other words, using the correct
syntax.
Some very experienced programmers can successfully combine the logic planning and the actual
instruction writing, or coding, of the program in one step. This may work for planning and writing a very
simple program, just as you can plan and write a postcard to a friend using one step.
Even though there are many programming languages, each computer knows only one language, its
machine language, which consists of many 1s and 0s. Computers understand machine language because
computers themselves are made up of thousands of tiny electrical switches, each of which can be set in
either the on or off state, which is represented by a 1 or 0, respectively.
Languages like Java or Visual Basic are available for programmers to use because someone has written a
translator program (a compiler or interpreter) that changes the English-like high-level programming
language in which the programmer writes into the low-level machine language that the computer
understands. If you write a programming language statement incorrectly (for example, by misspelling a
word, using a word that doesn’t exist in the language, or using “illegal” grammar), the translator
program doesn’t know what to do and issues an error message identifying a syntax error, or misuse of a
language’s grammar rules. You receive the same response when you speak nonsense to a human-
language translator. Imagine trying to look up a list of words in a Spanish-English dictionary if some of the
listed words are misspelled—you can’t complete the task until the words are spelled correctly. Although
making errors is never desirable, syntax errors are not a major concern to programmers, because the
compiler or interpreter catches every syntax error, and the computer will not execute a program that
contains them.
A computer program must be free of syntax errors before you can execute it. Typically, a programmer
develops a program’s logic, writes the code, and then compiles the program, receiving a list of syntax
22
errors. The programmer then corrects the syntax errors, and compiles the program again. Correcting the
first set of errors frequently reveals a new set of errors that originally were not apparent to the
compiler.
When writing a program, a programmer might need to recompile the code several times. An executable
program is created only when the code is free of syntax errors. When you run an executable program, it
typically also might require input data. Figure 1-1 shows a diagram of this entire process.
A program that is free of syntax errors is not necessarily free of logical errors. Once a program is free from
syntax errors, the programmer can test it—that is, execute it with some sample data to see whether the
results are logically correct. Programs should be tested with many sets of data.
Once the program is tested adequately, it is ready for the organization to use. Putting the program into
production might mean simply running the program once, if it was written to satisfy a user’s request for
a special list. However, the process might take months if the program will be run on a regular basis, or if
it is one of a large system of programs being developed. Perhaps data-entry people must be trained to
prepare the input for the new program, users must be trained to understand the output, or existing data
in the company must be changed to an entirely new format to accommodate this program. Conversion,
the entire set of actions an organization must take to switch over to using a new program or set of
programs, can sometimes take months or years to accomplish.
You might consider maintaining programs as a seventh step in the programming process. After programs
are put into production, making required changes is called maintenance.
TOPIC SUMMARY
Together, computer hardware (equipment) and software (instructions) accomplish four major
operations: input, processing, output, and storage. You write computer instructions in a
computer programming language that requires specific syntax; the instructions are translated into
23
machine language by a compiler or interpreter. When both the syntax and logic of a program
are correct, you can run, or execute, the program to produce the desired results.
A programmer’s job involves understanding the problem, planning the logic, coding the program,
translating the program into machine language, testing the program, and putting the program into
production.
KEY TERMS
25
D. volatile
8. Which of the following pairs of steps in the programming process is in the correct order?
A. code the program, plan the logic
B. test the program, translate it into machine language
C. put the program into production, understand the problem
D. code the program, translate it into machine language
9. The two most commonly used tools for planning a program’s logic are.
A. flowcharts and pseudocode
B. ASCII and EBCDIC
C. Java and Visual Basic
D. word processors and spread sheets
10. The most important thing a programmer must do before planning the logic to a program is. A. decide
which programming language to use
B. code the problem
C. train the users of the program
D. understand the problem
11. Writing a program in a language such as C++ or Java is known as the program. A. translating
B. coding
C. interpreting
D. compiling
12. A compiler would find all of the following programming errors except. A. the misspelled word “print”
in a language that includes the word “print”
B. the use of an “X” for multiplication in a language that requires an asterisk
C. a newBalanceDue calculated by adding a customerPayment to an oldBalanceDueinstead of
subtracting it
D. an arithmetic statement written as regularSales + discountedSales = totalSales
26
TOPIC 2
LEARNING OUTCOMES
After Studying this topic you should be able to:
Describe the data hierarchy
Understand how to use flowchart symbols and Pseudocode statements
Use and name variables
Use a sentinel, or dummy value, to end a program
Use a connector symbol
Assign values to variables
Recognize the proper format of assignment statements
Understanding the evolution of programming techniques
Some very simple programs require very simple data. For example, the number-doubling program
requires just one value as input. Most business programs, however, use much more data—inventory files
list thousands of items, personnel and customer files list thousands of people. When data items are stored
for use on computer systems, they are often stored in what is known as a data hierarchy, where the
smallest usable unit of data is the character. Characters are letters, numbers, and special symbols, such
as “A”, “7”, and “$”. Anything you can type from the keyboard in one keystroke (including a space or a
tab) is a character. Characters are made up of smaller elements called bits, but just as most hu man beings
can use a pencil without caring whether atoms are flying around inside it, most computer users can store
characters without caring about these bits.
Characters are grouped together to form a field. A field is a single data item, such as lastName,
streetAddress, or annualSalary.
Related fields are often grouped together to form a record. Records are groups of fields that go together
for some logical reason. A random name, address, and salary aren’t very useful, but if they’re your name,
your address, and your salary, then that’s your record. An inventory record might contain fields for item
number, color, size, and price; a student record might contain ID number, grade point average, and major.
Related records, in turn, are grouped together to form a file. Files are groups of records that go together
for some logical reason. The individual records of each student in your class might go together in a file
called STUDENTS. Records of each person at your company might be in a file called PERSONNEL. Items
you sell might be in an INVENTORY file.
27
Some files can have just a few records; others, such as the file of credit-card holders for a major
department-store chain or policyholders of an insurance company, can contain thousands or even millions
of records.
Finally, many organizations use database software to organize many files. A database holds a group of
files, often called tables, which together serve the information needs of an organization. Database
software establishes and maintains relationships between fields in these tables, so that users can write
questions called queries. Queries pull related data items together in a format that allows businesspeople
to make managerial decisions efficiently.
A database contains many files. A file contains many records. Each record in a file has the same fields. Each
record’s fields contain different data items that consist of one or more stored characters in each field.
2.2 USING FLOWCHART SYMBOLS AND PSEUDOCODE STATEMENTS
When programmers plan the logic for a solution to a programming problem, they often use one of two
tools, flowcharts or pseudocode (pronounced “sue-doe-code”). A flowchart is a pictorial representation
of the logical steps it takes to solve a problem. Pseudocode is an English-like representation of the same
thing. Pseudo is a prefix that means “false,” and to code a program means to put it in a programming
language; therefore, pseudocode simply means “false code,” or sentences that appear to have been
written in a computer programming language but don’t necessarily follow all the syntax rules of any
specific language.
Using pseudocode involves writing down all the steps you will use in a program. Usually, programmers
preface their pseudocode statements with a beginning statement like “start” and end them with a
terminating statement like “stop”. The statements between “start” and “stop” look like English and are
indented slightly so that “start” and “stop” standout.
Some professional programmers prefer writing pseudocode to drawing flowcharts, because using
pseudocode is more similar to writing the final statements in the programming language. Others prefer
drawing flowcharts to represent the logical flow, because flowcharts allow programmers to visualize more
easily how the program statements will connect. Especially for beginning programmers, flowcharts are an
excellent tool to help visualize how the statements in a program are interrelated. Almost every program
involves the steps of input, processing, and output. Therefore, most flowcharts need some graphical way
to separate these three steps. When you create a flowchart, you draw geometric shapes around the
individual statements and connect them with arrows. When you draw a flowchart, you use a
parallelogram to represent an input symbol, which indicates an input operation. You write an input
statement, in English, inside the parallelogram, as shown in Figure 2-1
28
FIGURE 2-1: INPUT SYMBOL
When you want to represent entering two or more values in a program, you can use one or multiple
flowchart symbols or pseudocode statements—whichever seems more reasonable and clear to you. For
example, the pseudocode to input a user’s name and address might be written as:
get inputName
The first version implies two separate input operations, whereas the second implies a single input
operation retrieving two data items. If your application will accept user input from a keyboard, using two
separate input statements might make sense, because the user will type one item at a time. If your
application will accept data from a storage device, obtaining all the data at once is more common.
Logically, either format represents the retrieval of two data items. The end result is the same in both
cases—after the statements have executed, inputName and inputAddress will have received values from
an input device. Arithmetic operation statements are examples of processing. In a flowchart, you use a
rectangle as the processing symbol that contains a processing statement, as shown in Figure 2-2.
To represent an output statement, you use the same symbol as for input statements—the output symbol
is a parallelogram, as shown in Figure 2-3.
As with input, output statements can be organized in whatever way seems most reasonable.
A program that prints the length and width of a room might use the statement: print length
print width
or:
print length, width
In some programming languages, using two print statements places the output values on two separate
lines on the monitor or printer, whereas using a single print statement places the values next to each
other on the same line. To show the correct sequence of these statements, you use arrows, or flow lines,
29
to connect the steps. Whenever possible, most of a flowchart should read from top to bottom or from
left to right on a page.
To complete, a flowchart should include two more elements: a terminal symbol, or start/stop symbol, at
each end. Often, you place a word like “start” or “begin” in the first terminal symbol and a word like “end”
or “stop” in the other. The standard terminal symbol is shaped like a racetrack; many programmers
refer to this shape as a lozenge, because it resembles the shape of a medicated candy lozenge you might
use to soothe a sore throat. Figure 2-4 shows a complete flowchart for the program that doubles a
number, and the pseudocode for the same problem.
The logic for the program represented by the flowchart and pseudocode in Figure 2-4 is correct no matter
what programming language the programmer eventually uses to write the corresponding code.
After the flowchart or pseudocode has been developed, the programmer only needs to:
buy a computer,
buy a language compiler,
learn a programming language,
code the program,
attempt to compile it,
fix the syntax errors,
compile it again,
test it with several sets of data, and
put it into production.
30
Programmers commonly refer to the locations in memory called inputNumber and calculatedAnswer as
variables. Variables are memory locations, whose contents can vary or differ over time. Sometimes,
inputNumber can hold a 2 and calculatedAnswer will hold a 4; at other times, inputNumber can hold a 6
and calculatedAnswer will hold a 12. It is the ability of memory variables to change in value that makes
computers and programming worthwhile. Because one memory location can be used over and over again
with different values, you can write program instructions once and then use them for thousands of
separate calculations. The number-doubling example requires two variables, inputNumber and
calculatedAnswer. These can just as well be named userEntry and programSolution, or inputValue and
twiceTheValue. As a programmer, you choose reasonable names for your variables. The language
interpreter then associates the names you choose with specific memory addresses.
A variable name is also called an identifier. Every computer programming language has its own set of rules
for naming identifiers. Most languages allow both letters and digits within variable names. Some
languages allow hyphens in variable names—for example, hourly-wage. Others allow underscores, as in
hourly_wage. Still others allow neither. Some languages allow dollar signs or other special characters in
variable names (for example, hourly$); others allow foreign alphabet characters, such as π or Ω.
Even though every language has its own rules for naming variables, when designing the logic of a computer
program, you should not concern yourself with the specific syntax of any particular computer language.
The logic, after all, works with any language. The variable names used throughout this book follow only
two rules:
1. Variable names must be one word. The name can contain letters, digits, hyphens, underscores, or
any other characters you choose, with the exception of spaces. Therefore, r is a legal variable name, as is
rate, as is interestRate. The variable name interest rate is not allowed because of the space. No
programming language allows spaces within a variable name. If you see a name such as interest rate in a
flowchart or pseudocode, you should assume that the programmer is discussing two variables, interest
and rate, each of which individually would be a fine variable name.
2. Variable names should have some appropriate meaning. This is not a rule of any programming
language. When computing an interest rate in a program, the computer does not care if you call the
variable g, u84, or fred. As long as the correct numeric result is placed in the variable, its actual name
doesn’t really matter. However, it’s much easier to follow the logic of a program with a statement in it
like compute finalBalance as equal to initialInvestment time’s interestRate as one with a statement in it
like compute someBanana as equal to j89 times myFriendLinda. You might think you will remember how
you intended to use a cryptic variable name within a program, but several months or years later when a
program requires changes, you, and other programmers working with you, will appreciate clear,
descriptive variable names.
Recall that the logic in the flowchart for doubling numbers has a major flaw—the program never ends.
This programming situation is known as an infinite loop—a repeating flow of logic with no end. If, for
example, the input numbers are being entered at the keyboard, the program will keep accepting
numbers and printing doubles forever. Of course, the user could refuse to type in any more numbers. But
the computer is very patient, and if you refuse to give it any more numbers, it will sit and wait forever.
When you finally type in a number, the program will double it, print the result, and wait for another. The
program cannot progress any further while it is waiting for input; meanwhile, the program is occupying
computer memory and tying up operating system resources. Refusing to enter any more numbers is not
31
a practical solution. Another way to end the program is simply to turn the computer off. But again, that’s
neither the best nor an elegant way to bring the program to an end.
A superior way to end the program is to set a predetermined value for inputNumber that means “Stop
the program!” For example, the programmer and the user could agree that the user will never need to
know the double of 0 (zero), so the user could enter a 0 when he or she wants to stop. The program could
then test any incoming value contained in inputNumber and, if it is a 0, stop the program. Testing a value
is also called making a decision. You represent a decision in a flowchart by drawing a decision symbol,
which is shaped like a diamond. The diamond usually contains a question, the answer to which is one of
two mutually exclusive options—often yes or no. All good computer questions have only two mutually
exclusive answers, such as yes and no or true and false.
One drawback to using 0 to stop a program, of course, is that it won’t work if the user does need to find
the double of 0. In that case, some other data-entry value that the user never will need, such as 999 or –
1, could be selected to signal that the program should end. A preselected value that stops the execution
of a program is often called a dummy value because it does not represent real data, but just a signal to
stop. Sometimes, such a value is called a sentinel value because it represents an entry or exit point, like a
sentinel who guards a fortress.
Not all programs rely on user data entry from a keyboard; many read data from an input device, such as
a disk or tape drive. When organizations store data on a disk or other storage device, they do not
commonly use a dummy value to signal the end of the file. For one thing, an input record might have
hundreds of fields, and if you store a dummy record in every file, you are wasting a large quantity of
storage on “non-data.” Additionally, it is often difficult to choose sentinel values for fields in a
company’s data files.
32
FIGURE 2-5: FLOWCHART FOR NUMBER-DOUBLING PROGRAM WITH SENTINEL VALUE OF 0
Fortunately, programming languages can recognize the end of data in a file automatically, through a code
that is stored at the end of the data. Many programming languages use the term eof (for “end of file”) to
talk about this marker that automatically acts as a sentinel. Therefore, uses eof to indicate the end of
data, regardless of whether the code is a special disk marker or a dummy value such as 0 that comes from
the keyboard.
33
FIGURE 2-6: FLOWCHART USING eof
By using just the input, processing, output, decision, and terminal symbols, you can represent the
flowcharting logic for many diverse applications. When drawing a flowchart segment, you might use
another symbol, the connector. You can use a connector when limited page size forces you to continue a
flowchart in an unconnected location or on another page. If a flowchart has six processing steps and a
page provides room for only three, you might represent the logic as shown in Figure 2-7.
34
FIGURE 2-7: FLOWCHART USING THE CONNECTOR
By convention, programmers use a circle as an on-page connector symbol, and a symbol that looks like a
square with a pointed bottom as an off-page connector symbol. The on-page connector at the bottom of
the left column in Figure 2-7 tells someone reading the flowchart that there is more to the flowchart. The
circle should contain a number or letter that can then be matched to another number or letter somewhere
else, in this case on the right. If a large flowchart needed more connectors, new numbers or letters would
be assigned in sequence (1, 2, 3... or A, B, C...) to each successive pair of connectors. The off-page
connector at the bottom of the right column in Figure 2-7 tells a reader that there is more to the flowchart
on another page. When you are creating your own flowcharts, you should avoid using any connectors, if
at all possible; flowcharts are more difficult to follow when their segments do not fit together on a page.
Some programmers would even say that if a flowchart must connect to another page, it is a sign of poor
design. Your instructor or future programming supervisor may require that long flowcharts be redrawn so
you don’t need to use the connector symbol. However, when continuing to a new location or page is
unavoidable, the connector provides the means.
When you create a flowchart or pseudocode for a program that doubles numbers, you can include the
statement compute calculatedAnswer as inputNumber times 2. This statement incorporates two
actions. First, the computer calculates the arithmetic value of inputNumber times 2. Second, the
computed value is stored in the calculatedAnswer memory location. Most programming languages allow
a shorthand expression for assignment statements such as compute calculatedAnswer as inputNumber
times 2. The shorthand takes the form calculatedAnswer = inputNumber * 2. The equal sign is the
assignment operator; it always requires the name of a memory location on its left side—the name of the
location where the result will be stored.
35
According to the rules of algebra, a statement like calculatedAnswer = inputNumber * 2 should be exactly
equivalent to the statement inputNumber * 2 = calculatedAnswer. That’s because in algebra, the equal
sign always represents equivalency. In most programming languages, however, the equal sign represents
assignment, and calculatedAnswer = inputNumber * 2 means “multiply inputNumber by 2 and store the
result in the variable called calculatedAnswer.” whatever operation is performed to the right of the equal
sign results in a value that is placed in the memory location to the left of the equal sign. Therefore, the
incorrect statement inputNumber * 2 = calculatedAnswer means to attempt to take the value of
calculatedAnswer and store it in a location called inputNumber * 2, but there can’t be a location called
inputNumber * 2. For one thing, you should recognize that the expression inputNumber * 2 can’t be a
variable because it has spaces in it. For another, a location can’t be multiplied. Its contents can be
multiplied, but the location itself cannot be. The backward statement inputNumber * 2 =
calculatedAnswer contains a syntax error, no matter what programming language you use; a program
with such a statement will not execute.
When you create an assignment statement, it may help to imagine the word “let” in front of the
statement. Thus, you can read the statement calculatedAnswerƒ= inputNumberƒ*ƒ2 as “Let
calculatedAnswer equal inputNumber times two.” The BASIC programming language allows you to use
the word “let” in such statements. You might also imagine the word “gets” or “receives” in place of the
assignment operator. In other words, calculatedAnswerƒ=ƒinputNumberƒ*ƒ2 means both
calculatedAnswerƒ gets ƒinputNumberƒ*ƒ2 and calculatedAnswer receives ƒinputNumberƒ*ƒ2.
Many programming languages allow you to create named constants. A named constant is a named
memory location, similar to a variable, except its value never changes during the execution of a
program. If you are working with a programming language that allows it, you might create a constant for
a value such as PIƒ=ƒ3.14 or COUNTY_SALES_TAX_RATEƒ=ƒ.06. Many programmers follow the convention
of using camel casing for variable identifiers but all capital letters for constant identifiers.
Computers deal with two basic types of data—text and numeric. When you use a specific numeric value,
such as 43, within a program, you write it using the digits and no quotation marks. A specific numeric
value is often called a numeric constant, because it does not change—a 43 always has the value 43. When
you use a specific text value, or string of characters, such as “Amanda”, you enclose the string constant,
or character constant, within quotation marks.
Some languages require single quotation marks surrounding character constants, whereas others
require double quotation marks. Many languages, including C++, C#, and Java, reserve single quotes for a
single character such as ‘A’, and double quotes for a character string such as “Amanda”.
Similarly, most computer languages allow at least two distinct types of variables. A variable’s data type
describes the kind of values the variable can hold and the types of operations that can be performed with
it. One type of variable can hold a number, and is often called a numeric variable. A numeric variable is
one that can have mathematical operations performed on it; it can hold digits, and usually can hold a
decimal point and a sign indicating positive or negative if you want. In the statement calculatedAnswer =
inputNumber * 2, both calculatedAnswer and inputNumber are numeric variables; that is, their intended
contents are numeric values, such as 6 and 3, 150 and 75, or –18 and –9.
36
Most programming languages have a separate type of variable that can hold letters of the alphabet and
other special characters such as punctuation marks. Depending on the language, these variables are called
character, text, or string variables. If a working program contains the statement lastName = “Lincoln”,
then lastName is a character or string variable.
Programmers must distinguish between numeric and character variables, because computers handle the
two types of data differently. Therefore, means are provided within the syntax rules of computer
programming languages to tell the computer which type of data to expect. How this is done is different in
every language; some languages have different rules for naming the variables, but with others you must
include a simple statement (called a declaration) telling the computer which type of data to expect.
Some languages allow for several types of numeric data. Languages such as C++, C#, Visual Basic, and Java
distinguish between integer (whole number) numeric variables and floating-point (fractional) numeric
variables that contain a decimal point. Thus, in some languages, the values 4 and 4.3 would be stored in
different types of numeric variables.
Some programming languages allow even more specific variable types, but the character versus numeric
distinction is universal. For the programs you develop in this book, assume that each variable is one of the
two broad types. If a variable called taxRate is supposed to hold a value of 2.5, assume that it is a numeric
variable. If a variable called inventoryItem is supposed to hold a value of “monitor”, assume that it is a
character variable.
Values such as “monitor” and 2.5 are called constants or literal constants because they never change. A
variable value can change. Thus, inventoryItem can hold “monitor” at one moment during the execution
of a program, and later you can change its value to “modem”.
By convention, character data like “monitor” within quotation marks to distinguish the characters from
yet another variable name. Also by convention, numeric data values are not enclosed within quotation
marks.
According to these conventions, then, taxRate = 2.5 and inventoryItem = “monitor” are both valid
statements. The statement inventoryItem = monitor is a valid statement only if monitor is also a character
variable. In other words, if monitor =”color”, and subsequently inventoryItem = monitor, then the end
result is that the memory address named inventoryItem contains the string of characters “color”.
Every computer handles text or character data differently from the way it handles numeric data. You may
have experienced these differences if you have used application software such as spreadsheets or
database programs. For example, in a spreadsheet, you cannot sum a column of words. Similarly, every
programming language requires that you distinguish variables as to their correct type, and that you use
each type of variable appropriately. Identifying your variables correctly as numeric or character is one of
the first steps you have to take when writing programs in any programming language. The process of
naming program variables and assigning a type to them is called making declarations, or declaring
variables. Table 2-1 provides you with a few examples of legal and illegal variable assignment
statements.
37
2.8 UNDERSTANDING THE EVOLUTION OF PROGRAMMING TECHNIQUES
People have been writing computer programs since the 1940s. The oldest programming languages
required programmers to work with memory addresses and to memorize awkward codes associated with
machine languages. Newer programming languages look much more like natural language and are easier
for programmers to use. Part of the reason it is easier to use newer programming languages is that they
allow programmers to name variables instead of using awkward memory addresses. Another reason is
that newer programming languages provide programmers with the means to create self- contained
modules or program segments that can be pieced together in a variety of ways. The oldest computer
programs were written in one piece, from start to finish; modern programs are rarely written that way—
they are created by teams of programmers, each developing his or her own reusable and connectable
program procedures. Writing several small modules is easier than writing one large program, and most
large tasks are easier when you break the work into units and get other workers to help with some of the
units.
Currently, there are two major techniques used to develop programs and their procedures. One
technique, called procedural programming, focuses on the procedures that programmers create. That is,
procedural programmers focus on the actions that are carried out—for example, getting input data for an
employee and writing the calculations needed to produce a paycheck from the data. Procedural
programmers would approach the job of producing a paycheck by breaking down the paycheck- producing
process into manageable subtasks. The other popular programming technique, called object- oriented
38
programming, focuses on objects, or “things,” and describes their features, or attributes, and their
behaviors. For example, object-oriented programmers might design a payroll application by thinking
about employees and paychecks, and describing their attributes (such as last name or check amount) and
behaviors (such as the calculations that result in the check amount).
With either approach, procedural or object-oriented, you can produce a correct paycheck, and both
techniques employ reusable program modules. The major difference lies in the focus the programmer
takes during the earliest planning stages of a project. The skills you gain in programming procedurally—
declaring variables, accepting input, making decisions, producing output, and so on—will serve you well
whether you eventually write programs in a procedural or object-oriented fashion, or in both.
There are two ways to solve the problems any programming languages: top-down and bottom-up. The
problem is broken up into procedures which will call each other, and pass information back and forth
using arguments (input values) and return values (output values). Ideally the arguments and return values
should be the only method of interaction between two procedures. Then when you use a procedure
there’s no need to concern yourself with how it actually works, just what the result is – i.e. you only need
to know about the interface to the procedure, not its internals. That is, you can think of the procedure as
a “black box” that takes one or more input values, performs some process on them, and produces one or
more output values. In programming this is particularly important when it comes to testing, working as
part of a large programming team, or when trying out different ways of implementing a procedure – as it
allows each procedure to be dealt with in isolation, whilst still giving some degree of confidence that they
will operate as expected when all connected together.
Top-Down Approach
The top-down approach is the most useful when the overall problem is known in advance, but the intricate
detail isn’t. Start by splitting the whole problem into slightly smaller, slightly better defined, procedures,
then keep splitting each of these into even smaller, even better defined, procedures – until you get to a
point where the procedures contain very specific low-level steps that you know how to perform. The key
to top-down problem solving is:
Break the problem down into smaller and smaller problems.
Look for parts of the problem which are sufficiently similar to each other that they can be replaced
by a generalised procedure that uses one or more arguments to specify how it behaves.
Bottom-Up
The bottom-up approach is most useful when the low-level details of the problem are known in
advance, but the overall problem isn’t necessarily. You start by taking procedures that you have already
developed (reusing them), and connecting them together so as to produce a new procedure that solves a
more complex problem. These new procedures can then be combined to produce solutions to yet more
complex problems, and so on. The key to bottom-up problem solving is:
Reuse procedures that you have already devised.
Combine them in different ways to solve more complex problems than they were originally designed
for.
Algorithms
Algorithm is the name for a formal description of how to go about solving a problem. An algorithm is a
finite list of instructions, based on a finite set of atomic commands, which specifically relate to the actions
39
of some device and are executed in a definite, consistent, order. Usually, to be of use, an algorithm must
finish executing in a finite time. This means that:
An algorithm must have a beginning and an end – otherwise we wouldn’t know where to start and
stop.
The commands must be as basic as possible – there must be no room for interpretation (either
through experience, or guesswork) as there might be with, say, the recipe for baking a cake.
The number of possible instructions is limited – otherwise it would take forever to determine what
each instruction means.
There must be some practical mechanism capable of executing the algorithm; otherwise it is of no
use.
We must be sure that the instructions will be executed in the same order every time the
algorithm operates, otherwise its behaviour will be completely unpredictable.
Usually we want the algorithm to have an outcome – so it must come to an end at some point.
However this is not always the case, e.g. an algorithm for monitoring a system should probably
operate “forever”.
Flow Charts
In a few weeks we will be describing algorithms using high level programming languages like C, and C++.
Often it is not a good idea to start thinking about an algorithm using a programming language, as they
require you to be very precise about the description, and the process of getting the program exactly right
(debugging it) can get in the way of formulating the algorithm. Initially it is much better to use a less
formal description, such as a flow chart. Flow charts provide a convenient graphical way of
describing how an algorithm works. The symbols are used as follows:
Start/End: Used for the start and end points of the algorithm as a whole, or of one of its procedures.
Usually there can only be one start point, but there may be more than one end point (and there should
be at least one of each).
Process: Any processing that the algorithm does. This could be a specific calculation, or it could be
something quite vague that you haven’t figured out how to describe in detail yet.
Input/ Output: Any point where data flows into, or out of, the algorithm (possibly both at the same time).
Connector: Crossing flow lines in a flow chart leads to confusion, so use numbered connector symbols to
jump around complicated diagrams as necessary (N.B. there shouldn’t be more than two connectors with
the same number).
TOPIC SUMMARY
40
When data items are stored for use on computer systems, they are stored in a data hierarchy of
character, field, record, file, and database.
When programmers plan the logic for a solution to a programming problem, they often use
flowcharts or pseudocode. When you draw a flowchart, you use parallelograms to represent input
and output operations, and rectangles to represent processing.
Variables are named memory locations, the contents of which can vary. As a programmer, you
choose reasonable names for your variables. Every computer programming language has its own
set of rules for naming variables; however, all variable names must be written as one word without
embedded spaces, and should have appropriate meaning.
Testing a value involves making a decision. You represent a decision in a flowchart by drawing a
diamond-shaped decision symbol containing a question, the answer to which is either yes or no.
You can stop a program’s execution by using a decision to test for a sentinel value.
A connector symbol is used to continue a flowchart that does not fit together on a page, or must
continue on an additional page.
Most programming languages use the equal sign to assign values to variables. Assignment always
takes place from right to left.
Programmers must distinguish between numeric and character variables, because computers
handle the two types of data differently. A variable declaration tells the computer which type of
data to expect. By convention, character data values are included within quotation marks.
Procedural and object-oriented programmers approach program problems differently. Procedural
programmers concentrate on the actions performed with data. Object-oriented programmers
focus on objects and their behaviors and attributes.
KEY TERMS
The data hierarchy represents the relationship of databases, files, records, fields, and characters.
Characters are letters, numbers, and special symbols such as “A”, “7”, and “$”.
A field is a single data item, such as lastName, streetAddress, or annualSalary.
Records are groups of fields that go together for some logical reason.
Files are groups of records that go together for some logical reason.
A database holds a group of files, often called tables, which together serve the information needs of
an organization.
Queries are questions that pull related data items together from a database in a format that
enhances efficient management decision making.
A flowchart is a pictorial representation of the logical steps it takes to solve a problem.
Pseudocode is an English-like representation of the logical steps it takes to solve a problem.
Input symbols, which indicate input operations, are represented as parallelograms in flowcharts.
Processing symbols are represented as rectangles in flowcharts.
Output symbols, which indicate output operations, are represented as parallelograms in
flowcharts.
Flow lines, or arrows, connect the steps in a flowchart.
A terminal symbol, or start/stop symbol, is used at each end of a flowchart. Its shape is a lozenge.
Variables are memory locations, whose contents can vary or differ over time.
41
A variable name is also called an identifier.
A mnemonic is a memory device; variable identifiers act as mnemonics for hard-to-remember
memory addresses.
Camel casing is the format for naming variables in which multiple-word variable names are run
together, and each new word within the variable name begins with an uppercase letter.
An infinite loop is a repeating flow of logic without an ending.
Testing a value is also called making a decision.
You represent a decision in a flowchart by drawing a decision symbol, which is shaped like a
diamond.
A yes-or-no decision is called a binary decision, because there are two possible outcomes.
A dummy value is a preselected value that stops the execution of a program. Such a value is
sometimes called a sentinel value because it represents an entry or exit point, like a sentinel who
guards a fortress.
Many programming languages use the term eof (for “end of file”) to talk about an end-of-data file
marker.
A connector is a flowchart symbol used when limited page size forces you to continue the flowchart
elsewhere on the same page or on the following page.
An assignment statement stores the result of any calculation performed on its right side to the
named location on its left side.
The equal sign is the assignment operator; it always requires the name of a memory location on its
left side.
A numeric constant is a specific numeric value.
A string constant, or character constant, is enclosed within quotation marks.
A variable’s data type describes the kind of values the variable can hold and the types of
operations that can be performed with it.
Numeric variables hold numeric values.
Character, text, or string variables hold character values. If a working program contains the
statement lastName = “Lincoln”, then lastName is a character or string variable.
A declaration is a statement that names a variable and tells the computer which type of data to
expect.
Integer values are whole-number, numeric variables.
Floating-point values are fractional, numeric variables that contain a decimal point.
The process of naming program variables and assigning a type to them is called making
declarations, or declaring variables.
The technique known as procedural programming focuses on the procedures that programmers
create.
The technique known as object-oriented programming focuses on objects, or “things,” and
describes their features, or attributes, and their behaviors.
42
1. Which of the following is a typical input instruction?
A. get accountNumber
B. calculate balanceDue
C. print customerIdentificationNumber
D. total = janPurchase + febPurchase
5. Which of the following is not a legal variable name in any programming language?
A. semester grade B. fall2005_grade
C. GradeInCIS100
D. MY_GRADE
43
Since the early days of computer programming, program errors have been called “bugs.” The term is often
said to have originated from an actual moth that was discovered trapped in the circuitry of a computer at
Harvard University in 1945. Actually, the term “bug” was in use prior to 1945 to mean trouble with any
electrical apparatus; even during Thomas Edison’s life, it meant an “industrial defect.” However, the
process of finding and correcting program errors has come to be known as debugging. Each of the
following pseudocode segments contains one or more bugs that you must find and correct.
1. This pseudocode segment is intended to describe computing your average score of two classroom
tests.
input midtermGrade input
finalGrade
average = (inputGrade + final) / 3 print
average
2. This pseudocode segment is intended to describe computing the number of miles per gallon you
get with your automobile.
input milesTraveled input
gallonsOfGasUsed
gallonsOfGasUsed /
milesTravelled =
milesPerGallon print
milesPerGal
3. This pseudocode segment is intended to describe computing the cost per day and the cost per
week for a vacation. input totalDollarsSpent input daysOnTrip
costPerDay = totalMoneySpent * daysOnTrip weeks
= daysOnTrip / 7
costPerWeek = daysOnTrip / numberOfWeeks print
costPerDay, week
EXERCISES
44
4. Would this set of data be suitable and sufficient to use to test each of the following programs?
Explain why or why not.
a. a program that prints a list of Psychology majors
b. a program that prints a list of Art majors
c. a program that prints a list of students on academic probation—those with a grade point
average under 2.0
d. a program that prints a list of students on the dean’s list
e. a program that prints a list of students from Wisconsin
f. a program that prints a list of female students
5. Suggest a good set of test data to use for a program that gives an employee a $50 bonus check if the
employee has produced more than 1,000 items in a week.
6. Suggest a good set of test data for a program that computes gross paychecks (that is, before any
taxes or other deductions) based on hours worked and rate of pay. The program computes gross as
hour’s times rate, unless hours are over 40. If so, the program computes gross as regular rate of pay
for 40 hours, plus one and a half times the rate of pay for the hours over 40.
7. Suggest a good set of test data for a program that is intended to output a student’s grade point
average based on letter grades (A, B, C, D, or F) in five courses.
8. Suggest a good set of test data for a program for an automobile insurance company that wants to
increase its premiums by $50 per month for every ticket a driver receives in a three-year period.
9. Assume that a grocery store keeps a file for inventory, where each grocery item has its own record.
two fields within each record are the name of the manufacturer and the weight of the item. Name
at least six more fields that might be stored for each record. Provide an example of the data for one
record. For example, for one product the manufacturer is Del Monte, and the weight is 12 ounces.
10. Assume that a library keeps a file with data about its collection, one record for each item the library
lends out. Name at least eight fields that might be stored for each record. Provide an example of the
data for one record.
45
11. Which of the following names seem like good variable names to you? If a name doesn’t seem like a
good variable name, explain why not.
A. c
B. cost
C. costAmount
D. cost amount
E. cstofdngbsns
F. costOfDoingBusinessThisFiscalYear
G. cost2004
12. If myAge and yourRate are numeric variables, and departmentCode is a character variable, which of
the following statements are valid assignments? If a statement is not valid, explain why not. A.
myAge = 23
B. myAge = yourRate
C. myAge = departmentCode
D. myAge = “departmentCode”
E. 42 = myAge
F. yourRate = 3.5
G. yourRate = myAge
H. yourRate = departmentCode
I. 6.91 = yourRate
J. departmentCode = Personnel
K. departmentCode = “Personnel”
L. departmentCode = 413
M. departmentCode = “413”
N. departmentCode = myAge
O. departmentCode = yourRate
46
P. 413 = departmentCode
Q. “413” = departmentCode
3. UNDERSTANDING STRUCTURE
LEARNING OUTCOMES
After Studying this topic you should be able to:
Describe the three basic structures—sequence, selection, and loop
Understand the need for structure
Describe three special structures—case, do-while, and do-until
47
3.1 UNDERSTANDING THE THREE BASIC STRUCTURES
In the mid-1960s, mathematicians proved that any program, no matter how complicated, can be
constructed using one or more of only three structures. A structure is a basic unit of programming logic;
each structure is a sequence, selection, or loop. With these three structures alone, you can diagram any
task, from doubling a number to performing brain surgery. You can diagram each structure with a specific
configuration of flowchart symbols.
The first of these structures is a sequence, as shown in Figure 3.1. With a sequence structure, you perform
an action or task, and then you perform the next action, in order. A sequence can contain any number of
tasks, but there is no chance to branch off and skip any of the tasks. Once you start a series of actions in
a sequence, you must continue step-by-step until the sequence ends.
The second structure is called a selection structure or decision structure, as shown in Figure 3-2. With this
structure, you ask a question, and, depending on the answer, you take one of two courses of action.
Then, no matter which path you follow, you continue with the next task.
The previous examples can also be called dual-alternative ifs, because they contain two alternatives— the
action taken when the tested condition is true and the action taken when it is false. Note that it is perfectly
correct for one branch of the selection to be a “do nothing” branch. For example: if it is raining then take
anUmbrella or
if employee belongs to dentalPlan then deduct
$40 from employeeGrossPay
The previous examples are single-alternative ifs, and a diagram of their structure is shown in Figure 3-3.
In these cases, you don’t take any special action if it is not raining or if the employee does not belong to
the dental plan. The case where nothing is done is often called the null case.
49
Some programmers call this structure a while...do, or more simply, a while loop, because it fits the following
statement:
All logic problems can be solved using only these three structures—sequence, selection, and loop. The
three structures, of course, can be combined in an infinite number of ways. For example, you can have a
sequence of tasks followed by a selection, or a loop followed by a sequence. Attaching structures end- to-
end is called stacking structures.
For example, Figure 3-5 shows a structured flowchart achieved by stacking structures, and shows
pseudocode that might follow that flowchart logic.
50
The pseudocode in Figure 3-5 shows two end-structure statements—endif and endwhile. You can use an
endif statement to clearly show where the actions that depend on a decision end. The instruction that
follows if occurs when its tested condition is true, the instruction that follows else occurs when the tested
condition is false, and the instruction that follows endif occurs in either case—it is not dependent on the
if statement at all. In other words, statements beyond the endif statement are “outside” the decision
structure. Similarly, you use an endwhile statement to show where a loop structure ends.
In Figure 3-5, while conditionF continues to be true, stepG continues to execute. If any statements followed
the endwhile statement, they would be outside of, and not a part of, the loop.
Besides stacking structures, you can replace any individual tasks or steps in a structured flowchart diagram
or pseudocode segment with additional structures. In other words, any sequence, selection, or loop can
contain other sequences, selections, or loops. For example, you can have a sequence of three tasks on
one side of a selection, as shown in Figure 3-6. Placing a structure within another structure is called nesting
the structures.
FIGURE 3-6: FLOWCHART AND PSEUDOCODE SHOWING A SEQUENCE NESTED WITHIN A SELECTION
When you write the pseudocode for the logic shown in Figure 3-6, the convention is to indent all
statements that depend on one branch of the decision, as shown in the pseudocode. The indentation and
the endif statement both show that all three statements (do stepB, do stepC, and do stepD) must execute
if conditionA is not true.
The three statements constitute a block, or a group of statements that execute as a single unit.
In place of one of the steps in the sequence in Figure 3-6, you can insert a selection. In Figure 3-7, the
process named stepC has been replaced with a selection structure that begins with a test of the
condition named conditionF.
51
FIGURE 3-7: SELECTION IN A SEQUENCE WITHIN A SELECTION
In the pseudocode shown in Figure 3-7, notice that do stepB, if conditionF is true then, else, endif, and do
stepD all align vertically with each other. This shows that they are all “on the same level.” If you look at
the same problem flowcharted in Figure 3-7, you see that you could draw a vertical line through the
symbols containing stepB, conditionF, and stepD. The flowchart and the pseudocode represent exactly
the same logic. The stepH and stepG processes, on the other hand, are one level “down”; they are
dependent on the answer to the conditionF question. Therefore, the do stepH and do stepG statements
are indented one additional level in the pseudocode.
Also notice that the pseudocode in Figure 3-7 has two endif statements. Each is aligned to correspond to
an if. An endif always partners with the most recent if that does not already have an endif partner, and an
endif should always align vertically with its if partner.
In place of do stepH on one side of the new selection in Figure 3-7, you can insert a loop. This loop, based
on conditionI, appears inside the selection that is within the sequence that constitutes the “No” side of
the original conditionA selection. In the pseudocode in Figure 3-8, notice that the while aligns with the
endwhile, and that the entire while structure is indented within the true (“Yes”) half of the if structure
that begins with the decision based on conditionF. The indentation used in the pseudocode reflects the
logic you can see laid out graphically in the flowchart.
52
FIGURE 3-8: FLOWCHART AND PSEUDOCODE FOR LOOP WITHIN SELECTION WITHIN SEQUENCE WITHIN SELECTION
The combinations are endless, but each of a structured program’s segments is a sequence, a selection, or
a loop. The three structures are shown together in Figure 3-9. Notice that each structure has one entry
and one exit point. One structure can attach to another only at one of these points.
53
Structures can be stacked or connected to one another only at their entry or exit points. Any
structure can be nested within another structure.
A structured program is never required to contain examples of all three structures; a structured program
might contain only one or two of them. For example, many simple programs contain only a sequence of
several tasks that execute from start to finish without any needed selections or loops.
The reasons for using only the three structures— sequence, selection, and loop. However, staying with
these three structures is better for the following reasons:
Clarity—the number-doubling program is a small program. As programs get bigger, they get more
confusing if they’re not structured.
Professionalism—All other programmers (and programming teachers you might encounter) expect your
programs to be structured. It’s the way things are done professionally.
Efficiency—most newer computer languages are structured languages with syntax that lets you deal
efficiently with sequence, selection, and looping. Older languages, such as assembly languages,
COBOL, and RPG, were developed before the principles of structured programming were
discovered. However, even programs that use those older languages can be written in a structured
form, and structured programming is expected on the job today. Newer languages such as C#, C++,
and Java enforce structure by their syntax.
Maintenance—You, as well as other programmers, will find it easier to modify and maintain
structured programs as changes are required in the future.
Modularity—structured programs can be easily broken down into routines or modules that can be
assigned to any number of programmers. The routines are then pieced back together like modular
furniture at each routine’s single entry or exit point. Additionally, often a module can be used in
multiple programs, saving development time in the new project.
Consider the college admissions program from the beginning of this chapter. It has been rewritten in structured
form in Figure 3-10 and is easier to foIIow now. Figure 3-10 also shows structured pseudocode forthe
same probIem.
54
start
read testscore, classRank
lf testscore >= 90 then
1£ classRank >= 25 then print
•Accept"
else
print •Re)ect" endlf
else
1£ testscore >= 80 then 1£
classRank >= SO then print " Accept ..
else
print " ReJect • endlf
else
1£ testscore >= 70 then
1£ classRank >= 75 then print •Accept"
else
print •ReJect" endlf
else
print " ReJect •
endlf
endlf
ru!lesiSoore,ClassRlr1k
I l
•tesiScor e > = 90tllell
C13SS11MK >= 25 men
1pnm """"''
else
I
endif 1..£!!1!-H-
else I
if testSccn >= so then
nclassR:!nk >= so then
I else
l llfint "Reieci
endn
..:;::_-
55
-
else
n testScore >= 70 then
n d3ssRook>= 75t11e11
l pnnt •ACcepr
elSe
1pmt -t<e)eCr
eooif
endn
endd
en«<H
endlf
stop
56
3.3 THREE SPECIAL STRUCTURES— CASE, DO WHILE, AND DO UNTIL
You can solve any logic problem you might encounter using only the three structures: sequence, selection,
and loop. However, many programming languages allow three more structures: the case structure and
the do-while and do-until loops. These structures are never needed to solve any problem— you can always
use a series of selections instead of the case structure, and you can always use a sequence plus a while
loop in place of the do-while or do-until loops. However, sometimes these additional structures are
convenient. Programmers consider them all to be acceptable, legal structures.
You can use the case structure when there are several distinct possible values for a single variable you are
testing, and each value requires a different course of action. Suppose you administer a school at which
tuition is $75, $50, $30, or $10 per credit hour, depending on whether a student is a freshman, sophomore,
junior, or senior. The structured flowchart and pseudocode in Figure 3-11 show a series of decisions that
assigns the correct tuition to a student.
The logic shown in Figure 3-11 is absolutely correct and completely structured. The class=”Junior”
selection structure is contained within the class=”Sophomore” structure, which is contained within the
class=”Freshman” structure. Note that there is no need to ask if a student is a senior, because if a student
is not a freshman, sophomore, or junior, it is assumed the student is a senior.
Even though the program segments in Figure 3-11 are correct and structured, many programming
languages permit using a case structure, as shown in Figure 3-12. When using the case structure, you test
a variable against a series of values, taking appropriate action based on the variable’s value. To many, such
programs seem easier to read, and the case structure is allowed because the same results could be
achieved with a series of structured selections (thus making the program structured). That is, if the first
program is structured and the second one reflects the first one point by point, then the second one must
be structured also.
57
FIGURE 3-12: FLOWCHART AND PSEUDOCODE OF CASE STRUCTURE
When you write a series of decisions using the case structure, the computer still makes a series of individual
decisions, just as though you had used many if-then-else combinations.
Recall that a structured loop (often called a while loop) looks like Figure 3-13. A special-case loop called a
do-while or do-until loop looks like Figure 3-14.
FIGURE 3-13: WHILE LOOP FIGURE 3-14: STRUCTURE OF A DO-WHILE OR DO-UNTIL (POSTTEST) LOOP
An important difference exists between these two structures. In a while loop, you ask a question and,
depending on the answer, you might or might not enter the loop to execute the loop’s procedure.
Conversely, in do-while and do-until loops, you ensure that the procedure executes at least once; then,
depending on the answer to the controlling question, the loop may or may not execute additional times.
In a do-while loop, the loop body continues to execute as long as the answer to the controlling question
is yes, or true. In a do-until loop, the loop body continues to execute as long as the answer to the
controlling question is no, or false; that is, the body executes until the controlling question is yes or true.
In a while loop, the question that controls a loop comes at the beginning, or “top,” of the loop body. A
while loop is also called a pre-test loop because a condition is tested before entering the loop even once.
In a do-while or do-until loop, the question that controls the loop comes at the end, or “bottom,” of the
loop body. Do-while and do-until loops are also called post-test loops because a condition is tested after
the loop body has executed.
58
Examples of do-until looping:
do
pay bills
until all bills are paid
and do wash dishes
until all dishes are washed
Similarly, you encounter examples of do-while looping every day. For example:
do
pay bills
while more bills remain to be paid
and do wash dishes
while more dishes remain to be washed
In these examples, the activity (paying bills or washing dishes) must occur at least one time. You ask the
question that determines whether you continue only after the activity has been executed at least once.
The only difference in these structures is whether the answer to the bottom loop-controlling question
must be false for the loop to continue (as in all bills are paid), which is a do-until loop, or true for the loop
to continue (as in more bills remain to be paid), which is a do-while loop.
You are never required to use a post-test loop. You can duplicate the same series of actions generated by
any post-test loop by creating a sequence followed by a standard, pre-test while loop. For example, the
following code performs the bill-paying task once, then asks the loop-controlling question at the top of a
while loop, in which the action might be performed again:
pay bills
while there are more bills to pay pay
bills
endwhile
Consider the flowcharts and pseudocode in Figures 3-15 and 3-16. In Figure 3-15, A is done, and then B is
asked. If B is yes, then A is done and B is asked again. In Figure 3-16, A is done, and then B is asked. If B is
yes, then A is done and B is asked again. In other words, both flowcharts and pseudocode segments do
exactly the same thing.
59
FIGURE 3-15: FLOWCHART AND PSEUDOCODE FOR DO-WHILE LOOP
FIGURE 3-16: FLOWCHART AND PSEUDOCODE FOR SEQUENCE FOLLOWED BY WHILE LOOP
Because programmers understand that any post-test loop (do-while or do-until) can be expressed with a
sequence followed by a while loop, most languages allow the post-test loop. (Frequently, languages allow
one type of post-test loop or the other.) Again, you are never required to use a post-test loop; you can
always accomplish the same tasks with a sequence followed by a pre-test while loop.
Figure 3-17 shows an unstructured loop. It is neither a while loop (which begins with a decision and, after
an action, returns to the decision) nor a do-while or do-until loop (which begins with an action and ends
with a decision that might repeat the action). Instead, it begins like a post-test loop (a do-while or a do-
until loop), with a process followed by a decision, but one branch of the decision does not repeat the initial
process; instead, it performs an additional new action before repeating the initial process. If you need to
use the logic shown in Figure 3-17—performing a task, asking a question, and perhaps performing an
additional task before looping back to the first process—then the way to make the logic structured is to
repeat the initial process within the loop, at the end of the loop. Figure 3-18 shows the same logic as
Figure 3-17, but now it is structured logic, with a sequence of two actions occurring within the loop.
60
FIGURE 3-18: SEQUENCE AND STRUCTURED LOOP THAT ACCOMPLISH THE SAME TASKS AS FIGURE 3-17
TOPIC SUMMARY
KEY TERMS
61
An if-then-else is another name for a selection structure.
Dual-alternative ifs define one action to be taken when the tested condition is true, and another
action to be taken when it is false.
Single-alternative ifs take action on just one branch of the decision.
The null case is the branch of a decision in which no action is taken.
With a loop structure, you continue to repeat actions based on the answer to a question.
Repetition and iteration are alternate names for a loop structure.
A while...do, or more simply, a while loop, is a loop in which a process continues while some condition
continues to be true.
Attaching structures end-to-end is called stacking structures.
Placing a structure within another structure is called nesting the structures.
A block is a group of statements that execute as a single unit.
A priming read or priming input is the statement that reads the first input data record prior to starting
a structured loop.
You can use the case structure when there are several distinct possible values for a single variable
you are testing, and each requires a different course of action.
In do-while and do-until loops, you ensure that a procedure executes at least once; then,
depending on the answer to the controlling question, the loop may or may not execute
additional times.
A while loop is also called a pre-test loop because a condition is tested before entering the loop even
once.
Do-while and do-until loops are also called post-test loops because a condition is tested after the loop
body has executed.
REVIEW QUESTIONS
8. The statement while temperature remains below 60, leave the furnace on is an example of a . A.
single-alternative if
B. loop
C. dual-alternative if
D. sequence
9. The statement if age < 13 then movieTicket = 4.00 else movieTicket = 8.50 is an example of a . A.
single-alternative if
B. loop
C. dual-alternative if
D. sequence
10. Which of the following attributes do all three basic structures share? A. Their flowcharts all contain
exactly three processing symbols.
B. They all contain a decision.
C. They all begin with a process. D. They all
have one entry and one exit point.
11. When you read input data in a loop within a program, the input statement that precedes the loop. A.
is called a priming input
63
B. cannot result in eof
C. is the only part of a program allowed to be unstructured
D. executes hundreds or even thousands of times in most business programs
14. Which of the following is not a reason for enforcing structure rules in computer programs? A.
Structured programs are clearer to understand than unstructured ones. B. Other professional
programmers will expect programs to be structured.
C. Structured programs can be broken down into modules easily.
D. Structured programs usually are shorter than unstructured ones.
15. Which of the following is not a benefit of modularizing programs?
A. Modular programs are easier to read and understand than non-modular ones.
B. Modular components are reusable in other programs.
C. If you use modules, you can ignore the rules of structure. D. Multiple programmers can work on
different modules at the same time.
17. The structure that you can use when you must make a decision with several possible outcomes,
depending on the value of a single variable, is the.
A. multiple-alternative if structure
B. case structure
C. do-while structure
D. do-until structure
18. Which type of loop ensures that an action will take place at least one time? A. a do-until loop B. a
while loop
C. a do-over loop
D. any structured loop
Each of the following pseudocode segments contains one or more errors that you must find and correct.
1. This pseudocode segment is intended to describe determining whether you have passed or
failed a course based on the average score of two classroom tests.
input midtermGrade input
finalGrade
average = (midGrade+ finalGrade) /2
print avg if average >=60 then
print “Pass”
endif else
print “Fail”
2. This pseudocode segment is intended to describe computing the number of miles per gallon you
get with your automobile. The program segment should continue as long as the user enters a positive
value for miles travelled.
input gallonsOfGasUsed
input milesTraveled while
milesTraveled>0
milesPerGallon=gallonsOfGasUsed/milesTraveled print
milesPerGal
endwhile
3. This pseudocode segment is intended to describe computing the cost per day for a vacation. The
user enters a value for total dollars available to spend and can continue to enter new dollar amounts
while the amount entered is not 0. For each new amount entered, if the amount of money available
to spend per day is below $100, a message displays.
input totalDollarsAvailable while
totalDollarsAvailable not = 0
dollarsPerDay = totalMoneyAvailable / 7
print dollarsPerDay
endwhile
input totalDollarsAvailable if
dollarsPerDay > 100 then
print “You better search for a bargain vacation” endwhile
65
TOPIC 4
4. MODULARIZATION
LEARNING OUTCOMES
After Studying this topic you should be able to:
Describe the advantages of modularization
Modularize a program
Understand how a module can call another module
Explain how to declare variables
Programmers seldom write programs as one long series of steps. Instead, they break down the
programming problem into reasonable units, and tackle one small task at a time. These reasonable units
are called modules. Programmers also refer to them as subroutines, procedures, functions, or methods.
The name that programmers use for their modules usually reflects the programming language they use.
For example, Visual Basic programmers use “procedure” (or “sub procedure”). C and C++ programmers
call their modules “functions,” whereas C#, Java, and other object-oriented language programmers are
more likely to use “method.”
The process of breaking down a large program into modules is called modularization. You are never required
to break down a large program into modules, but there are at least four reasons for doing so:
Modularization provides abstraction.
Modularization allows multiple programmers to work on a problem.
Modularization allows you to reuse your work.
Modularization makes it easier to identify structures.
One reason modularized programs are easier to understand is that they enable a programmer to see the
big picture. Abstraction is the process of paying attention to important properties while ignoring
nonessential details. Abstraction is selective ignorance.
When you dissect any large task into modules, you gain the ability to divide the task among various people.
Rarely does a single programmer write a commercial program that you buy. Consider any word-
processing, spread sheet, or database program you have used. Each program has so many options, and
responds to user selections in so many possible ways, that it would take years for a single programmer to
write all the instructions. Professional software developers can write new programs in weeks or months,
instead of years, by dividing large programs into modules and assigning each module to an individual
programmer or programming team.
66
4.3 MODULARIZATION ALLOWS YOU TO REUSE YOUR WORK
If a subroutine or function is useful and well-written, you may want to use it more than once within a
program or in other programs. For example, a routine that checks the current date to make sure it is valid
(the month is not lower than 1 or higher than 12, the day is not lower than 1 or higher than 31 if the month
is 1, and so on) is useful in many programs written for a business. A program that uses a personnel file
containing each employee’s birth date, hire date, last promotion date, and termination date can use the
date-validation module four times with each employee record. Other programs in an organization can also
use the module; these include programs that ship customer orders, and calculate when loan payments
should be made. If you write the date-checking instructions so they are entangled with other statements
in a program, they are difficult to extract and reuse. On the other hand, if you place the instructions in
their own module, the unit is easy to use and portable to other applications. The feature of modular
programs that allows individual modules to be used in a variety of applications is known as reusability.
You can find many real-world examples of reusability. Software that is reusable is more reliable. Reliability
is the feature of programs that assures you a module has been tested and proven to function correctly.
Reliable software saves time and money. If you create the functional components of your programs as
stand-alone modules and test them in your current programs, much of the work will already be done when
you use the modules in future applications.
When you combine several programming tasks into modules, it may be easier for you to identify
structures. For example, the selection structure looks like Figure 4-1. When you work with a program
segment that looks like Figure 4-2, you may question whether it is structured. If you can modularize some
of the statements and give them a more abstract group name, as in Figure 4-3, it is easier to see that the
program involves a major selection (whether the hours value is greater than 40) that determines
the type of pay (regular or overtime). In Figure 4-3, it is also easier to see that the program segment is
structured.
67
FIGURE 4-2: SECTION OF LOGIC FROM A PAYROLL PROGRAM
The single program segment shown in Figure 4-2 accomplishes the same steps as the two program
segments shown together in Figure 4-3; both program segments are structured. The structure may be
more obvious in the program segments in Figure 4-3 because you can see two distinct parts—a decision
structure calls a subroutine named overtimeModule (), and that module contains another decision
structure, which is followed by a sequence. Neither of the program segments shown in Figures 4-2 and 4-
3 is superior to the other in terms of functionality, but you may prefer to modularize to help you identify
structures.
Most programs contain a main module which contains the mainline logic; this module then accesses other
modules or subroutines. When you create a module or subroutine, you give it a name. The rules for
naming modules are different in every programming language, but they often are similar to the language’s
rules for variable names. In this text, module names follow the same two rules used for variable names:
Module names must be one word.
Module names should have some meaning.
Additionally, module names are followed by a set of parentheses. This will help you distinguish module
names from variable names. This style corresponds to the way modules are named in many
programming languages, such as Java, C++, and C#.
68
Table 4-1 lists some possible module names for a module that calculates an employee’s gross pay, and
provides a rationale for the appropriateness of each one.
TABLE 4-1: VALID AND INVALID MODULE NAMES FOR A MODULE THAT CALCULATES AN EMPLOYEE’S GROSS PAY
Any variables enclosed in the parentheses contain information you want to send to the module. For now,
the parentheses we use at the end of module names will be empty. Most programming languages require
that module names begin with an alphabetic character.
Although it is not a requirement of any programming language, it frequently makes sense to use a verb as
all or part of a module’s name, because modules perform some action. Typical module names begin with
words such as get, compute, and print.
When a program or module uses another module, you can refer to the main program as the calling
program (or calling module), because it “calls” the module’s name when it wants to use the module. The
flowchart symbol used to call a module is a rectangle with a bar across the top. You place the name of the
module you are calling inside the rectangle.
When one module calls another, the called module is a submodule. Instead of placing only the name of
the module they are calling in the flowchart, many programmers insert an appropriate verb, such as
“perform” or “do,” before the module name. These verbs help clarify that the module represents an action
to be carried out. A module can call another module, and the called module can call another. The number
of chained calls is limited only by the amount of memory available on your computer.
You draw each module separately with its own sentinel symbols. The symbol that is the equivalent of the
start symbol in a program contains the name of the module. This name must be identical to the name
used in the calling program. The symbol that is the equivalent of the stop symbol in a program does not
contain “stop”; after all, the program is not ending. Instead, the module ends with a “gentler,” less final
term, such as exit or return. These words correctly indicate that when the module ends, the logical
progression of statements will return to the calling program.
A flowchart and pseudocode for a program that calculates the arithmetic average of two numbers a user
enters can look like Figure 4-4. Here the main program, or program that runs from start to stop and calls
other modules, calls three modules: getInput(), calculateAverage(), and printResult().
70
FIGURE 4-4: FLOWCHART AND PSEUDOCODE FOR AVERAGING PROGRAM WITH MODULES
Whenever a main program calls a module, the logic transfers to the module. When the module ends, the
logical flow transfers back to the main calling program and resumes where it left off. The computer keeps
track of the correct memory address to which it should return after executing a module by recording the
memory address in a location known as the stack.
Just as a program can call a module or subroutine, any module can call another module. For example, the
program illustrated in Figure 4-4 can be broken down further, as shown in Figure 4-5.
71
FIGURE 4-5: FLOWCHART AND PSEUDOCODE FOR AVERAGING PROGRAM WITH SUBMODULES
72
Determining when to break down any particular module into its own subroutines or submodules is an art.
Programmers do follow some guidelines when deciding how far to break down subroutines, or how much
to put in each of them. Some companies may have arbitrary rules, such as “a subroutine should never take
more than a page,” or “a module should never have more than 30 statements in it,” or “never have a
method or function with only one statement in it.” Rather than use such arbitrary rules, a better policy is
to place together statements that contribute to one specific task. The more the statements contribute to
the same job, the greater the functional cohesion of the module. A routine that checks the validity of a
date variable’s value, or one that prompts a user and allows the user to type in a value, is considered
cohesive. A routine that checks date validity, deducts insurance premiums, and computes federal
withholding tax for an employee would be less cohesive.
The primary work of most modules in most programs you write is to manipulate data—for example, to
calculate the figures needed for a paycheck, customer bill, or sales report. You store your program data in
variables. Many program languages require you to declare all variables before you use them.
Declaring a variable involves providing a name for the memory location where the computer will store the
variable value, and notifying the computer of what type of data to expect. Every programming language
requires that you follow specific rules when declaring variables, but all the rules involve identifying at least
two attributes for every variable:
You must declare a data type.
You must give the variable a name.
Different programming languages provide different variable types, but that all allow at least the distinction
between character and numeric data. Two data types—num, which holds number values, and char, which
holds all other values, including those that contain letters and combinations of letters and numbers.
Variable names must not contain spaces, statements such as char lastName and num weeklySalary to
declare two variables of different types.
Some programming languages, such as Visual Basic and BASIC, do not require you to name any variable
until the first time you use it. However, other languages, including COBOL, C++, C#, and Java, require that
you declare variables with a name and a data type. Some languages require that you declare all variables
at the beginning of a program, before you write any executable statements; others allow you to declare
variables at any point, but require the declaration before you can use the variable.
In many modern programming languages, variables typically are declared within each module that uses
them. Such variables are known as local variables.
For example, to complete the averaging program shown in Figure 4-5 so that its variables are properly
declared, you can redraw the main program flowchart to look like the one shown in Figure 4-6. Three
variables are required: firstNumber, secondNumber, and average. The variables are declared as the first
step in the program, before you use any of them, and each is correctly identified as numeric. They appear
to the side of the “declare variables” step in an annotation symbol or annotation box, which is simply an
attached box containing notes. You can use an annotation symbol any time you have more to write than
you can conveniently fit within a flowchart symbol, or any time you want to add an explanatory comment
to a flowchart.
73
FIGURE 4-6: FLOWCHART AND PSEUDOCODE FOR MAINLINE LOGIC FOR AVERAGING PROGRAM SHOWING DECLARED
VARIABLES
Figure 4-6 also shows pseudocode for the same program. Because pseudocode is written and not drawn,
you might choose to list the variable names below the declare variables statement, as shown.
Programmers sometimes create a data dictionary, which is a list of every variable name used in a program,
along with its type, size, and description. When a data dictionary is created, it becomes part of the program
documentation.
TOPIC SUMMARY
Programmers break down programming problems into smaller, reasonable units called modules,
subroutines, procedures, functions, or methods. Modularization provides abstraction, allows
multiple programmers to work on a problem, makes it easy to reuse your work, and allows you to
identify structures more easily.
When you create a module or subroutine, you give the module a name that a calling program uses
when the module is about to execute. The flowchart symbol used to call a subroutine is a rectangle
with a bar across the top; the name of the module that you are calling is inside the rectangle. You
draw a flowchart for each module separately, with its own sentinel symbols.
A module can call other modules.
74
Declaring a variable involves providing a name for the memory location where the computer will store
the variable value, and notifying the computer of what type of data to expect.
KEY TERMS
Modules are small program units that you can use together to make a program. Programmers also refer
to modules as subroutines, procedures, functions, or methods.
The process of breaking down a program into modules is called modularization.
Abstraction is the process of paying attention to important properties while ignoring nonessential
details.
Low-level details are small, non-abstract steps.
High-level programming languages allow you to use English-like vocabulary in which one broad
statement corresponds to dozens of machine instructions.
Reusability is the feature of modular programs that allows individual modules to be used in a variety of
applications.
Reliability is the feature of modular programs that assures you that a module has been tested and
proven to function correctly.
The mainline logic is the logic used in the main module that calls other program modules.
A calling program or calling module is one that calls a module.
A module that is called by another is a submodule.
A main program runs from start to stop and calls other modules.
A prompt is a message that is displayed on a monitor, asking the user for a response.
The functional cohesion of a module is a measure of the degree to which all the module statements
contribute to the same task.
Declaring a variable involves providing a name for the memory location where the computer will store
the variable value, and notifying the computer of what type of data to expect.
Local variables are declared within each module that uses them.
Global variables are given a type and name once, and then are used in all modules of the program.
An annotation symbol or annotation box is a flowchart symbol that represents an attached box
containing notes.
A data dictionary is a list of every variable name used in a program, along with its type, size, and
description.
REVIEW QUESTIONS
1. which of the following is not a term used as a synonym for “module” in any programming
language?
A. structure
B. procedure
C. method
D. function
75
2. Which of the following is not a reason to use modularization? A. Modularization provides abstraction.
B. Modularization allows multiple programmers to work on a problem.
C. Modularization allows you to reuse your work.
D. Modularization eliminates the need for structure.
3. What is the name for the process of paying attention to important properties while ignoring
nonessential details?
A. structure
B. iteration
C. abstraction
D. modularization
4. All modern programming languages that use English-like vocabulary to create statements that
correspond to dozens of machine instructions are referred to as.
A. high-level
B. object-oriented
C. modular
D. obtuse
6. Programmers say that one module can another, meaning that the first module causes the second
module to execute.
A. declare
B. define
C. enact D. call
7. A message that appears on a monitor, asking the user for a response, is a. A. call
B. prompt
C. command
D. declaration
8. The more that a module’s statements contribute to the same job, the greater the of the module. A.
structure
B. modularity
C. functional cohesion
D. size
FIND THE ERRORS Each of the following pseudocode segments contains one or more errors that you
must find and correct.
1. This pseudocode is intended to describe determining whether you have passed or failed a
course based on the average score of two classroom tests. The main program calls three modules—
one that gets the input values, one that performs the average calculation and another that displays
the results. start declare variables num test1Score num test2Score char letterGrade perform
getInputValues() perform computeAvg() perform displayResults() stop getInput() input test1Score input
test2Score return computeAverage()
average=(test1Score+test2Score)/2
if average>=60 then letterGrade =
“P”
else
average=“F”
endif return
displayResults()
print average
print letter
return
2. This pseudocode is intended to describe computing the number of miles per gallon you get with
your automobile as well as the cost of gasoline per mile. The main program calls modules that allow
the user to enter data, compute statistics, and display results.
start declare variables num
gallonsOfGasUsed num
milesTraveled num
pricePerGallon num
milesPerGallon num
costPerMile perform
inputData() perform
computeStatistics() perform
displayResults() inputData()
input gallonsOfGasUsed
input milesTravelled input
pricePerGallonOfGas return
computeStatistics() milesPerGallon
=gallonsOfGasUsed/milesTraveled
costPerMile=pricePerGallon-milesPerGallon
return displayResults() print milesPerGal
print costPerMile return
stop
77
3. This pseudocode segment is intended to describe computing the cost per day for a vacation. The
user enters a value for total dollars available to spend and can continue to enter new dollar amounts
while the amount entered is not 0. For each new amount entered, a module is called that calculates
the amount of money available to spend per day.
start
declare variables num
totalDollars num costPerDay
input totalDollarsSpent while
totalDollarsSpent=0 perform
caclulateCost() endwhile end
calculateCost()
costPerDay=totalMoneySpent/
7
print costPerDay
endwhile
EXERCISES
1. Redraw the following flowchart so that the decisions and compensation calculations are in a
module.
78
2. Rewrite the following pseudocode so the discount decisions and calculations are in a module. start
read customerRecord if
quantityOrdered>100 then
discount=.20 else
if quantityOrdered>12 then
discount= .10 endif endif
total=priceEach*quantityOrdered
total=total-discount*total
print total
stop
3. What are the final values of variables a, b, and c after the following program runs?
start a=2 b=4 c=10
while c>6 perform
changeBAndC()
endwhile
if a=2 then perform
changeAAndB()
endif
if c =10 then perform
changeAAndB() else
perform changeBAndC()
endif print a, b,
c stop
changeBAndC()
b=b+1 c=c-1
return
changeAAndB()
a=a+1 b=b-1
return
4. What are the final values of variables d, e, and f after the following program runs?
start d=1 e=3
f=100 while e>d
perform module1()
endwhile if>0 then
perform module2()
else d=d+5
79
endif print
d, e, f stop
module1()
f=f-50
e=e+1
d=d+3
return
module2()
f=f+13
d=d*10
return
80
TOPIC 5
LEARNING OUTCOMES
After Studying this topic you should be able to:
Plan the mainline logic for a complete program
Describe typical housekeeping tasks
Describe tasks typically performed in the main loop of a program
Describe tasks performed in the end-of-job module
Understand the need for good program design
Appreciate the advantages of storing program components in separate files
Select superior variable and module names
Design clear module statements
Understand the need for maintaining good programming habits
Plan the logic for your first complete computer program. The output is an inventory report; a print chart
is shown in Figure 5-1. The report lists inventory items along with the price, cost, and profit of each
item.
Figure 5-2 shows the input INVENTORY file description, Figure 5-3 shows some typical data that might
exist in the input file, and Figure 5-4 shows how the output would actually look if the input file in Figure
5-3 were used.
81
FIGURE 5-2: INVENTORY FILE DESCRIPTION
Examine the print chart and the input file description. Your first task is to make sure you understand what
the report requires; your next job is to determine whether you have all the data you need to produce the
report. (Figure 5-5 shows this process.) The output requires the item name, price, and cost, and you can
see that all three are data items in the input file. The output also requires a profit figure for each item;
you need to understand how profit is calculated—which could be done differently in various companies.
If there is any doubt as to what a term used in the output means or how a value is calculated, you must
ask the user, or your client—the person who has requested the program and who will read and use the
report to make management decisions. In this case, suppose you are told you can determine the profit by
subtracting an item’s cost from its selling price. The input record contains an additional field, “Quantity in
stock”. Input records often contain more data than an application needs; in this example, you will not use
the quantity field. You have all the necessary data, so you can begin to plan the program.
82
FIGURE 5-5: STEPS TO CREATING A PROGRAM
You can write a program that reads records from an input file and produces a printed report as a
procedural program—that is, a program in which one procedure follows another from the beginning until
the end. You write the entire set of instructions for a procedural program, and when the program
executes, instructions take place one at a time, following your program’s logic. The overall logic, or
mainline logic, of almost every procedural computer program can follow a general structure that
consists of three distinct parts:
1. Performing housekeeping or initialization tasks. Housekeeping includes steps you must perform at
the beginning of a program to get ready for the rest of the program.
2. Performing the main loop repeatedly within the program. The main loop contains the
instructions that are executed for every record until you reach the end of the input of records, or
eof.
3. Performing the end-of-job routine. The end-of-job routine holds the steps you take at the end of the
program to finish the application.
You can write any procedural program as one long series of programming language statements, but
programs are easier to understand if you break their logic down into at least three parts, or modules. The
main program can call the three major modules, as shown in the flowchart and pseudocode in Figure 5-6.
Of course, the names of the modules, or subroutines, are entirely up to the programmer.
83
FIGURE 5-6: FLOWCHART AND PSEUDOCODE OF MAINLINE LOGIC
In summary, breaking down a big program into three basic procedures, or modularizing the program, helps
keep the job manageable, allowing you to tackle a large job one step at a time. Dividing the work into
routines also might allow you to assign the three major procedures to three different programmers, if you
choose. It also helps you keep the program structured.
HOUSEKEEPING TASKS
Housekeeping tasks include all the steps that must take place at the beginning of a program. Very often,
this includes four major tasks:
You declare variables.
You open files.
You perform any one-time-only tasks that should occur at the beginning of the program, such
as printing headings at the beginning of a report. You read the first input record.
Your first task in writing any program is to declare variables. When you declare variables, you assign
reasonable names (identifiers) to memory locations, so you can store and retrieve data there. Declaring a
84
variable involves selecting a name and a type. When you declare a variable in program code, the operating
system reserves space in memory to hold the contents of the variable. It uses the type (num or char) to
determine how to store the information; it stores numeric and character values in different formats.
For example, within the inventory report program, you need to supply variable names for the data fields
that appear in each input record. You might decide on the variable names and types shown in Figure
5 - 8.
You can provide any names you choose for your variables. When you write another program that uses the
same input file, you are free to choose completely new variable names. Similarly, other programmers
can write programs that use the same file and choose their own variable names. The variable names just
represent memory positions, and are internal to your program. The files do not contain any variable
names; files contain only data. When you read the characters “cotton shirt” from an input file, it doesn’t
matter whether you store those characters at a memory location named invItemName, nameOfItem,
productDescription, or any other one-word variable name. The variable name is simply an easy-to-
remember name for a specific memory address where those characters are stored.
Each of the four variable declarations in Figure 5-8 contains a type (character or numeric) and an identifier.
You can choose any one-word name to identify the variable, but a typical practice involves beginning
similar variables with a common prefix—for example, inv. In a large program in which you eventually
declare dozens of variables, the inv prefix will help you immediately identify a variable as part of the
inventory file.
Creating the inventory report as planned in Figure 5-1 involves using the invItemName, invPrice, and
invCost fields, but you do not need to use the invQuantity field in this program. However, the
information regarding quantity does take room in the input file, so you typically declare the variable to
allocate space for it when it is read into memory. If you imagine the surface of a disk as pictured in Figure
5-9, you can envision how the data fields follow one another in the file.
85
FIGURE 5-9: HOW TYPICAL DATA ITEMS LOOK WITHIN AN INVENTORY FILE
When you ask the program to read an inventory record, four “chunks” of data will be transferred from the
input device to the computer’s main memory: name, price, cost, and quantity. When you declare the
variables that represent the input data, you must provide a memory position for each of the four pieces
of data, whether or not they all are used within this program.
In most programming languages, you can give a group of associated variables a group name. This allows
you to handle several associated variables using a single instruction. Just as it is easier to refer to “The
Andersons” than it is to list “Nancy, Bud, Jim, Tom, Julie, Jane, Kate, and John,” the benefit of using a group
name is the ability to reference several variables with one all-encompassing name. For example, if you
group four fields together and call them invRecord, then you can write a statement such as read invRecord.
This is simpler than writing read invItemName, invPrice, invCost, and invQuantity. The way you assign a
group name to several variables differs in each programming language. This book follows the convention
of underlining any group name and indenting the group members beneath, as shown in Figure 5-10.
FIGURE 5-10: VARIABLE DECLARATIONS FOR THE INVENTORY FILE INCLUDING A GROUP NAME
In addition to declaring variables, sometimes you want to provide a variable with an initial value. Providing
a variable with a value when you create it is known as initializing, or defining, the variable. For example,
for the inventory report print chart shown in Figure 5-1, you might want to create a variable named
mainHeading and store the value “INVENTORY REPORT” in that variable. The declaration is char
mainHeading = “INVENTORY REPORT”. This indicates that mainHeading is a character variable, and that
the character contents are the words “INVENTORY REPORT”.
In many programming languages, if you do not provide an initial value when declaring a variable, then the
value is unknown, or garbage. Some programming languages do provide you with an automatic starting
value; for example, in Java, Visual Basic, BASIC, or RPG, all numeric variables automatically begin with the
value zero. However, in C++, C#, Pascal, and COBOL, variables generally do not receive any initial value
86
unless you provide one. No matter which programming language you use, it is always clearest to provide
a value for those variables that require them.
When you declare the variables invItemName, invPrice, invCost, and invQuantity, you do not provide them
with any initial value. The values for these variables will be assigned when the first file record is read into
memory. It would be legal to assign a value to input file record variables—for example, invItemName =
“cotton shirt”—but it would be a waste of time and might mislead others who read your program. The
first invItemName will come from an input device, and may or may not be “cotton shirt”.
The report illustrated in Figure 5-1 contains three individual heading lines. The most common practice is to
declare one variable or constant for each of these lines. The three declarations are as follows:
Within the program, when it is time to write the heading lines to an output device, you will code:
You are not required to create variables for your headings. Your program can contain the following
statements, in which you use literal strings of characters instead of variable names. The printed results
are the same either way.
Using variable names, as in print mainHeading, is usually more convenient than spelling out the
heading’s contents within the statement that prints, especially if you will use the headings in multiple
locations within your program. Additionally, if the contents of all of a program’s heading lines can be found
in one location at the start of the program, it is easier to locate them all if changes need to be made in the
future.
Dividing the headings into three lines is not required either, but it is a common practice. In most
programming languages, you could write all the headings in one statement, using a code that indicates a
new line at every appropriate position. Alternatively, most programming languages let you produce a
character for output without advancing to a new line. You could write out the headings using separate
print statements to display one character at a time, advancing to a new line only after all the line’s
characters were individually printed, although this approach seems painstakingly detailed. Storing and
writing one complete line at a time is a reasonable compromise.
87
Every programming language provides you with a means to physically advance printer paper to the top of
a page when you print the first heading. Similarly, every language provides you with a means to produce
double- and triple-spaced lines of text by sending specific codes to the printer or monitor. Because the
methods and codes differ from language to language, examples in this book assume that if a print chart
or sample output shows a heading that prints at the top of the page and then skips a line, any
corresponding variable you create, such as mainHeading, will also print in this manner. You can add the
appropriate language-specific codes to implement the mainHeading spacing when you write the actual
computer program. Similarly, if you create a print chart that shows detail lines as double-spaced, assume
your detail lines will double-space when you execute the step to write them.
Often, you must create dozens of variables when you write a computer program. If you are using a
flowchart to diagram the logic, it is physically impossible to fit the variables in one flowchart box.
Therefore, you might want to use an annotation symbol. The beginning of a flowchart for the
housekeeping() module of the inventory report program is shown in Figure 5-11.
FIGURE 5-11: BEGINNING OF FLOWCHART FOR housekeeping() MODULE FOR THE INVENTORY REPORT
PROGRAM
Notice that the three heading variables defined in Figure 5-11 are not indented under invRecord as the
invRecord fields are. This shows that although invItemName, invPrice, invCost, and invQuantity are part
of the invRecord group, mainHeading, columnHead1, and columnHead2 are not.
In Figure 5-11, notice that columnHead1 contains only the words that appear in the first line of column
headings, in row 4 of the print chart in Figure 5-1: “ITEM RETAIL PRICE MANUFACTURING PROFIT
PER”. Similarly, columnHead2 contains only the words that appear in the second row of column
headings.
If a program will use input files, you must tell the computer where the input is coming from—for example,
a specific disk drive, CD, or tape drive. You also must indicate the name (and possibly the path, the list of
folders or directories in which the file resides) for the file. Then you must issue a command to open the
file, or prepare it for reading. In many languages, if no input file is opened, input is accepted from a default
or standard input device, most often the keyboard.
If a program will have output, you must also open a file for output. Perhaps the output file will be sent to
a disk or tape. Although you might not think of a printed report as a file, computers treat a printer as just
another output device, and if output will go to a printer, then you must open the printer output device as
well. Again, if no file is opened, a default or standard output device, usually the monitor, is used.
88
When you create a flowchart, you usually write the command to open the files within a parallelogram.
You use the parallelogram because it is the input/output symbol, and you are opening the input and
output devices. You can use an annotation box to list the files that you open, as shown in Figure 5-12.
Within a program’s housekeeping module, besides declaring variables and opening files, you perform any
other tasks that occur only at the beginning of the program. A common housekeeping task involves
printing headings at the top of a report. In the inventory report example, three lines of headings appear
at the beginning of the report. In this example, printing the heading lines is straightforward:
print mainHeading
print columnHead1
print columnHead2
The last task you execute in the housekeeping module of most computer programs is to read the first data
record into memory. In this example, the input data is read from a stored file. Other applications might be
interactive applications—that is, applications that interact with a user who types data at a keyboard. When
you write your first computer programs, you probably will use interactive input so that you don’t have to
complicate the programs by including the statements necessary to locate and open an input file. To read
the necessary data interactively from the user, you could issue a statement such as the following:
read invItemName, invPrice, invCost, invQuantity
The statement would pause program execution until the user typed four values from the keyboard,
typically separating them with a delimiter, or character produced by a keystroke that separates data items.
Depending on the programming language, the delimiter might be the Enter key, the tab character,
or a comma.
Requiring a user to type four values in the proper order is asking a lot. More frequently, the read statement
would be separated into four distinct read statements, each preceded by an output statement
called a prompt that asks the user for a specific item. For example, the following set of statements prompts
the user for and accepts each of the necessary data items for the inventory program:
print “Please enter the inventory item name”
read invItemName
print “Enter the price”
read invPrice
89
print “Enter the cost of the item” read
invCost
print “Enter the quantity in stock” read
invQuantity
If the four data fields have already been stored and are input from a data file instead of interactively, then
no prompts are needed, and you can write the following:
read invItemName, invPrice, invCost, invQuantity
In most programming languages, if you have declared a group name such as invRecord, it is simpler to
obtain values for all the data fields by writing the following:
read invRecord
This statement fills the entire group item with values from the input file. Using the group name is a
shortcut for writing each field name. When you write your first programs, you might get your data
interactively, in which case you will write prompts and separate input statements, or you might obtain
input from a data file, but delay studying how to create group items, so you might list each field separately.
For simplicity, most of the input statements in this book will assume the data comes from files and is
grouped; this assumption will allow the book to use the shortest version of the statement that simply
means “obtain all the data fields this application needs.”
The last task within the housekeeping() module is to read the first invRecord; the first task following
housekeeping() is to check for eof on the file that contains the inventory records. If the program is an
interactive one, the user might indicate that input is complete by typing a predetermined value from the
keyboard, or using a mouse to select a screen option indicating completion of data entry. If the program
reads data from an input file stored on a disk, tape, or other storage device, the input device recognizes
that it has reached the end of a file when it attempts to read a record and finds no records available.
Recall the mainline logic of the inventory report program from Figure 5-6—eof is tested immediately after
housekeeping() ends.
If the input file has no records, when you read the first record the computer recognizes the end-of-file
condition and proceeds to the finishUp() module, never executing mainLoop(). More commonly, an input
file does have records, and after the first read the computer determines that the eof condition is false,
and the logic proceeds to mainLoop().
Immediately after reading from a file, the next step always should determine whether eof was
encountered. Notice in Figure 5-6 that the eof question always follows both the housekeeping() module
and the mainLoop() module. When the last instruction in each of these modules reads a record, then the
eof question correctly follows each read instruction immediately.
Not reading the first record within the housekeeping() module is a mistake. If housekeeping() does not
include a step to read a record from the input file, you must read a record as the first step in
mainLoop(), as shown on the left side of Figure 5-13. In this program, a record is read, a profit is
calculated, and a line is printed. Then, if it is not eof, another record is read, a profit calculated, and a line
90
printed. The program works well, reading records, calculating profits, and printing information until
reaching a read command in which the computer encounters the eof condition. When this last read
occurs, the next steps involve computing a profit and writing a line—but there isn’t any data to process.
Depending on the programming language you use, either garbage data will calculate and print, or a repeat
of the data from the last record before eof will print.
FIGURE 5-13: COMPARING FAULTY AND CORRECT RECORD-READING LOGIC FAULTY RECORD-READING
LOGIC
91
The flowchart in the lower part of Figure 5-13 shows correct record-reading logic. The appropriate place
for the priming record read is at the end of the preliminary housekeeping steps, and the appropriate place
for all subsequent reads is at the end of the main processing loop.
Figure 5-14 shows a completed housekeeping() routine for the inventory program in both flowchart and
pseudocode versions.
FIGURE 5-14: FLOWCHART AND PSEUDOCODE FOR housekeeping() ROUTINE IN INVENTORY REPORT
PROGRAM
As an alternative to including print mainHeading, print columnHead1, and print columnHead2 within the
housekeeping() module, you can place the three heading line statements in their own module. In this case,
the flowchart and pseudocode for housekeeping() will look like Figure 5-15, with the steps in the newly
created headings() module appearing in Figure 5-16. Either approach is fine; the logic of the program is
the same whether or not the heading line statements are segregated into their own routine.
The programmer can decide on the program organization that makes the most sense.
92
FIGURE 5-15: FLOWCHART AND PSEUDOCODE FOR ALTERNATIVE housekeeping() MODULE THAT CALLS
headings() MODULE
FIGURE 5-16: FLOWCHART AND PSEUDOCODE FOR headings() MODULE CALLED BY MAINLINE IN
FIGURE 5-15
After you declare the variables for a program and perform the housekeeping tasks, the “real work” of the
program begins. The inventory report described at the beginning of this chapter and depicted in Figure 5-
93
1 needs just one set of variables and one set of headings, yet there might be hundreds or thousands of
inventory items to process. The main loop of a program, controlled by the eof decision, is the program’s
“workhorse.” Each data record will pass once through the main loop, where calculations are performed
with the data and the results printed.
For the inventory report program to work, the mainLoop() module must include three steps:
At the end of housekeeping(), you read one data record into the computer’s memory. As the first step in
mainLoop(), you can calculate an item’s profit by subtracting its manufacturing cost from its retail price:
profit = invPrice - invCost. The name profit is the programmer-created variable name for a new spot in
computer memory where the value of the profit is stored. Although it is legal to use any variable name to
represent profit, naming it invProfit would be misleading. Using the inv prefix would lead those who read
your program to believe that profit was part of the input record, like the other variable names that start
with inv. The profit value is not part of the input record, however; it represents a memory location used
to store the arithmetic difference between two other variables.
Because you have a new variable, you must add profit to the list of declared variables at the beginning of
the program. Programmers often work back and forth between the variable list and the logical steps
during the creation of a program, listing some of the variables they will need as soon as they start to plan,
and adding others later as they think of them. Because profit will hold the result of a mathematical
calculation, you should declare it as a numeric variable when you add it to the variable list, as shown in
Figure 5-17. Notice that, like the headings, profit is not indented under invRecord. You want to show that
profit is not part of the invRecord group; instead, it is a separate variable that you are declaring to store a
calculated value.
FIGURE 5-17: VARIABLE LIST FOR INVENTORY REPORT PROGRAM, INCLUDING PROFIT
After you determine an item’s profit, you can write a detail line of information on the inventory report:
print invItemName, invPrice, invCost, profit. Notice that in the flowchart and pseudocode for the
mainLoop() routine in Figure 5-18, the output statement is not print invRecord. For one thing, the entire
invRecord is not printed—the quantity is not part of the report. Also, the calculated profit is included in
the detail line—it does not appear on the input record. Even if the report detail lines listed each of the
invRecord fields in the exact same order as on the input file, the print statement still would most often be
written listing the individual fields to be printed. Usually, you would include a formatting statement with
each printed field to control the spacing within the detail line. Because the way you space fields on detail
lines differs greatly in programming languages, discussion of the syntax to space fields is not included in
94
this book. However, the fields that are printed are listed separately, as you would usually do when coding
in a specific programming language.
The last step in the mainLoop() module of the inventory report program involves reading the next
invRecord. Figure 5-18 shows the flowchart and pseudocode for mainLoop().
FIGURE 5-18: FLOWCHART AND PSEUDOCODE FOR mainLoop() OF INVENTORY REPORT PROGRAM
Just as headings are printed one full line at a time, detail lines are also printed one line at a time. You can
print each field separately, as in the following code, but it is clearer and more efficient to write one full
line at a time, as shown in Figure 5-18.
print invItemName
print invPrice print
invCost print
profit
In most programming languages, you also have the option of calculating the profit and printing it in one
statement, as in the following:
print invItemName, invPrice, invCost, invPrice – invCost
If the language you use allows this type of statement, in which a calculation takes place within the output
statement, it is up to you to decide which format to use. Performing the arithmetic as part of the print
statement allows you to avoid declaring a profit variable. However, if you need the profit figure for further
calculations, then it makes sense to compute the profit and store it in a profit field. Using a separate work
variable, or work field, such as profit to temporarily hold a calculation is never wrong, and often it’s the
clearest course of action.
Although a language may allow you to combine actions into a single statement, you are never required to
do so. If the program is clearer using separate statements, then that is what you should do.
95
After the detail line containing the item name, price, cost, and profit has been written, the last step you
take before leaving the mainLoop() module is to read the next record from the input file into memory.
When you exit mainLoop(), the logic flows back to the eof question in the mainline logic. If it is not eof—
that is, if an additional data record exists—then you enter mainLoop() again, compute profit on the second
record, print the detail line, and read the third record.
Eventually, during an execution of mainLoop(), the program will read a new record and encounter the end
of the file. Then, when you ask the eof question in the mainline of the program, the answer will be yes,
and the program will not enter mainLoop() again. Instead, the program logic will enter the finishUp()
routine.
Within any program, the end-of-job routine holds the steps you must take at the end of the program, after
all input records are processed. Some end-of-job modules print summaries or grand totals at the end of a
report. Others might print a message such as “End of Report”, so readers can be confident that they have
received all the information that should be included. Such end-of-job message lines often are called footer
lines, or footers for short. Very often, endof-job modules must close any open files.
The end-of-job module for the inventory report program is very simple. The print chart does not indicate
that any special messages, such as “Thank you for reading this report”, print after the detail lines end.
Likewise, there are no required summary or total lines; nothing special happens. Only one task needs to
be performed in the end-of-job routine that this program calls finishUp(). In housekeeping(), you opened
files; in finishUp(), you close them. The complete finishUp() module is flowcharted and written in
pseudocode in Figure 5-19.
Many programmers wouldn’t bother with a subroutine for just one statement, but as you create more
complicated programs, your end-of-job routines will get bigger, and it will make more sense to see the
necessary job-finishing tasks together in a module.
For your convenience, Figure 5-20 shows the flowchart and pseudocode for the entire inventory report
program. Make sure you understand the importance of each flowchart symbol and each pseudocode line.
There is nothing superfluous—each is included to accomplish a specific part of the program that creates
the completed inventory report.
96
(st_art ( stop )
( main oop() ) t
profK • invPnce
invCoot
,
housekeepi
•
ng()
•
No
C------- return ) :
invRecord
char invltemName
0 -
num invPrice
num invCost
num invQuantity
char mainHeading • "INVetiTORY REPORT"
eof?
maini.ool'()
char columnHead2 = "DESCRIPTION EACH
•
97
)
houseke pi ng()
e 1 ( return
fifes
-, ]";'
vanable
'f ( finishUpO ) t
pri nts close
mai nHeadi ng
open I -
tis - VENTORY, Printer t
( rerum )
print
ool umnHead2
I
NVENTORY , Printer
FIGURE 5-20: FlDWCHART AN 0PSEUDOCODE FOR INVENTORY REPORT PROGRAM
98
FIGURE 5-20: FLOWCHART AND PSEUDOCODE FOR INVENTORY REPORT PROGRAM (CONTINUED)
As your programs become larger and more complicated, the need for good planning and design increases.
Think of an application you use, such as a word processor or a spreadsheet. The number and variety of
user options are staggering. Not only would it be impossible for a single programmer to write such an
application, but without thorough planning and design, the components would never work together
properly. Ideally, each program module you design needs to work well as a stand-alone module and as an
element of larger systems. Just as a house with poor plumbing or a car with bad brakes is fatally flawed,
a computer-based application can be great only if each component is designed well.
When you start to work on professional programs, you will see that many of them are quite lengthy, with
some containing hundreds of variables and thousands of lines of code. Earlier in this chapter, you learned
you can manage lengthy procedural programs by breaking them down into modules. Although
modularization helps you to organize your programs, sometimes it is still difficult to manage all of a
program’s components.
99
Most modern programming languages allow you to store program components in separate files. If you
write a module and store it in the same file as the program that uses it, your program files become large
and hard to work with, whether you are trying to read them on a screen or on multiple printed pages. In
addition, when you define a useful module, you might want to use it in many programs. Of course, you
can copy module definitions from one file to another, but this method is time-consuming as well as prone
to error. A better solution (if you are using a language that allows it) is to store your modules in individual
files and use an instruction to include them in any program that uses them. The statement needed to
access modules from separate files varies from language to language, but it usually involves using a verb
such as include, import, or copy, followed by the name of the file that contains the module.
For example, suppose your company has a standard employee record definition, part of which is shown
in Figure 5-21. Files with the same format are used in many applications within the organization—
personnel reports, production reports, payroll, and so on. It would be a tremendous waste of resources if
every programmer rewrote this file definition in multiple applications. Instead, once a programmer writes
the statements that constitute the file definition, those statements should be imported in their entirety
into any program that uses a record with the same structure. For example, Figure 5-22 shows how the
data fields in Figure 5-21 would be defined in the C++ programming language. If the statements in Figure
5-22 are saved in a file named Employees, then any C++ program can contain the statement #include
Employees and all the data fields are automatically declared.
FIGURE 5-22: DATA FIELDS IN FIGURE 5-21 DEFINED IN THE C++ LANGUAGE
Suppose you write a useful module that checks dates to guarantee their validity. For example, the two
digits that represent a month can be neither less than 01 nor greater than 12, and the two digits that
represent the day can contain different possible values, depending on the month. Any program that uses
the employee file description shown in Figure 5-21 might want to call the date-validating module several
times in order to validate any employee’s hire date, birth date, and termination date. Not only do you
want to call this module from several locations within any one program, you want to call it from many
programs. For example, programs used for company ordering and billing would each contain several
dates. If the date-validating module is useful and well-written, you might even want to market it to other
100
companies. By storing the module in its own file, you enable its use to be flexible. When you write a
program of any length, you should consider storing each of its components in its own file.
Storing components in separate files can provide an advantage beyond ease of reuse. When you let others
use your programs or modules, you often provide them with only the compiled (that is, machine-
language) version of your code, not the source code, which is composed of readable statements. Storing
your program statements in a separate, nonreadable, compiled file is an example of implementation
hiding, or hiding the details of how the program or module works. Other programmers can use your code,
but cannot see the statements you used to create it. A programmer who cannot see your well- designed
modules is more likely to use them simply as they were intended; the programmer also will not be able
to attempt to make adjustments to your code, thereby introducing error. Of course, in order to work with
your modules or data definitions, a programmer must know the names and types of data you are using.
Typically, you provide programmers who use your definitions with written documentation of the data
names and purposes.
An often-overlooked element in program design is the selection of good data and module names
(sometimes generically called identifiers). In Chapter 1, you learned that every programming language has
specific rules for the construction of names—some languages limit the number of characters, some allow
d ashes, and so on—but there are other general guidelines:
Use meaningful names. Creating a data field named someData or a module named firstModule()
makes a program cryptic. Not only will others find it hard to read your programs, but you will forget
the purpose of these identifiers even within your own programs. All programmers occasionally use
short, nondescriptive names such as x or temp in a quick program written to test a procedure;
however, in most cases, data and module names should be meaningful. Programmers refer to
programs that contain meaningful names as self-documenting. This means that even without
further documentation, the program code explains itself to readers.
Usually, you should use pronounceable names. A variable name like pzf is neither
pronounceable nor meaningful. A name that looks meaningful when you write it might not be as
meaningful when someone else reads it; for instance, preparead() might mean “Prepare ad” to
you, but “Prep a read” to others. Look at your names critically to make sure they are
pronounceable. Very standard abbreviations do not have to be pronounceable. For example, most
business people would interpret ssn as Social Security number.
Be judicious in your use of abbreviations. You can save a few keystrokes when creating a module
called getStat(), but is its purpose to find the state in which a city is located, output some statistics,
or determine the status of some variables? Similarly, is a variable named fn meant to hold a first
name, file number, or something else?
Usually, avoid digits in a name. Zeroes get confused with the letter “O”, and lowercase “l”s are
misread as the numeral 1. Of course, use your judgment: budgetFor2007 is probably not going to
be misinterpreted.
Use the system your language allows to separate words in long, multiword variable names. For
example, if the programming language you use allows dashes or underscores, then use a method
name like initialize-data() or initialize_data(), which is easier to read than initializedata(). If you use
a language that allows camel casing, then use initializeData(). If you use a language that is case
101
sensitive, it is legal but confusing to use variable names that differ only in case—for example,
empName, EmpName, and Empname.
Consider including a form of the verb to be, such as is or are, in names for variables that are intended
to hold a status. For example, use isFinished as a flag variable that holds a “Y” or “N” to indicate
whether a file is exhausted. The shorter name finished is more likely to be confused with a module
that executes when a program is done.
When you begin to write programs, the process of determining what data variables and modules you will
need and what to name them all might seem overwhelming. The design process is crucial, however. When
you acquire your first professional programming assignment, the design process might very well be
completed already. Most likely, your first assignment will be to write or make modifications to one small
member module of a much larger application. The more the original programmers stuck to these
guidelines, the better the original design was, and the easier your job of modification will be.
In addition to selecting good identifiers, you can use the following tactics to contribute to the clarity of
the statements within your program modules:
Some older programming languages require that program statements be placed in specific columns. Most
modern programming languages are free-form; you can arrange your lines of code any way you see fit. As
in real life, with freedom comes responsibility; when you have flexibility in arranging your lines of code,
you must take care to make sure your meaning is clear. With free-form code, programmers often
do not provide enough line breaks, or they provide inappropriate ones.
Figure 5-23 shows an example of code (part of the housekeeping() module from Figure 5-14) that does
not provide enough line breaks for clarity. If you have been following the examples used throughout this
book, the code in Figure 5-24 looks clearer to you; it will also look clearer to most other programmers.
102
Figure 5-24 shows that more, but shorter, lines usually improve your ability to understand a program’s
logic; appropriately breaking lines will become even more important as you introduce decisions and loops
into your programs in the next chapters.
When you need several mathematical operations to determine a result, consider using a series of
temporary variables to hold intermediate results. For example, Figure 5-25 shows two ways to calculate
a value for a real estate salespersonCommission variable. Each method achieves the same result—the
salesperson’s commission is based on the square feet multiplied by the price per square foot, plus any
premium for a lot with special features, such as a wooded or waterfront lot. However, the second example
uses two temporary variables, sqFootPrice and totalPrice. When the computation is broken down into
less complicated, individual steps, it is easier to see how the total price is calculated. In calculations with
even more computation steps, performing the arithmetic in stages would become increasingly helpful.
Whenever possible, use named values in your programs. If your program contains a statement like
salesTax = price * taxRate instead of salesTax = price * .06, you gain two benefits:
It is easier for readers to know that the price is being multiplied by a tax rate instead of a iscount,
commission, or some other rate represented by .06.
When the tax rate changes, you make one change to the value where taxRate is defined, rather than
searching through a program for every instance of .06.
Named values can be variables or constants. For example, if a taxRate is one value when a price is over
$100 and a different value when the price is not over $100, then you can store the appropriate value in a
variable named taxRate, and use it when computing the sales tax. A named value also can be declared to
be a named constant, meaning its value will never change during the execution of the program. For
example, the program segment in Figure 5-26 uses the constants TUITION_PER_CREDIT_HOUR and
ATHLETIC_FEE. Because the fields are declared to be constant, using the modifier const, you know that
their values will not change during the execution of the program. If the values of either of these should
change in the future, then the values assigned to the constants can be made in the declaration list, the
code can be recompiled, and the actual program statements that perform the arithmetic with the values
do not have to be disturbed. By convention, many programmers use all capital letters in constant names,
so they stand out as distinct from variables.
103
FIGURE 5-26: PROGRAM SEGMENT THAT CALCULATES STUDENT BALANCE DUE USING DEFINED
CONSTANTS
When you learn a programming language and begin to write lines of program code, it is easy to forget the
principles you have learned in this text. Having some programming knowledge and a keyboard at your
fingertips can lure you into typing lines of code before you think things through. But every program you
write will be better if you plan before you code. If you maintain the habits of first drawing
flowcharts or writing pseudocode, as you have learned here, your future programming projects will go
more smoothly. If you walk through your program logic on paper (called desk-checking) before starting to
type statements in C++, COBOL, Visual Basic, or Java, your programs will run correctly sooner. If you think
carefully about the variable and module names you use, and design your program statements so they are
easy for others to read, you will be rewarded with programs that are easier to get up and running, and
are easier to maintain as well.
CHAPTER SUMMARY
When you write a complete program, you first determine whether you have all the necessary data
to produce the output. Then, you plan the mainline logic, which usually includes modules to
perform housekeeping, a main loop that contains the steps that repeat for every record, and an
end-of-job routine.
Housekeeping tasks include all steps that must take place at the beginning of a program. These tasks
include declaring variables, opening files, performing any one-time-only tasks—such as printing
headings at the beginning of a report—and reading the first input record.
The main loop of a program is controlled by the eof decision. Each data record passes once through
the main loop, where calculations are performed with the data and results are printed.
Within any program, the end-of-job module holds the steps you must take at the end of the program,
after all the input records have been processed. Typical tasks include printing summaries, grand
totals, or final messages at the end of a report, and closing all open files.
As your programs become larger and more complicated, the need for good planning and design
increases.
Most modern programming languages allow you to store program components in separate files and
use instructions to include them in any program that uses them. Storing components in separate
files can provide the advantages of easy reuse and implementation hiding.
104
When selecting data and module names, use meaningful, pronounceable names. Be judicious in
your use of abbreviations, avoid digits in a name, and visually separate words in multiword names.
Consider including a form of the verb to be, such as is or are, in names for variables that are
intended to hold a status.
When writing program statements, you should avoid confusing line breaks, use temporary
variables to clarify long statements, and use constants where appropriate.
KEY TERMS
A user, or client, is a person who requests a program, and who will actually use the output of the
program.
A procedural program is a program in which one procedure follows another from the beginning until
the end.
The mainline logic of a program is the overall logic of the main program from beginning to end.
A housekeeping module includes steps you must perform at the beginning of a program to get ready
for the rest of the program.
The main loop of a program contains the steps that are repeated for every record.
The end-of-job routine holds the steps you take at the end of the program to finish the
application.
Functional decomposition is the act of reducing a large program into more manageable modules.
A prefix is a set of characters used at the beginning of related variable names.
Hungarian notation is a variable-naming convention in which a variable’s data type or other
information is stored as part of its name.
A group name is a name for a group of associated variables.
Initializing, or defining, a variable is the process of providing a variable with a value, as well as a
name and a type, when you create it.
Garbage is the unknown value of an undefined variable.
Opening a file is the process of telling the computer where the input is coming from, the name of
the file (and possibly the folder), and preparing the file for reading.
standard input device is the default device from which input comes, most often the
keyboard.
The standard output device is the default device to which output is sent, usually the monitor.
Interactive applications are applications that interact with a user who types data at a keyboard.
A delimiter is a keystroke that separates data items.
An output statement called a prompt asks the user for a specific item.
A work variable, or work field, is a variable you use to temporarily hold a calculation.
Footer lines, or footers, are end-of-job message lines.
Source code is the readable statements of a program, written in a programming language.
Implementation hiding is hiding the details of the way a program or module works.
105
Identifiers are the names of variables and modules.
Self-documenting programs are those that contain meaningful data and module names that
describe the programs’ purpose.
An arithmetic expression is a statement, or part of a statement, that performs arithmetic and has a
value.
A named constant holds a value that never changes during the execution of a program. Desk-
checking is the process of walking through a program’s logic on paper.
REVIEW QUESTIONS
2. A program in which one operation follows another from the beginning until the end is a
program.
A. modular
B. functional
C. procedural
D. object-oriented
3. The mainline logic of many computer programs contains . A. calls to housekeeping, record
processing, and finishing routines
B. steps to declare variables, open files, and read the first record
C. arithmetic instructions that are performed for each record in the input file
D. steps to print totals and close files
6. When a programmer uses a data file and names the first field stored in each record idNumber, then
other programmers who use the same file in their programs. A. must also name the field idNumber
B. might name the field idNumber
C. cannot name the field idNumber
D. cannot name the field
106
7. If you use a data file containing student records, and the first field is the student’s last name, then
you can name the field .
A. stuLastName
B. studentLastName
C. lastName
D. any of the above
8. If a field in a data file used for program input contains “Johnson”, then the best choice among the
following names for a programmer to use when declaring a memory location for the data is . A.
Johnson
B. n
C. lastName D. A programmer cannot declare a variable name for this field; it is already called
Johnson.
10. Defining a variable means the same as it and providing a starting value for it. A. declaring
B. initializing
C. deleting
D. assigning
14. Preparing an input device to deliver data records to a program is called a file.
A. prompting
B. opening
C. refreshing
107
D. initializing
17. Most business programs contain a that executes once for each record in an input file. A.
housekeeping module
B. main loop
C. finish routine
D. terminal symbol
18. Which of the following pseudocode statements is equivalent to this pseudocode: salePrice =
salePrice - discount finalPrice = salePrice + tax
print finalPrice
A. print salePrice + tax
B. print salePrice - discount
C. print salePrice - discount + tax
D. print discount + tax - salePrice
19. Common end-of-job module tasks in programs include all of the following except _. A. opening
files
B. printing totals
C. printing end-of-job messages
D. closing files
20. Which of the following is least likely to be performed in an end-of-job module? A. closing files
B. checking for eof
C. printing the message “End of report”
D. adding two values
FIND THE BUGS
Each of the following pseudocode segments contains one or more bugs that you must find and correct.
1. This pseudocode should create a report containing first-quarter profit statistics for a retail store.
Input records contain a department name (for example, “Cosmetics”), expenses for each of the
months January, February, and March, and sales for each of the same three months. Profit is determined
by subtracting total expenses from total sales. The main program calls three modules— housekeeping(),
mainLoop(), and finishUp(). The housekeeping() module calls printHeadings().
108
2. This pseudocode should create a report containing rental agents’ commissions at an apartment
complex. Input records contain each salesperson’s ID number and name, as well as number of three -
bedroom, two-bedroom, one-bedroom, and studio apartments rented during the month.
The commission for each apartment rented is $50 times the number of bedrooms, except for studio
apartments, for which the commission is $35. The main program calls three modules—
housekeeping(), calculateCommission(), and finishUp(). The housekeeping() module calls
displayHeaders().
109
EXERCISES
1. A pet store owner needs a weekly sales report. The output consists of a printed report titled PET
SALES, with column headings TYPE OF ANIMAL and PRICE. Fields printed on output are: type of animal
and price. After all records print, a footer line END OF REPORT prints. The input file description is shown
below.
a. Design the output for this program; create either sample output or a print chart.
b. Draw the hierarchy chart for this program.
c. Draw the flowchart for this program.
d. Write the pseudocode for this program.
2. An employer wants to produce a personnel report. The output consists of a printed report titled
ACTIVE PERSONNEL. Fields printed on output are: last name of employee, first name of employee, and
110
current weekly salary. Include appropriate column headings and a footer. The input file description is
shown below.
111
a. Design the output for this program; create either sample output or a print chart.
b. Draw the hierarchy chart for this program.
c. Draw the flowchart for this program.
d. Write the pseudocode for this program.
3. An employer wants to produce a personnel report that shows the end result if she gives everyone
a 10 percent raise in salary. The output consists of a printed report entitled PROJECTED RAISES. Fields
printed on output are: last name of employee, first name of employee, current weekly salary, and
projected weekly salary. The input file description is shown below.
a. Design the output for this program; create either sample output or a print chart.
b. Draw the hierarchy chart for this program.
c. Draw the flowchart for this program.
d. Write the pseudocode for this program.
4. A furniture store maintains an inventory file that includes data about every item it sells. The
manager wants a report that lists each stock number, description, and profit, which is the retail price
minus the wholesale price. The fields include a stock number, description, wholesale price, and retail
price. The input file description is shown below.
a. Design the output for this program; create either sample output or a print chart.
b. Draw the hierarchy chart for this program.
c. Draw the flowchart for this program.
d. Write the pseudocode for this program.
5. A summer camp keeps a record for every camper, including first name, last name, birth date, and
skill scores that range from 1 to 10 in four areas: swimming, tennis, horsemanship, and crafts. (The birth
date is stored in the format YYYYMMDD without any punctuation. For example, January 21, 1991 is
19910121.) The camp wants a printed report listing each camper’s data, plus a total score that is the
sum of the camper’s four skill scores. The input file description is shown below.
112
a. Design the output for this program; create either sample output or a print chart.
b. Draw the hierarchy chart for this program.
c. Draw the flowchart for this program.
d. Write the pseudocode for this program.
6. An employer needs to determine how much tax to withhold for each employee. This withholding
amount computes as 20 percent of each employee’s weekly pay. The output consists of a printed report
titled WITHHOLDING FOR EACH EMPLOYEE. Fields printed on output are: last name of employee,
first name of employee, hourly pay, weekly pay based on a 40-hour workweek, and withholding amount
per week. The input file description is shown below.
a. Design the output for this program; create either sample output or a print chart.
b. Draw the hierarchy chart for this program.
c. Draw the flowchart for this program.
d. Write the pseudocode for this program.
7. A baseball team manager wants a report showing her players’ batting statistics. A batting average
is computed as hits divided by at-bats, and it is usually expressed to three decimal positions (for
example, .235). The output consists of a printed report titled TEAM STATISTICS. Fields printed on output
are: player number, first name, last name, and batting average. The input file description is shown
below.
a. Design the output for this program; create either sample output or a print chart.
b. Draw the hierarchy chart for this program.
c. Draw the flowchart for this program.
d. Write the pseudocode for this program.
113
a. Design the output for this program; create either sample output or a print chart.
b. Draw the hierarchy chart for this program.
c. Draw the flowchart for this program.
d. Write the pseudocode for this program.
8. A car rental company manager wants a report showing the revenue earned per mile on vehicles
rented each week. An automobile’s miles traveled are computed by subtracting the odometer reading
when the car is rented from the odometer reading when the car is returned. The amount earned per
mile is computed by dividing the rental fee by the miles traveled. The output consists of a printed report
titled CAR RENTAL REVENUE STATISTICS. Fields printed on output are: vehicle identification number,
odometer reading out, odometer reading in, miles traveled, rental fee, and amount earned per mile.
The input file description is shown below.
9. Professor Smith provides her programming logic students with a final grade that is based on their
performance in attendance (a percentage based on 16 class meetings), homework (a percentage based
on 10 assignments that might total up to 100 points), and exams (a percentage based on two 100-point
exams). A student’s final percentage for the course is determined using a weighted average of these
figures, with exams counting twice as much as attendance or homework. For example, a student who
attended 12 class meetings (75%), achieved 90 points on homework assignments (90%), and scored an
average of 60% on tests would have a final average of 71.25% (75 + 90 + 2 * 60) / 4. Professor Smith
wants a report that shows each student’s ID number and his or her final percentage score.
a. Design the output for this program; create either sample output or a print chart.
b. Draw the hierarchy chart for this program.
c. Draw the flowchart for this program.
d. Write the pseudocode for this program.
114
TOPIC 6
6. MAKING DECISIONS
LEARNING OUTCOMES
After Studying this topic you should be able to:
Evaluate Boolean expressions to make comparisons
Use the relational comparison operators
Understand AND logic
Understand OR logic
Use selections within ranges
Understand precedence when combining AND and OR selections
Understand the case structure
Use decision tables
One reason people think computers are smart lies in a computer program’s ability to make decisions. For
example, a medical diagnosis program that can decide if your symptoms fit various disease profiles seems
quite intelligent, as does a program that can offer you potential vacation routes based on your destination.
The selection structure (also called the decision structure) involved in such programs is not new to you—
it’s one of the basic structures of structured programming. See Figures 6-1 and 6-2.
FIGURE 6-1: THE DUAL-ALTERNATIVE SELECTION FIGURE 6-2: THE SINGLE-ALTERNATIVE SELECTION STRUCTURE
STRUCTURE
You can refer to the structure in Figure 6-1 as a dual-alternative, or binary, selection because there is an
action associated with each of two possible outcomes. Depending on the answer to the question
115
represented by the diamond, the logical flow proceeds either to the left branch of the structure or to the
right. The choices are mutually exclusive; that is, the logic can flow only to one of the two alternatives,
never to both. This selection structure is also called an if-then-else structure because it fits the statement:
The flowchart segment in Figure 6-2 represents a single-alternative, or unary, selection where action is
required for only one outcome of the question. You call this form of the if-then-else structure an if-then,
because no alternative or “else” action is included or necessary.
For example, Figure 6-3 shows the flowchart and pseudocode for a typical if-then-else decision in a
business program. Many organizations pay employees time and a half (one and one-half times their usual
hourly rate) for hours in excess of 40 per week. The logic segments in the figure show this decision.
In the example in Figure 6-3, the longer calculation that adds a time-and-a-half factor to an employee’s
gross pay executes only when the expression hoursWorked > 40 is true. The overtime calculation exists in
the if clause of the decision—the part of the decision that holds the action or actions that execute when
the tested condition in the decision is true. The shorter, regular pay calculation, which produces grossPay
by multiplying hoursWorked by rate, constitutes the else clause of the decision—the part that executes
only when the tested condition in the decision is false.
The typical if-then decision in Figure 6-4 shows an employee’s paycheck being reduced if the employee
participates in the dental plan. No action is taken if the employee is not a dental plan participant.
116
FIGURE 6-4: FLOWCHART AND PSEUDOCODE FOR DENTAL PLAN DECISION
The expressions hoursWorked > 40 and dentalPlanCode = “Y” that appear in Figures 6-3 and 6-4,
respectively, are Boolean expressions. In Chapter 4, you learned that in programming, an expression is a
statement, or part of a statement, that has a value. For example, an arithmetic expression is one that
performs arithmetic, resulting in a value. A Boolean expression is one that represents only one of two
states, usually expressed as true or false. Every decision you make in a computer program involves
evaluating a Boolean expression. True/false evaluation is “natural” from a computer’s standpoint, because
computer circuitry consists of two-state, on-off switches, often represented by 1 or 0. Every computer
decision yields a true-or-false, yes-or-no, 1-or-0 result.
Usually, you can compare only values that are of the same type; that is, you can compare numeric values
to other numbers and character values to other characters. You can ask every programming question by
using one of only six types of comparison operators in a Boolean expression. For any two values that are
the same type, you can decide whether:
In any Boolean expression, the two values used can be either variables or constants. For example, the
expression currentTotal = 100? compares the value stored in a variable, currentTotal, to a numeric
constant, 100. Depending on the currentTotal value, the expression is true or false. In the expression
currentTotal = previousTotal? both values are variables, and the result is also true or false depending on
the values stored in each of the two variables. Although it’s legal to do so, you would never use expressions
in which you compare two unnamed constants—for example, 20 = 20? or 30 = 40?. Such expressions are
considered trivial because each will always evaluate to the same result: true for the first expression and
false for the second.
Each programming language supports its own set of relational comparison operators, or comparison
symbols, that express these Boolean tests. For example, many languages such as Visual Basic and Pascal
use the equal sign (=) to express testing for equivalency, so balanceDue = 0 compares balanceDue to zero.
COBOL programmers can use the equal sign, but they also can spell out the expression, as in balanceDue
equal to 0. RPG programmers use the two-letter operator EQ in place of a symbol. C#, C++, and Java
programmers use two equal signs to test for equivalency, so they write balanceDue == 0 to compare the
two values. Although each programming language supports its own syntax for comparing values’
equivalency, all languages provide for the same logical concept of equivalency.
Most languages allow you to use the algebraic signs for greater than (>) and less than (<) to make the
corresponding comparisons. Additionally, COBOL, which is very similar to English, allows you to spell out
the comparisons in expressions such as daysPastDue is greater than 30 or packageWeight is less than
117
maximumWeightAllowed. RPG uses the two-letter abbreviations GT and LT to represent greater than or
less than. When you create a flowchart or pseudocode, you can use any form of notation you want to
express “greater than” and “less than.” It’s simplest to use the symbols > and < if you are comfortable with
their meaning. As with equivalency, the syntax changes when you change languages, but the concepts of
greater than and less than exist in all programming languages.
Most programming languages allow you to express “greater than or equal to” by typing a greater-than sign
immediately followed by an equal sign (>=). When you are drawing a flowchart or writing
pseudocode, you might prefer a greaterthan sign with a line under it (≥) because mathematicians use that
symbol to mean “greater than or equal to.” However, when you write a program, you type >= as two
separate characters, because no single key on the keyboard expresses this concept. Similarly, “less than or
equal to” is written with two symbols, < immediately followed by =.
Any logical situation can be expressed using just three types of comparisons: equal, greater than, and less
than. You never need the three additional comparisons (greater than or equal to, less than or equal to, or
not equal to), but using them often makes decisions more convenient. For example, assume you need to
issue a 10 percent discount to any customer whose age is 65 or greater, and charge full price to other
customers. You can use the greater-than-or-equal-to symbol to write the logic as follows:
As an alternative, if you want to use only one of the three basic comparisons (=, >, and <), you can express
the same logic by writing:
In any decision for which a >= b is true, then a < b is false. Conversely, if a >= b is false, then a < b is true.
By rephrasing the question and swapping the actions taken based on the outcome, you can make the
same decision in multiple ways. The clearest route is often to ask a question so the positive or true
outcome results in the unusual action. For example, assume that charging a customer full price is the
ordinary course, and that providing a discount is the unusual occurrence. When your company policy is
to “provide a discount for those who are 65 and older,” the phrase “greater than or equal to” comes to
mind, so it is the most natural to use. Conversely, if your policy is to “provide no discount for those under
65,” then it is more natural to use the “less than” syntax. Either way, the same people receive a discount.
118
Comparing two amounts to decide if they are not equal to each other is the most confusing of all the
comparisons. Using “not equal to” in decisions involves thinking in double negatives, which makes you
prone to include logical errors in your programs. For example, consider the flowchart segment in Figure 6-
5.
In Figure 6-5, if the value of customerCode is equal to 1, the logical flow follows the false branch of the
selection. If customerCode not equal to 1 is true, the discount is 0.25; if customerCode not equal to 1 is
not true, it means the customerCode is 1, and the discount is 0.50. Even using the phrase
“customerCode not equal to 1 is not true” is awkward.
Figure 6-6 shows the same decision, this time asked in the positive. Making the decision if
customerCode is 1 then discount = 0.50 is clearer than trying to determine what customerCode is not.
FIGURE 6-6: USING THE POSITIVE EQUIVALENT OF THE NEGATIVE COMPARISON IN FIGURE 6-5
Besides being awkward to use, the “not equal to” comparison operator is the one most likely to be different
in the various programming languages you may use. COBOL allows you to write “not equal to”; Visual Basic
and Pascal use a less-than sign followed immediately by a greater-than sign (<>); C#, C++, C, and Java use
an exclamation point followed by an equal sign (!=). In a flowchart or in pseudocode, you can use the
symbol that mathematicians use to mean “not equal,” an equal sign with a slash through it (≠). When you
program, you will not be able to use this symbol, because no single key on the keyboard produces it.
119
Figure 6-7 summarizes the six comparison operators and contrasts trivial (both true and false) examples
with typical examples of their use.
Often, you need more than one selection structure to determine whether an action should take place. For
example, suppose that your employer wants a report that lists workers who have registered for both
insurance plans offered by the company: the medical plan and the dental plan. This type of situation is
known as an AND decision because the employee’s record must pass two tests—participation in the
medical plan and participation in the dental plan—before you write that employee’s information on the
report. A compound, or AND, decision requires a nested decision, or a nested if. A nested decision is a
decision “inside of” another decision. The logic looks like Figure 6-8.
The AND decision shown in Figure 6-8 is part of a much larger program. To help you develop this program,
suppose your employer provides you with the employee data file description and you learn that the
120
medical and dental insurance fields contain a single character, “Y” or “N”, indicating each employee’s
participation status. With your employer’s approval, you develop the sample output.
The mainline logic and housekeeping() routines for this program are diagrammed in Figures 6-9 and 6- 10.
FIGURE 6-9: FLOWCHART AND PSEUDOCODE OF MAINLINE LOGIC FOR MEDICAL AND DENTAL PARTICIPANT REPORT
121
FIGURE 6-10: FLOWCHART AND PSEUDOCODE OF housekeeping() MODULE FOR MEDICAL AND DENTAL
PARTICIPANT REPORT
At the end of the housekeeping() module, the first employee record is read into computer memory.
Assuming that the eof condition is not yet met, the logical flow proceeds to the createReport() method. If
the program required data for all employees to be printed, this method would simply print the information
from the current record and get the next record. However, in this case, the output should contain only the
names of those employees who participate in both the medical and dental insurance plans. Therefore,
within the createReport() module of this program, you ask the questions that determine whether
the current employee’s record will print; if the employee’s data meet the medical and dental insurance
requirements, then you print the record. Whether or not you take the path that prints the record, the last
thing you do in the createReport() method is to read the next input record. Figure 6-11 shows the
createReport() module.
122
FIGURE 6-11: THE createReport() MODULE OF A PROGRAM THAT LISTS EMPLOYEES WHO ARE BOTH
MEDICAL AND DENTAL INSURANCE PROGRAM PARTICIPANTS
The createReport() module works like this: If the employee has medical insurance, then and only then test
to see if the employee has dental insurance. If so, then and only then print the employee’s data. The dental
insurance question is nested entirely within half of the medical insurance question structure. If an
employee does not carry medical insurance, there is no need to ask about the dental insurance; the
employee is already disqualified from the report.
When you nest decisions because the resulting action requires that two conditions be true, you must
decide which of the two decisions to make first. Logically, either selection in an AND decision can come
first. However, when there are two selections, you often can improve your program’s performance by
making an appropriate choice as to which selection to make first.
For example, Figure 6-12 shows the nested decision structure in the createReport() method logic of the
program that produces a report of employees who participate in both the medical and dental insurance
plans. Alternatively, you can write the decision as in Figure 6-13. if empMedicalIns = “Y” then
if empDentalIns = “Y” then print empIdNumber,
empLastName, empFirstName
endif
endif
123
FIGURE 6-12: FINDING MEDICAL AND DENTAL PLAN PARTICIPANTS, CHECKING MEDICAL FIRST
Examine the decision statements in Figures 6-12 and 6-13. If you want to print employees who participate
in the medical AND dental plans, you can ask about the medical plan first, eliminate those employees who
do not participate, and ask about the dental plan only for those employees who “pass” the medical
insurance test. Or, you could ask about the dental plan first, eliminate those who do not participate, and
ask about the medical plan only for those employees who “pass” the dental insurance test. Either way, the
final list contains only those employees who have both kinds of insurance.
Does it make a difference which question is asked first? As far as the output goes, no. Either way, the same
employee names appear on the report—those with both types of insurance. As far as program efficiency
goes, however, it might make a difference which question is asked first.
Assume you know that out of 1,000 employees in your company, about 90 percent, or 900, participate in
the medical insurance plan. Assume you also know that out of 1,000 employees, only about half, or 500,
participate in the dental plan.
The medical and dental insurance program will ask the first question in the createReport() method 1,000
times during its execution—once for each employee record contained in the input file. If the program uses
the logic in Figure 6-12, it asks the first question empMedicalIns = “Y”? 1,000 times. For approximately 90
percent of the employees, or 900 of the records, the answer is true, meaning the empMedicalIns field
contains the character “Y”. So 100 employees are eliminated, and 900 proceed to the next question about
dental insurance. Only about half of the employees participate in the dental plan, so 450 out of the 900
will appear on the printed report.
Using the alternate logic in Figure 6-13, the program asks the first question empDentalIns = “Y”? 1,000
times. Because only about half of the company’s employees participate, only 500 will “pass” this test and
proceed to the medical insurance question. Then about 90 percent of the 500, or 450 employees, will
appear on the printed report. Whether you use the logic in Figure 6-12 or 6-13, the same 450 employees
who have both types of insurance appear on the report.
The difference lies in the fact that when you use the logic in Figure 6-12, the program must ask 1,900
questions to produce the report—the medical insurance question tests all 1,000 employee records, and
900 continue to the dental insurance question. If you use the logic in Figure 6-13 to produce the report,
the program asks only 1,500 questions—all 1,000 records are tested for dental insurance, but only 500
proceed to the medical insurance question. By asking about the dental insurance first, you “save” 400
decisions.
124
The 400-question difference between the first set of decisions and the second set really doesn’t take much
time on most computers. But it will take some time, and if there are hundreds of thousands of employees
instead of only 1,000, or if many such decisions have to be made within a program, performance time can
be significantly improved by asking questions in the proper order.
In many AND decisions, you have no idea which of two events is more likely to occur; in that case, you can
legitimately ask either question first. In addition, even though you know the probability of each of two
conditions, the two events might not be mutually exclusive; that is, one might depend on the other.
For example, if employees with dental insurance are significantly more likely to carry medical insurance
than those who don’t carry dental insurance, the order in which to ask the questions might matter less or
not matter at all. However, if you do know the probabilities of the conditions, or can make a reasonable
guess, the general rule is: In an AND decision, first ask the question that is less likely to be true. This
eliminates as many records as possible from having to go through the second decision, which speeds up
processing time.
Most programming languages allow you to ask two or more questions in a single comparison by using a
logical AND operator. For example, if you want to select employees who carry both medical and dental
insurance, you can use nested ifs, or you can include both decisions in a single statement by writing
empDentalIns = “Y” AND empMedicalIns = “Y”?. When you use one or more AND operators to combine
two or more Boolean expressions, each Boolean expression must be true in order for the entire expression
to be evaluated as true. For example, if you ask, “Are you at least 18, and are you a registered voter, and
did you vote in the last election?”, the answer to all three parts of the question must be “yes” before the
response can be a single, summarizing “yes”. If any part of the question is false, then the entire question
is false.
If the programming language you use allows an AND operator (and almost all do), you still must realize
that the question you place first is the question that will be asked first, and cases that are eliminated based
on the first question will not proceed to the second question. The computer can ask only one question at
a time; even when your logic follows the flowchart segment in Figure 6-14, the computer will execute the
logic in the flowchart in Figure 6-15.
125
FIGURE 6-14: FLOWCHART AND PSEUDOCODE OF AN AND DECISION USING AN AND OPERATOR
FIGURE 6-15: FLOWCHART AND PSEUDOCODE OF COMPUTER LOGIC OF PROGRAM CONTAINING AN AND
OPERATOR IN THE DECISION (THE COMPUTER STILL MAKES TWO SEPARATE DECISIONS, EVEN THOUGH AN
AND OPERATOR IS USED)
When you must satisfy two or more criteria to initiate an event in a program, you must make sure that the
second decision is made entirely within the first decision. For example, if a program’s objective is to print
a report of those employees who carry both medical and dental insurance, then the program segment
shown in Figure 6-16 contains three different types of logic errors.
126
FIGURE 6-16: INCORRECT LOGIC TO PRODUCE REPORT CONTAINING EMPLOYEES WHO PARTICIPATE IN
BOTH MEDICAL AND DENTAL INSURANCE PLANS
The diagram shows that the program asks the dental insurance question first. However, if an employee
participates in the dental program, the employee’s record prints immediately. The employee record should
not print, because the employee might not have the medical insurance. In addition, the program should
eliminate an employee without dental insurance from the next selection, but every employee’s record
proceeds to the medical insurance question, where it might print, whether the employee has dental
insurance or not. Additionally, any employee who has both medical and dental insurance, having passed
each test successfully, will appear twice on this report. For many reasons, the logic shown in Figure 6-16 is
not correct for this problem.
Beginning programmers often make another type of error when they must make two comparisons on the
same field when using a logical AND operator. For example, suppose you want to list employees who make
between $10.00 and $11.99 per hour, inclusive. When you make this type of decision, you are basing it on
a range of values—every value between low and high limits. For example, you want to select employees
whose empRate is greater than or equal to 10.00 AND whose empRate is less than 12.00; therefore, you
need to make two comparisons on the same field.
The correct way to make this comparison with the AND operator is as follows:
127
if empRate >= 10.00 AND empRate < 12.00 then print
empIdNumber, empLastName, empFirstName endif
You substitute the AND operator for the phrase then if. However, some programmers might try to make
the comparison as follows:
In most languages, the phrase empRate >= 10.00 AND < 12.00 is incorrect. The logical AND is usually a
binary operator that requires a complete Boolean expression on each side. The expression to the right of
the AND, < 12.00, is not a complete Boolean expression; you must indicate what is being compared to
12.00.
Sometimes, you want to take action when one or the other of two conditions is true. This is called an OR
decision because either a first condition must be met or a second condition must be met for an event to
take place. If someone asks you, “Are you free Friday or Saturday?”, only one of the two conditions has to
be true in order for the answer to the whole question to be “yes”; only if the answers to both halves of the
question are false is the value of the entire expression false.
For example, suppose your employer wants a list of all employees who participate in either the medical or
dental plan. The mainline logic and housekeeping() module for this program are identical to those used in
Figures 6-9 and 6-10. You only need to change the heading on the sample output and change the heading1
variable in Figure 6-10 from heading1 = “Employees with Medical and Dental Insurance” to heading1 =
“Employees with Medical or Dental Insurance”. The only substantial changes to the program occur in the
createReport() module.
Figure 6-17 shows the possible logic for the createReport() method in this OR selection. As each record
enters the createReport() method, you ask the question empMedicalIns = “Y”?, and if the result is true,
you print the employee data. Because the employee needs to participate in only one of the two insurance
plans to be selected for printing, there is no need for further questioning after you have determined that
an employee has medical insurance. If the employee does not participate in the medical insurance
plan, only then do you need to ask if empDentalIns = “Y”?. If the employee does not have medical
insurance, but does have dental, you want this employee information to print on the report.
128
FIGURE 6-17: FLOWCHART AND PSEUDOCODE FOR createReport() MODULE OF PROGRAM THAT PRINTS
RECORDS OF EMPLOYEES WHO PARTICIPATE IN EITHER THE MEDICAL OR DENTAL INSURANCE PLAN
You might have noticed that the statement print empIdNumber, empLastName, empFirstName appears
twice in the flowchart and in the pseudocode shown in Figure 6-17. The temptation is to redraw the
flowchart in Figure 6-17 to look like Figure 6-18. Logically, you can argue that the flowchart in Figure 6- 18
is correct because the correct employee records print. However, this flowchart is not allowed
because it is not structured.
129
FIGURE 6-18: INCORRECT FLOWCHART FOR createReport() MODULE
The way we casually use English can cause another type of error when you require a decision based on a
value falling within a range of values. For example, a movie theater manager might say, “Provide a discount
to patrons who are under 13 years old and those who are over 64 years old; otherwise, charge he full
price.” Because the manager has used the word “and” in the request, you might be tempted to create the
decision shown in Figure 6-19; however, this logic will not provide a discounted price for any movie patron.
You must remember that every time the decision in Figure 6-19 is made, it is made using a single data
record. If the age field in that record contains an age lower than 13, then it cannot possibly contain an age
over 64. Similarly, if it contains an age over 64, then there is no way it can contain an age under that.
Therefore, there is no value that could be stored in the age field of a movie patron record for which both
parts of the AND question are true—and the price will never be set to the discountPrice for any record.
Figure 6-20 shows the correct logic.
FIGURE 6-19: INCORRECT LOGIC THAT ATTEMPTS TO PROVIDE A DISCOUNT FOR MOVIE PATRONS UNDER 13 AND FOR MOVIE
PATRONS OVER 64
FIGURE 6-20: CORRECT LOGIC THAT PROVIDES A DISCOUNT FOR MOV Table 2-2 Commonly used TCP/IP classes
A similar error can occur in your logic if the theater manager says something like, “Don’t give a discount—
that is, charge full price—if a patron is over 12 or under 65.” Because the word “or” appears in the request,
you might plan your logic like that shown in Figure 6-21.
130
FIGURE 6-21: INCORRECT LOGIC THAT ATTEMPTS TO CHARGE FULL PRICE FOR MOVIE PATRONS OVER 12
AND UNDER 65
As in Figure 6-19, in Figure 6-21, no patron ever receives a discount, because every patron is either over
12 or under 65. Remember, in an OR decision, only one of the conditions needs to be true in order for the
entire expression to be evaluated as true. So, for example, because a patron who is 10 is under 65, the full
price is charged, and because a patron who is 70 is over 12, the full price also is charged. Figure 6-22 shows
the correct logic for this decision.
FIGURE 6-22: CORRECT LOGIC THAT CHARGES FULL PRICE FOR MOVIE PATRONS OVER 12 AND UNDER 65
You can write a program that creates a report containing all employees who have either medical or dental
insurance by using the createReport() method in either Figure 6-23 or Figure 6-24.
131
FIGURE 6-23: THE createReport() MODULE TO SELECT EMPLOYEES WITH MEDICAL OR DENTAL INSURANCE,
USING MEDICAL DECISION FIRST
132
FIGURE 6-24: ALTERNATE createReport() MODULE TO SELECT EMPLOYEES WITH MEDICAL OR DENTAL
INSURANCE, USING DENTAL DECISION FIRST
You might have guessed that one of these selections is superior to the other, if you have some background
information about the relative likelihood of each condition you are testing. For example, once again
assume you know that out of 1,000 employees in your company, about 90 percent, or 900, participate in
the medical insurance plan, and about half, or 500, participate in the dental plan.
When you use the logic shown in Figure 6-23 to select employees who participate in either insurance plan,
you first ask about medical insurance. For 900 employees, the answer is true; you print these employee
records. Only about 100 records continue to the next question regarding dental insurance, where about
half, or 50, fulfill the requirements to print. In the end, you print about 950 employees.
If you use Figure 6-24, you ask empDentalIns = “Y”? first. The result is true for 50 percent, or 500
employees, whose names then print. Five hundred employee records then progress to the medical
insurance question, after which 90 percent, or 450, of them print.
Using either scenario, 950 employee records appear on the list, but the logic used in Figure 6-23 requires
1,100 decisions, whereas the logic used in Figure 6-24 requires 1,500 decisions. The general rule is: In an
OR decision, first ask the question that is more likely to be true. Because a record qualifies for printing as
soon as it passes one test, asking the more likely question first eliminates as many records as possible from
having to go through the second decision. The time it takes to execute the program is decreased.
6.8 COMBINING DECISIONS IN AN OR SELECTION
When you need to take action when either one or the other of two conditions is met, you can use two
separate, nested selection structures, as in the previous examples. However, most programming languages
allow you to ask two or more questions in a single comparison by using a logical OR operator—for example,
empDentalIns = “Y” OR empMedicalIns = “Y”. When you use the logical OR operator, only one of the listed
conditions must be met for the resulting action to take place. If the programming language you use allows
this construct, you still must realize that the question you place first is the question that will be asked first,
and cases eliminated by the first question will not proceed to the second question. The computer can ask
only one question at a time; even when you draw the flowchart in Figure 6-25, the computer will execute
the logic in the flowchart in Figure 6-26.
133
FIGURE 6-26: FLOWCHART AND PSEUDOCODE OF COMPUTER LOGIC OF PROGRAM CONTAINING AN OR
OPERATOR IN THE DECISION; THE COMPUTER STILL MAKES TWO SEPARATE DECISIONS EVEN THOUGH AN
OR OPERATOR IS USED
Business programs often need to make selections based on a variable falling within a range of values. For
example, suppose you want to print a list of all employees and the names of their supervisors. An
employee’s supervisor is assigned according to the employee’s department number, as shown in Figure 6-
27.
DEPARTMENT NUMBER SUPERVISOR
1–3 Dillon
4—7 Escher
8—9 Fontana
FIGURE 6-27: SUPERVISORS BY DEPARTMENT
When you write the program that reads each employee’s record, you could make nine decisions before
printing the supervisor’s name, such as empDept = 1?, empDept = 2?, and so on. However, it is more
convenient to find the supervisor by using a range check.
When you use a range check, you compare a variable to a series of values between limits. To perform a
range check, make comparisons using either the lowest or highest value in each range of values you are
using. For example, to find each employee’s supervisor as listed in Figure 6-27, either use the values 1, 4,
and 8, which represent the low ends of each supervisor’s department range, or use the values 3, 7, and 9,
which represent the high ends.
Figure 6-27 shows the flowchart and pseudocode that represent the logic for choosing a supervisor name
by using the high-end range values. You test the empDept value for less than or equal to the high end of
the lowest range group. If the comparison evaluates as true, you know the intended value of
supervisorName. If not, you continue checking.
134
FIGURE 6-28: USING HIGH-END VALUES FOR A RANGE CHECK
For example, consider records containing three different values for empDept, and compare how they
would be handled by the set of decisions in Figure 6-28.
First, assume that the value of empDept for a record is 2. Using the logic in Figure 5-31, the value of
the Boolean expression empDept <= 3 is true, supervisorName is set to “Dillon”, and the if structure
ends. In this case, the second decision, empDept <= 7, is never made, because the else half of
empDept <= 3 never executes.
Next, assume that for another record, the value of empDept is 7. Then, empDept <= 3 evaluates as
false, so the else clause of the decision executes. There, empDept <= 7 is evaluated, and found to
be true, so supervisorName becomes “Escher”.
Finally, assume that the value of empDept is 9. In this case, the first decision, empDept <= 3, is false,
so the else clause executes. Then, the second decision, empDept <=7, also evaluates as false, so
the else clause of the second decision executes, and supervisorName is set to “Fontana”. In
this example, “Fontana” can be called a default value, because if neither of the two decision
expressions is true, supervisorName becomes “Fontana” by default. A default value is the value
assigned after a series of selections are all false.
The flowchart and pseudocode for choosing a supervisor name using the reverse of this method, by
comparing the employee department to the low end of the range values that represent each
supervisor’s area, appear in Figure 6-29.
Using the technique shown in Figure 6-29, you compare empDept to the low end (8) of the highest range
(8 to 9) first; if empDept falls in the range, supervisorName is known; otherwise, you check the next lower
group. In this example, “Dillon” becomes the default value. That is, if the department number is not
greater than or equal to 8, and it is also not greater than or equal to 4, then by default, supervisorName is
set to “Dillon”.
135
FIGURE 6-29: USING LOW-END VALUES OF RANGES TO DETERMINE EMPLOYEE’S SUPERVISOR
Two common errors that occur when programmers perform range checks both entail doing more work
than is necessary. Figure 6-30 shows a range check in which the programmer has asked one question too
many. If you know that all empDept values are positive numbers, then if empDept is not greater than or
equal to 8, and it is also not greater than or equal to 4, then by default it must be greater than or equal to
1. Asking whether empDept is greater than or equal to 1 is a waste of time; no employee record can ever
travel the logical path on the far left. You might say that the path that can never be traveled is a dead or
unreachable path, and that the statements written there constitute dead or unreachable code. Providing
such a path is always a logical error.
Another error that programmers make when writing the logic to perform a range check also involves asking
unnecessary questions. You should never ask a question if there is only one possible answer or outcome.
Figure 6-31 shows an inefficient range selection that asks two unneeded questions. In the figure, if
empDept is greater than or equal to 8, “Fontana” is the supervisor. If empDept is not greater than or equal
to 8, then it must be less than 8, so the next question does not have to check for less than 8. The computer
136
logic will never execute the second decision unless empDept is already less than 8— that is, unless it
follows the false branch of the first selection. If you use the logic in Figure 6-31, you are wasting computer
time asking a question that has previously been answered. Similarly, if empDept is not greater than or
equal to 8 and it is also not greater than or equal to 4, then it must be le ss than 4. Therefore, there is no
reason to compare empDept to 4 to determine whether “Dillon” is the supervisor. If the logic makes it past
the first two if statements in Figure 6-31, then the supervisor must be “Dillon”.
Most programming languages allow you to combine as many AND and OR operators in an expression as
you need. For example, assume you need to achieve a score of at least 75 on each of three tests in order
to pass a course. When multiple conditions must be true before performing an action, you can use an
expression like the following:
if score1 >= 75 AND score2 >= 75 AND score3 >= 75 then classGrade
= “Pass”
else
classGrade = “Fail”
endif
On the other hand, if you need to pass only one test in order to pass the course, then the logic is as
follows: if score1 >= 75 OR score2 >= 75 OR score3 >= 75 then classGrade = “Pass”
else
classGrade = “Fail”
endif
The logic becomes more complicated when you combine AND and OR operators within the same
statement. When you combine AND and OR operators, the AND operators take precedence, meaning their
Boolean values are evaluated first.
137
For example, consider a program that determines whether a movie theater patron can purchase a
discounted ticket. Assume discounts are allowed for children (age 12 and under) and senior citizens (age
65 and older) who attend “G”-rated movies. The following code looks reasonable, but produces
incorrect results, because the AND operator evaluates before the OR.
For example, assume a movie patron is 10 years old and the movie rating is “R”. The patron should not
receive a discount—or be allowed to see the movie! However, within the previous if statement, the part
of the expression containing the AND, age >= 65 AND rating = “G”, evaluates first. For a 10-year-old and
an “R”-rated movie, the question is false (on both counts), so the entire if statement becomes the
equivalent of the following:
if age <= 12 OR aFalseExpression
Because the patron is 10, age <= 12 is true, so the original if statement becomes the equivalent of:
if aTrueExpression OR aFalseExpression
which evaluates as true. Therefore, the statement “Discount applies” prints when it should not.
Many programming languages allow you to use parentheses to correct the logic and force the
expression age <= 12 OR age >= 65 to evaluate first, as shown in the following pseudocode:
if (age <= 12 OR age >= 65) AND rating = “G” then
print “Discount applies”
With the added parentheses, if the patron’s age is 12 or under OR 65 or over, the expression is
evaluated as:
if aTrueExpression AND rating = “G”
When the age value qualifies a patron for a discount, then the rating value must also be acceptable before
the discount applies. This was the original intention of the statement.
You always can avoid the confusion of mixing AND and OR decisions by nesting if statements instead of
using ANDs and ORs. With the flowchart and pseudocode shown in Figure 6-32, it is clear which movie
patrons receive the discount.
In the flowchart in the figure, you can see that the OR is nested entirely within the Yes branch of the rating
= “G”? selection. Similarly, by examining the pseudocode in Figure 6-32, you can see by the alignment that
if the rating is not “G”, the logic proceeds directly to the last endif statement, bypassing any checking of
the age at all.
138
FIGURE 6-32: NESTED if LOGIC THAT DETERMINES MOVIE PATRON DISCOUNTS
When you have a series of decisions based on the value stored in a single variable, most languages allow
you to use a case structure. You first learned about the case structure in Chapter 2. There, you learned
that you can solve any programming problem using only the three basic structures—sequence,
selection, and loop. You are never required to use a case structure—you can always substitute a series of
nested selections. The case structure simply provides a convenient alternative to using a series of decisions
when you must make choices based on the value stored in a single variable.
For example, suppose you work for a real estate developer who is selling houses that have one of three
different floor plans. The logic segment of a program that determines the base price of the house might
look like the logic shown in Figure 6-33.
139
FIGURE 6-33: FLOWCHART AND PSEUDOCODE DETERMINING HOUSE MODEL PRICE USING ifS
The logic shown in Figure 6-33 is completely structured. However, rewriting the logic using a case structure,
as shown in Figure 6-34, might make it easier to understand. When using the case structure, you test a
variable against a series of values, taking appropriate action based on the variable’s value.
FIGURE 6-34: FLOWCHART AND PSEUDOCODE DETERMINING HOUSE MODEL PRICE USING THE CASE
STRUCTURE
In Figure 6-34, the model variable is compared in turn with “Arlington”, “BelAire”, and “Carrington”, and
an appropriate basePrice value is set. The default case is the case that executes in the event no other
cases execute. The logic shown in Figure 6-33 is identical to that shown in Figure 6-34; your choice of
method to set the housing model prices is entirely a matter of preference.
140
6.9.3 USING DECISION TABLES
Some programs require multiple decisions to produce the correct output. Managing all possible outcomes
of multiple decisions can be a difficult task, so programmers sometimes use a tool called a decision table
to help organize the possible decision outcome combinations.
CHAPTER SUMMARY
Every decision you make in a computer program involves evaluating a Boolean expression. You can
use dual-alternative, or binary, selections or if-then-else structures to choose between two possible
outcomes. You also can use single-alternative, or unary, selections or if-then structures when there
is only one outcome for the question where an action is required.
For any two values that are the same type, you can use relational comparison operators to decide
whether the two values are equal, the first value is greater than the second value, or the first value
is less than the second value. The two values used in a Boolean expression can be either variables
or constants.
An AND decision occurs when two conditions must be true in order for a resulting action to take
place. An AND decision requires a nested decision, or a nested if.
In an AND decision, first ask the question that is less likely to be true. This eliminates as many records
as possible from having to go through the second decision, which speeds up processing time.
Most programming languages allow you to ask two or more questions in a single comparison by using
a logical AND operator.
When you must satisfy two or more criteria to initiate an event in a program, you must make sure
that the second decision is made entirely within the first decision, and that you use a complete
Boolean expression on both sides of the AND.
An OR decision occurs when you want to take action when one or the other of two conditions is true.
Errors occur in OR decisions when programmers do not maintain structure. An additional source of
errors that are particular to the OR selection stems from people using the word AND to express OR
requirements.
In an OR decision, first ask the question that is more likely to be true.
Most programming languages allow you to ask two or more questions in a single comparison by using
a logical OR operator.
To perform a range check, make comparisons with either the lowest or highest value in each range
of values you are using.
Common errors that occur when programmers perform range checks include asking unnecessary and
previously answered questions.
The case structure provides a convenient alternative to using a series of decisions when you must make
choices based on the value stored in a single variable.
141
A decision table is a problem-analysis tool that consists of conditions, possible combinations of
Boolean values for the conditions, possible actions based on the conditions, and the action that
corresponds to each Boolean value of each condition.
KEY TERMS
A dual-alternative, or binary, selection structure offers two actions, each associated with one of two
possible outcomes.
It is also called an if-then-else structure.
In a single-alternative, or unary, selection structure, an action is required for only one outcome of
the question. You call this form of the selection structure an if-then, because no “else” action is
necessary.
The if clause of a decision holds the action or actions that execute when a Boolean expression in a
decision is true.
The else clause of a decision holds the action or actions that execute when the Boolean
expression in a decision is false.
A Boolean expression is one that represents only one of two states, usually expressed as true or false.
A trivial Boolean expression is one that always evaluates to the same result.
Relational comparison operators are the symbols that express Boolean comparisons. Examples
include =, >, <, >=, <=, and <>.
A logical operator (as the term is most often used) compares single bits. However, some
programmers use the term synonymously with “relational comparison operator.”
With an AND decision, two conditions must both be true for an action to take place. An AND decision
requires a nested decision, or a nested if—that is, a decision “inside of” another decision. A
series of nested if statements can also be called a cascading if statement.
logical AND operator is a symbol that you use to combine decisions so that two (or more)
conditions must be true for an action to occur.
Short-circuiting is the compiler technique of not evaluating an expression when the outcome makes
no difference.
A range of values encompasses every value between a high and low limit.
An OR decision contains two (or more) decisions; if at least one condition is met, the resulting action
takes place.
A logical OR operator is a symbol that you use to combine decisions when any one condition can be
true for an action to occur.
When you use a range check, you compare a variable to a series of values between limits.
A default value is one that is assigned after all test conditions are found to be false.
A dead or unreachable path is a logical path that can never be traveled.
When an operator has precedence, it is evaluated before others.
The case structure provides a convenient alternative to using a series of decisions when you must
make choices based on the value stored in a single variable.
142
A decision table is a problem-analysis tool that consists of four parts: conditions, possible
combinations of Boolean values for the conditions, possible actions based on the conditions, and
the specific action that corresponds to each Boolean value of each condition.
REVIEW QUESTIONS
1. The selection statement if quantity > 100 then discountRate = 0.20 is an example of a .
a. single-alternative selection
b. dual-alternative selection
c. binary selection
d. all of the above
2. The selection statement if dayOfWeek = “S” then price = 5.00 else price = 6.00 is an example of a .
a. unary selection
b. single-alternative selection
c. binary selection
d. all of the above
7. If you could use only three relational comparison operators, you could get by with .
a. greater than, less than, and greater than or equal to
b. less than, less than or equal to, and not equal to
c. equal to, less than, and greater than
d. equal to, not equal to, and less than
143
8. If a > b is false, then which of the following is always true? a.
a<b
b. a <= b
c. a = b
d. a >= b
9. Usually, the most difficult comparison operator to work with is .
a. equal to
b. greater than
c. less than
d. not equal to
11. The Midwest Sales region of Acme Computer Company consists of five states—Illinois, Indiana, Iowa,
Missouri, and Wisconsin. Suppose you have input records containing Acme customer data, including
state of residence. To most efficiently select and display all customers who live in the Midwest Sales
region, you would use .
a. five completely separate unnested if statements
b. nested if statements using AND logic
c. nested if statements using OR logic
d. Not enough information is given.
12. The Midwest Sales region of Acme Computer Company consists of five states—Illinois, Indiana, Iowa,
Missouri, and Wisconsin. About 50 percent of the regional customers reside in Illinois, 20 percent in
Indiana, and 10 percent in each of the other three states. Suppose you have input records containing
Acme customer data, including state of residence. To most efficiently select and display all customers
who live in the Midwest Sales region, you would ask first about residency in _. a. Illinois
b. Indiana
c. Wisconsin
d. either Iowa, Missouri, or Wisconsin—it does not matter which one is first
13. The Boffo Balloon Company makes helium balloons. Large balloons cost $13 a dozen, mediumsized
balloons cost $11 a dozen, and small balloons cost $8.60 a dozen. About 60 percent of the company’s
sales are the smallest balloons, 30 percent are the medium, and large balloons constitute only 10 percent
of sales. Customer order records include customer information, quantity ordered, and size. When you
write a program to determine price based on size, for the most efficient decision, you should ask first
whether the size is . a. large
b. medium
c. small
144
d. It does not matter.
14. The Boffo Balloon Company makes helium balloons in three sizes, 12 colors, and with a choice of
40 imprinted sayings. As a promotion, the company is offering a 25 percent discount on orders of large,
red “Happy Valentine’s Day” balloons. To most efficiently select the orders to which a discount applies,
you would use .
a. three completely separate unnested if statements
b. nested if statements using AND logic
c. nested if statements using OR logic
d. Not enough information is given.
15. Radio station FM-99 keeps a record of every song played on the air in a week. Each record contains
the day, hour, and minute the song started, and the title and artist of the song. The station manager
wants a list of every title played during the important 8 a.m. commute hour on the two busiest traffic
days, Monday and Friday. Which logic would select the correct titles? a. if day =
“Monday” OR day = “Friday” OR hour = 8 then print title
endif
b. if day = “Monday” then
if hour = 8 then
print title
else
if day = “Friday” then
print title
endif endif
endif
c. if hour = 8 AND day = “Monday” OR day = “Friday” then
print title
endif
d. if hour = 8 then
if day = “Monday” OR day = “Friday” then print
title
endif
endif
16. In the following pseudocode, what percentage raise will an employee in Department 5 receive?
if department < 3 then raise = 25
else
if department < 5 then raise
= 50
else raise = 75
endif
endif
a. 25
b. 50
c. 75
d. impossible to tell
145
17. In the following pseudocode, what percentage raise will an employee in Department 8 receive? if
department < 5 then
raise = 100
else
if department < 9 then
raise = 250
else
if department < 14 then
raise = 375
endif
endif
endif a. 100 b. 250
c. 375 d. impossible to tell
18. In the following pseudocode, what percentage raise will an employee in Department 10 receive?
if department < 2 then raise = 1000
else
if department < 6 then raise
= 2500
else
if department < 10 then raise
= 3000
endif endif
endif
a. 1000
b. 2500
c. 3000
d. impossible to tell
19. When you use a range check, you compare a variable to the value in the range. a.
lowest
b. middle
c. highest
d. lowest or highest
146
20. Which of the following is not a part of a decision table? a.
conditions
b. declarations
c. possible actions
d. specific actions that will take place under given conditions
Each of the following pseudocode segments contains one or more bugs that you must find and correct.
1. This pseudocode should create a report containing annual profit statistics for a retail store. Input
records contain a department name (for example, “Cosmetics”) and profits for each quarter for the last
two years. For each quarter, the program should determine whether the profit is higher, lower, or the
same as in the same quarter of the previous year. Additionally, the program should determine whether
the annual profit is higher, lower, or the same as in the previous year. For example, the line that displays
the Cosmetics Department statistics might read “Cosmetics Same Lower Lower Higher Higher” if profits
were the same in the first quarter as last year, lower in the second and third quarters, but higher in the
fourth quarter and for the year as a whole.
start
perform housekeeping()
while not eof
perform detrmineProfitStatistics()
perform finalTasks()
stop
housekeeping() declare
variables
profitRec char department num
salesQuarter1ThisYear num
salesQuarter2ThisYear num
salesQuarter2ThisYear num
salesQuarter4ThisYear num
salesQuarter1LastYear num
salesQuarter2LastYear num
salesQuarter3ThisYear num
salesQuarter4LastYear char mainHead =
“Profit Report” char columnHeaders =
“Department Quarter 1
Quarter 2 Quarter 3 Quarter 4 Over All”
num totalThisYear num totalLastYear char word1 char
word2 char word3 char word4 char word5 open files
perform printHeadings()
read profitRec return
147
printHeadings() print
mainHeader print
columnHeaders return
finalTasks()
close files return
2. This pseudocode should create a report containing rental agents’ commissions at an apartment
complex. Input records contain an apartment number, the ID number and name of the agent who rented
the apartment, and the number of bedrooms in the apartment. The commission is $100 for renting a
three-bedroom apartment, $75 for renting a two-bedroom apartment, $55 for renting a one- bedroom
apartment, and $30 for renting a studio (zero-bedroom) apartment. Each report line should list the
apartment number, the salesperson’s name and ID number, and the commission earned on the rental.
start
perform housekeeping()
while not eof perform
calculateCommission() perform
finishUp()
stop
149
displayHeader() print
mainHeader print
columnHeaders return
commissionEarned
read rentalRecord
return finishUp()
close files return
EXERCISES
For each of the following Boolean expressions, decide whether the statement is true, false, or illegal. a.
numberRed = numberBlue?
b. numberBlue > numberGreen?
c. numberGreen < numberRed?
d. numberBlue = wordBlue?
e. numberGreen = “Green”?
f. wordRed = “Red”?
g. wordBlue = “Blue”?
h. numberRed <= numberGreen?
i. numberBlue >= 200?
j. numberGreen >= numberRed + numberBlue?
2. A candy company wants a list of its best-selling items, including the item number and the name of
candy. Best-selling items are those that sell over 2,000 pounds per month. Input records contain fields
for the item number (three digits), the name of the candy (20 characters), the price per pound (four
digits, two assumed decimal places), and the quantity in pounds sold last month (four digits, no
decimals).
a. Design the output for this program; create either sample output or a print chart.
150
b. Draw the hierarchy chart for this program.
c. Draw the flowchart for this program.
d. Write the pseudocode for this program.
3. The same candy company described in Exercise 2 wants a list of its high-priced, best-selling items.
Best-selling items are those that sell over 2,000 pounds per month. High-priced items are those that sell
for $10 per pound or more.
a. Design the output for this program; create either sample output or a print chart.
b. Draw the hierarchy chart for this program.
c. Draw the flowchart for this program.
d. Write the pseudocode for this program.
4. The Literary Honor Society needs a list of English majors who have a grade point average of 3.5 or
higher. The student record file includes students’ last names and first names, major (for example,
“History” or “English”), and grade point average (for example, 3.9 or 2.0).
a. Design the output for this program; create either sample output or a print chart.
b. Draw the hierarchy chart for this program.
c. Draw the flowchart for this program.
d. Write the pseudocode for this program.
5. A telephone company charges 10 cents per minute for all calls outside the customer’s area code that
last over 20 minutes. All other calls are 13 cents per minute. The phone company has a file with one
record for every call made in one day. (In other words, a single customer might have many such records
on file.) Fields for each call include customer area code (three digits), customer phone number (seven
digits), called area code (three digits), called number (seven digits), and call time in minutes (never more
than four digits). The company wants a report listing one detail line for each call, including the
customer area code and number, the called area code and number, the minutes, and the total charge.
a. Design the output for this program; create either sample output or a print chart.
b. Draw the hierarchy chart for this program.
c. Create a decision table to use while planning the logic for this program.
d. Draw the flowchart for this program.
e. Write the pseudocode for this program.
6. A nursery maintains a file of all plants in stock. Each record contains the name of a plant, its price, and
fields that indicate the plant’s light and soil requirements. The light field contains either “sunny”, “partial
sun”, or “shady”. The soil field contains either “clay” or “sandy”. Only 20 percent of the nursery stock
does well in shade, and 50 percent does well in sandy soil. Customers have requested a report that lists
the name and price of each plant that would be appropriate in a shady, sandy yard. Consider program
efficiency when designing your solution.
a. Design the output for this program; create either sample output or a print chart.
b. Draw the hierarchy chart for this program.
c. Create a decision table to use while planning the logic for this program.
d. Draw the flowchart for this program.
151
e. Write the pseudocode for this program.
Draw the flowchart or write the pseudocode for the selection structures that print the
custPolicyNumber and custLastName for customers whose data satisfy the following requests for lists of
policyholders:
8. Student files contain an ID number (four digits), last and first names (15 characters each), and major
field of study (10 characters). Plan a program that lists ID numbers and names for all French or Spanish
majors.
a. Design the output for this program; create either sample output or a print chart.
b. Draw the hierarchy chart for this program.
c. Create a decision table to use while planning the logic for this program.
d. Draw the flowchart for this program.
e. Write the pseudocode for this program.
9. A florist wants to send coupons to her best customers, so she needs a list of names and addresses for
customers who placed orders more than three times last year or spent more than $200 last year.
Consider program efficiency when designing your solution. The input file description follows:
152
(Note: To save room, the record does not include a city or state. Assume that all the florist’s best
customers are in town.)
a. Design the output for this program; create either sample output or a print chart.
b. Draw the hierarchy chart for this program.
c. Create a decision table to use while planning the logic for this program.
d. Draw the flowchart for this program.
e. Write the pseudocode for this program.
10. A carpenter needs a program that computes the price of any desk a customer orders, based on the
following input fields: order number, desk length and width in inches (three digits each, no decimals),
type of wood (20 characters), and number of drawers (two digits). The price is computed as follows:
a. Design the output for this program; create either sample output or a print chart.
b. Draw the hierarchy chart for this program.
c. Create a decision table to use while planning the logic for this program.
d. Draw the flowchart for this program.
e. Write the pseudocode for this program.
11. A company is attempting to organize carpools to save energy. Each input record contains an
employee’s name and town of residence. Ten percent of the company’s employees live in Wonder Lake.
Thirty percent of the employees live in Woodstock. Because these towns are both north of the company,
the company wants a list of employees who live in either town, so it can recommend that these
employees drive to work together.
a. Design the output for this program; create either sample output or a print chart.
b. Draw the hierarchy chart for this program.
c. Create a decision table to use while planning the logic for this program.
d. Draw the flowchart for this program.
e. Write the pseudocode for this program.
153
12. A supervisor in a manufacturing company wants to produce a report showing which employees have
increased their production this year over last year, so that she can issue them a certificate of
commendation. She wants to have a report with three columns: last name, first name, and either the
word “UP” or blanks printed under the column heading PRODUCTION. “UP” is printed when this year’s
production is a greater number than last year’s production. Input exists as follows:
a. Design the output for this program; create either sample output or a print chart.
b. Draw the hierarchy chart for this program.
c. Create a decision table to use while planning the logic for this program.
d. Draw the flowchart for this program.
e. Write the pseudocode for this program.
13. A supervisor in the same manufacturing company as described in Exercise 12 wants to produce a
report from the PRODUCTION input file showing bonuses she is planning to give based on this year’s
production. She wants to have a report with three columns: last name, first name, and bonus. The
bonuses will be distributed as follows.
If this year’s production is:
1,000 units or fewer, the bonus is $25
1,001 to 3,000 units, the bonus is $50
3,001 to 6,000 units, the bonus is $100
6,001 units and up, the bonus is $200
a. Design the output for this program; create either sample output or a print chart.
b. Draw the hierarchy chart for this program.
c. Create a decision table to use while planning the logic for this program.
d. Draw the flowchart for this program.
e. Write the pseudocode for this program.
14. Modify Exercise 13 to reflect the following new facts, and have the program execute as efficiently as
possible:
Only employees whose production this year is higher than it was last year will receive bonuses. This
is true for approximately 30 percent of the employees.
Sixty percent of employees produce over 6,000 units per year; 20 percent produce 3,001 to 6,000;
15 percent produce 1,001 to 3,000 units; and only 5 percent produce fewer than 1,001.
a. Design the output for this program; create either sample output or a print chart.
b. Draw the hierarchy chart for this program.
154
c. Create a decision table to use while planning the logic for this program.
d. Draw the flowchart for this program.
e. Write the pseudocode for this program.
15. The Richmond Riding Club wants to assign the title of Master or Novice to each of its members. A
member earns the title of Master by accomplishing two or more of the following:
Create a report that prints each club member’s name along with the designation “Master” or
“Novice”. Input exists as follows:
a. Design the output for this program; create either sample output or a print chart.
b. Draw the hierarchy chart for this program.
c. Create a decision table to use while planning the logic for this program.
d. Draw the flowchart for this program.
e. Write the pseudocode for this program.
16. Freeport Financial Services manages clients’ investment portfolios. The company charges for its
services based on each client’s annual income, net worth, and length of time as a client, as follows:
Clients with an annual income over $100,000 and a net worth over $1 million are charged 1.5 percent
of their net worth.
Clients with an annual income over $100,000 and a net worth between $500,000 and $1 million
inclusive are charged $8,000.
Clients with an annual income over $100,000 and a net worth of less than $500,000 are charged
$6,000.
Clients with an annual income from $75,000 up to and including $100,000 are charged 1 percent of
their net worth.
Clients with an income of $75,000 or less are charged $4,000, unless their net worth is over $1
million, in which case they are charged $4,500.
Any client for over four years gets a 10 percent discount; any client for over seven years gets a 15
percent discount.
155
Create a report that prints each client’s name and the client’s annual fee. Input records contain the
following data:
a. Design the output for this program; create either sample output or a print chart.
b. Draw the hierarchy chart for this program.
c. Create a decision table to use while planning the logic for this program.
d. Draw the flowchart for this program.
e. Write the pseudocode for this program.
TOPIC 7
7. LOOPING
LEARNING OUTCOMES
After Studying this topic you should be able to:
Understand the advantages of looping
Control a while loop using a loop control variable
Increment a counter to control a loop
Loop with a variable sentinel value
Control a loop by decrementing a loop control variable
Avoid common loop mistakes
Use a for statement
Use do while and do until loops
Recognize the characteristics shared by all loops
Nest loops
Use a loop to accumulate totals
Understand control break logic
Perform single-level control breaks
Perform multiple-level control breaks
156
If making decisions is what makes computers seem intelligent, it’s looping that makes computer
programming worthwhile. When you use a loop within a computer program, you can write one set of
instructions that operates on multiple, unique sets of data. Consider the following set of tasks required for
each employee in a typical payroll program:
In reality, this list is too short—companies deduct stock option plans, charitable contributions, union dues,
and other items from checks in addition to the items mentioned in this list. Also, they might pay bonuses
and commissions and provide sick days and vacation days that must be taken into account and handled
appropriately. As you can see, payroll programs are complicated.
The advantage of having a computer perform payroll calculations is that all of the deduction instructions
need to be written only once and can be repeated over and over again for each paycheck using a loop, the
structure that repeats actions while some condition continues.
7.2 USING A WHILE LOOP WITH A LOOP CONTROL VARIABLE
Recall the loop, or while structure, that you learned about in Chapter 2. (See Figure 7-1.) In Chapter 4, you
learned that almost every program has a main loop, or a basic set of instructions that is repeated for every
record. The main loop is a typical loop—within it, you write one set of instructions that executes repeatedly
while rec ords continue to be read from an input file. Several housekeeping tasks execute at the start of
most programs, and a few cleanup tasks execute at the end. However, most of a program’s tasks are
located in a main loop; these tasks repeat over and over for many records (sometimes hundreds,
thousands, or millions).
In addition to this main loop, loops also appear within a program’s modules. They are used any time you
need to perform a task several times and don’t want to write identical or similar instructions over and
over. Suppose, for example, as part of a much larger program, you want to print a warning message on the
computer screen when the user has made a potentially dangerous menu selection (for example, “Delete
all files”). To get the user’s attention, you want to print the message four times. You can write this program
157
segment as a sequence of four steps, as shown in Figure 7-2, but you can also use a loop, as shown in
Figure 7-3.
On each pass through the loop, the value in the rep variable determines whether the loop will continue.
Therefore, variables like rep are known as loop control variables. Any variable that determines whether a
loop will continue to execute is a loop control variable. To stop a loop’s execution, you compare the loop
control value to a sentinel value (also known as a limit or ending value), in this case the value 5. The
decision that controls every loop is always based on a Boolean comparison. You can use any of the six
comparison operators that you learned about in Chapter 5 to control a loop—equal to, greater than, less
than, greater than or equal to, less than or equal to, and not equal to.
The statements that execute within a loop are known as the loop body. The body of a loop might contain
any number of statements, including method calls, sequences, decisions, and other loops. Once your
program enters the body of a structured loop, the entire loop body must execute. Your program can leave
a structured loop only at the comparison that tests the loop control variable.
158
Suppose you own a factory and have decided to place a label on every product you manufacture. The label
contains the words “Made for you personally by ” followed by the first name of one of your employees.
For one week’s production, suppose you need 100 personalized labels for each employee.
Assume you already have a personnel file that can be used for input. This file has more information than
you’ll need for this program: an employee last name, first name, Social Security number, address, date
hired, and salary. The important feature of the file is that it does contain each employee’s name stored in
a separate record. The input file description appears in Figure 7-4.
In the mainline logic of this program, you call three modules: a housekeeping module (housekeep()), a
main loop module (createLabels()), and a finish routine (finishUp()). See Figure 7-5.
The first task for the label-making program is to name the fields in the input record so you can refer to
them within the program. As a programmer, you can choose any variable names you like, for example:
inLastName, inFirstName, inSSN, inAddress, inDate, and inSalary.
You also can set up a variable to hold the characters “Made for you personally by ” and name it labelLine.
You eventually will print this labelLine variable followed by the employee’s first name (inFirstName).
You will need one more variable: a location to be used as a counter. A counter is any numeric variable you
use to count the number of times an event has occurred; in this example, you need a counter to keep track
of how many labels have been printed at any point. Each time you read an employee record, the counter
variable is set to 0. Then every time a label is printed, you add 1 to the counter. Adding to a variable is
159
called incrementing the variable; programmers often use the term “incrementing” specifically to mean
“increasing by one.” Before the next employee label is printed, the program checks the variable to see if it
has reached 100 yet. When it has, that means 100 labels have been printed, and the job is done for that
employee. While the counter remains below 100, you continue to print labels. As with all variables, the
programmer can choose any name for a counter; this program uses labelCounter. In this example,
labelCounter is the loop control variable.
The housekeep() module for the label program, shown in Figure 7-6, includes a step to open the files: the
employee file and the printer. Unlike a program that produces a report, this program produces no
headings, so the next and last task performed in housekeep() is to read the first input record.
When the housekeep() module is done, the logical flow returns to the eof question in the mainline logic. If
you attempt to read the first record at the end of housekeep() and for some reason there is no record, the
answer to eof? is Yes, so the createLabels() module is never entered; instead, the logic of the program
flows directly to the finishUp() module.
Usually, however, employee records will exist and the program will enter the createLabels() module, which
is shown in Figure 7-7. When this happens, the first employee record is sitting in memory waiting to be
processed. During one execution of the createLabels() module, 100 labels will be printed for one employee.
As the last event within the createLabels() module, the program reads the next employee record. Control
of the program then returns to the eof question. If the new read process has not resulted in the eof
condition, control reenters the createLabels() module, where 100 more labels print for the new employee.
160
FIGURE 7-7: THE createLabels() MODULE FOR THE LABEL PROGRAM
The createLabels() method of this label-making program contains three parts:
Set labelCounter to 0.
Compare labelCounter to 100. While labelCounter is less than 100, print labelLine and
inFirstName, and add 1 to labelCounter.
When the first employee record enters the createLabels() module, labelCounter is set to 0. The
labelCounter value is less than 100, so the record enters the label-making loop. One label prints for the
first employee, labelCounter increases by one, and the logical flow returns to the question labelCounter <
100?. After the first label is printed, labelCounter holds a value of only 1. It is nowhere near 100 yet, so the
value of the Boolean expression is true, and the loop is entered for a second time, thus printing a second
label.
After the second printing, labelCounter holds a value of 2. After the third printing, it holds a value of 3.
Finally, after the 100th label prints, labelCounter has a value of 100. When the question labelCounter <
100? is asked, the answer will finally be No, and the loop will exit.
Before leaving the createLabels() method, and after the program prints 100 labels for an employee, there
is one final step: the next input record is read from the EMPLOYEES file. When the createLabels() method
is over, control returns to the eof question in the main line of the logic. If it is not eof (if another employee
record is present), the program enters the createLabels() method again, resets labelCounter to 0, and
prints 100 new labels with the next employee’s name.
At some point while attempting to read a new record, the program encounters the end of the file, the
createLabels() module is not entered again, and control passes to the finishUp() module. In this
program, the finishUp() module simply closes the files. See Figure 7-8.
161
FIGURE 7-8: THE finishUp() MODULE FOR THE LABEL PROGRAM
Sometimes you don’t want to be forced to repeat every pass through a loop the same number of times.
For example, instead of printing 100 labels for each employee, you might want to vary the number of labels
based on how many items a worker actually produces. That way, high-achieving workers won’t run out of
labels, and less productive workers won’t have too many. Instead of printing the same number of labels
for every employee, a more sophisticated program prints a different number for each employee,
depending on that employee’s production the previous week. For example, you might decide to print
enough labels to cover 110 percent of each employee’s production rate from the previous week; this
ensures that the employee will have enough labels for the week, even if his or her production level
improves.
For example, assume that employee production data exists in an input file called EMPPRODUCTION in the
format shown in Figure 7-9.
A real-life production file would undoubtedly have more fields in each record, but these fields supply more
than enough information to produce the labels. You need the first name to print on the label, and you
need the field that holds production for the last week in order to calculate the number of labels to print
for each employee. Assume this field can contain any number from 0 through 999.
To write a program that produces an appropriate number of labels for each employee, you can make some
minor modifications to the original label-making program. For example, the input file variables have
changed; you must delare a variable for an inLastProduction field. Additionally, you might want to create
a numeric field named labelsToPrint that can hold a value equal to 110 percent of a worker’s
inLastProduction.
The major modification to the original label-making program is in the question that controls the label-
producing loop. Instead of asking if labelCounter < 100, you now can ask if labelCounter < labelsToPrint.
The sentinel, or limit, value can be a variable like labelsToPrint just as easily as it can be a constant like
100. See Figure 7-10 for the flowchart as well as the pseudocode.
162
FIGURE 7-10: FLOWCHART AND PSEUDOCODE FOR LABEL-MAKING createLabels() MODULE
7.2.3 LOOPING BY DECREMENTING
Rather than increasing a loop control variable until it passes some sentinel value, sometimes it is more
convenient to reduce a loop control variable on every cycle through a loop. For example, again assume
you want to print enough labels for every worker to cover 110 percent production. As an alternative to
setting a labelCounter variable to 0 and increasing it after each label prints, you initially can set
labelCounter equal to the number of labels to print (inLastProduction * 1.1), and subsequently reduce the
labelCounter value every time a label prints.
You continue printing labels and reducing labelCounter until you have counted down to zero. Decreasing
a variable is called decrementing the variable; programmers most often use the term to mean a
decrease by one.
For example, when you write the following, you produce enough labels to equal 110 percent of
inLastProduction:
When you decrement, you can avoid declaring a special variable for labelsToPrint. The labelCounter
variable starts with a value that represents the labels to print, and works its way down to zero.
163
Yet another alternative allows you to eliminate the labelCounter variable. You could use the
inLastProduction variable itself to keep track of the labels. For example, the following pseudocode segment
also produces a number of labels equal to 110 percent of each worker’s inLastProduction value:
In this example, inLastProduction is first increased by 10 percent. Then, while it remains above 0, there are
more labels to print; when it is eventually reduced to hold the value 0, all the needed labels will have been
printed. With this method, you do not need to create any new counter variables such as labelCounter,
because inLastProduction itself acts as a counter. However, you can’t use this method if you need to use
the value of inLastProduction for this record later in the program. By decrementing the variable, you are
changing its value on every cycle through the loop; when you have finished, the original value in
inLastProduction has been lost.
The mistakes that programmers make most often with loops are:
It is always a mistake to fail to initialize a loop’s control variable. For example, assume you remove the
statement labelCounter = 0 from the program illustrated in Figure 7-10. When labelCounter is compared
to labelsToPrint at the start of the while loop, it is impossible to predict whether any labels will print.
Because uninitialized values contain unknown, unpredictable garbage, comparing such a variable to
another value is meaningless. Even if you initialize labelCounter to 0 in the housekeep() module of the
program, you must reset labelCounter to 0 for each new record that is processed within the while loop. If
you fail to reset labelCounter, it never surpasses 100 because after it reaches 100, the answer to the
question labelCounter < 100 is always No, and the logic never enters the loop where a label can be printed.
A different sort of error occurs if you remove the statement that adds 1 to labelCounter from the program
in Figure 7-10. This error results in the following code:
164
Following this logic, if labelCounter is 0 and labelsToPrint is, for example, 110, then labelCounter will be
less than labelsToPrint forever. Nothing in the loop changes either variable, so when labelCounter is less
than labelsToPrint once, then labelCounter is less than labelsToPrint forever, and labels will continue to
print. A loop that never stops executing is called an infinite loop. It is unstructured and incorrect to create
a loop that cannot terminate on its own.
7.5 USING THE WRONG COMPARISON WITH THE LOOP CONTROL VARIABLE
Programmers must be careful to use the correct comparison in the statement that controls a loop.
Although there is only a one-keystroke difference between the following two code segments, one
performs the loop 10 times and the other performs the loop 11 times.
And
The seriousness of the error of using <= or >= when only < or > is needed depends on the actions performed
within the loop. For example, if such an error occurred in a loan company program, each customer might
be charged a month’s additional interest; if the error occurred in an airline’s program, it might overbook a
flight; and if it occurred in a pharmacy’s drug-dispensing program, each patient might receive one extra
(and possibly harmful) unit of medication.
7.6 INCLUDING STATEMENTS INSIDE THE LOOP THAT BELONG OUTSIDE THE LOOP
When you run a computer program that uses the loop in Figure 7-10, hundreds or thousands of employee
records might pass through the createLabels() method. If there are 100 employee records, then
labelCounter is set to 0 exactly 100 times; it must be reset to 0 once for each employee, in orde r to count
each employee’s labels correctly. Similarly, labelsToPrint is reset (to 1.1 times the current inLastProduction
value) once for each employee.
If the average employee produces 100 items during a week, then the loop within the createLabels()
method, the one controlled by the statement while labelCounter < labelsToPrint, executes 11,000 times—
110 times each for 100 employees. This number of repetitions is necessary in order to print the correct
number of labels.
165
A repetition that is not necessary would be to execute 11,000 separate multiplication statements to
recalculate the value to compare to labelCounter. See Figure 7-11.
Although the logic shown in Figure 7-11 will produce the correct number of labels for every employee, the
statement while labelCounter < inLastProduction * 1.1 executes an average of 110 times for each
employee. That means the arithmetic operation that is part of the question—multiplying inLastProduction
by 1.1—occurs 110 separate times for each employee. Performing the same calculation that results
in the same mathematical answer 110 times in a row is inefficient. Instead, it is superior to perform the
multiplication just once for each employee and use the result 110 times, as shown in the original version
of the program in Figure 7-10. In the pseudocode in Figure 7-10, you still must recalculate labelsToPrint
once for each record, but not once for each label, so you have improved the program’s efficiency.
The modules illustrated in Figures 7-10 and 7-11 do the same thing: print enough labels for every employee
to cover 110 percent of production. As you become more proficient at programming, you will recognize
many opportunities to perform the same tasks in alternative, more elegant, and more efficient
ways.
Another common error made by beginning programmers involves initializing a variable that does not
require initialization. When declaring variables for the label-making program, you might be tempted to
declare num labelsToPrint = inLastProduction * 1.1. It seems as though this declaration statement indicates
that the value of labelsToPrint will always be 110 percent of the inLastProduction figure. However, this
approach is incorrect for two reasons. First, at the time labelsToPrint is declared, the first employee record
has not yet been read into memory, so the value of inLastProduction is garbage; therefore, the result in
166
labelsToPrint after multiplication will also be garbage. Second, even if you read the first empRecord into
memory before declaring the labelsToPrint variable, the mathematical calculation of labelsToPrint within
the housekeep() module would be valid for the first record only. The value of labelsToPrint must be
recalculated for each employee record in the input file. Therefore, calculation of labelsToPrint correctly
belongs within the createLabels() module, as shown in Figure 7-10.
The label-making programs discussed in this chapter each contain two loops. For example, Figures 7-12
and 7-13 show the loop within the mainline program as well as the loop within the createLabels() module
for a program that produces exactly 100 labels for each employee. (These flowcharts were shown earlier
in this chapter.)
FIGURE 7-12: MAINLINE LOGIC FOR LABEL-MAKING FIGURE 7-13: THE createLabels() LOGIC FOR LABEL-MAKING
PROGRAM PROGRAM
Entry to the createLabels() module in the mainline logic of the label-making program is controlled by the
eof decision. Within the createLabels() method, the loop that produces labels is controlled by the
labelCounter decision. When you execute the mainline logic, you cannot predict how many times the
createLabels() module will execute. Depending on the size of the input file (that is, depending on the
number of employees who require labels), any number of records might be processed; while the
program runs, you don’t know what the total number of records finally will be. Until you attempt to read
a record and encounter the end of the file, you don’t know if more records are going to become available.
Of course, not being able to predict the number of input records is valuable—it allows the program to
function correctly no matter how many employees exist from week to week or year to year. Because you
can’t determine ahead of time how many records there might be and, therefore, how many times the loop
might execute, the mainline loop in the labelmaking program is called an indeterminate, or indefinite,
loop.
With some loops, you know exactly how many times they will execute. If every employee needs 100 printed
labels, then the loop within the createLabels() module executes exactly 100 times for each employee. This
kind of loop, in which you definitely know the repetition factor, is a definite loop.
167
Every high-level computer programming language contains a while statement that you can use to code
any loop, including indefinite loops (like the mainline loop) and definite loops (like the label-printing loop).
You can write statements like the following: while not eof perform createLabels() endwhile
and
while labelCounter < 100 print
labelLine, inFirstName labelCounter =
labelCounter +1 endwhile
In addition to the while statement, most computer languages also support a for statement. You can use
the for statement with definite loops—those for which you know how many times the loop will repeat.
The for statement provides you with three actions in one compact statement. The for statement:
initializes the loop control variable
evaluates the loop control variable
alters the loop control variable (typically by incrementing it)
The for statement does not represent a new structure; it simply provides a compact way to write a pretest
loop. You are never required to use a for statement; the label loop executes correctly using a while
statement with labelCounter as a loop control variable. However, when a loop is based on a loop control
variable progressing from a known starting value to a known ending value in equal increments, the for
statement presents you with a convenient shorthand.
When you use either a while loop or a for statement, the body of the loop may never execute. For example,
in the mainline logic in Figure 7-5, the last action in the housekeep() module is to read an input record. If
168
the input file contains no records, the result of the eof decision is true, and the program executes the
finishUp() module without ever entering the createLabels() module.
Similarly, when you produce labels within the createLabels() module shown in Figure 7-10, labels are
produced while labelCounter < labelsToPrint. Suppose an employee record contains a 0 in the
inLastProduction field—for example, in the case of a new employee or an employee who was on vacation
during the previous week. In such a case, the value of labelsToPrint would be 0, and the label- producing
body of the loop would never execute. With a while loop, you evaluate the loop control variable prior to
executing the loop body, and the evaluation might indicate that you can’t enter the loop.
With a while loop, the loop body might not execute. When you want to ensure that a loop’s body executes
at least one time, you can use either a do while or a do until loop. In both types of loops, the loop control
variable is evaluated after the loop body executes, instead of before. Therefore, the body always executes
at least one time. Although the loops have similarities, as explained above, they are different in that the
do while loop continues when the result of the test of the loop control variable is true, but the do until
loop continues when the result of the test of the loop control variable is false. In other words, the
difference between the two loops is simply in how the question at the bottom of the loop is phrased.
For example, suppose you want to produce one label for each employee to wear as identification, before
you produce enough labels to cover 110 percent of last week’s production. You can write the do until loop
that appears in Figure 7-14.
169
FIGURE 7-14: USING A do until LOOP TO PRINT ONE IDENTIFICATION LABEL, THEN PRINT ENOUGH TO COVER
PRODUCTION REQUIREMENTS
In Figure 7-14, the labelCounter variable is set to 0 and labelsToPrint is calculated. Suppose labelsToPrint
is computed to be 0. The do until loop will be entered, a label will print, 1 will be added to labelCounter,
and then and only then will labelCounter be compared to labelsToPrint. Because labelCounter is now 1
and labelsToPrint is only 0, the loop is exited, having printed a single identification label and no product
labels.
As a different example using the logic in Figure 7-14, suppose that for a worker labelsToPrint is
calculated to be 1. In this case, the loop is entered, a label prints, and 1 is added to labelCounter. N ow,
the value of labelCounter is not yet greater than the value of labelsToPrint, so the loop repeats, a second
label prints, and labelCounter is incremented again. This time labelCounter (with a value of 2) does exceed
labelsToPrint (with a value of 1), so the loop ends. This employee gets an identification label as well as one
product label.
170
Of course, you could achieve the same results by printing one label, then entering a while loop, as in Figure
7-15. In this example, one label prints before labelCounter is compared to labelsToPrint. No matter what
the value of labelsToPrint is, one identification label is produced.
FIGURE 7-15: USING A while LOOP TO PRINT ONE IDENTIFICATION LABEL, THEN PRINT ENOUGH TO COVER
PRODUCTION REQUIREMENTS
The results of the programs shown in Figures 7-14 and 7-15 are the same. Using either, every employee
will receive an identification label and enough labels to cover production. Each module works correctly,
and neither is logically superior to the other. There is almost always more than one way to solve the same
programming problem. As you learned in Chapter 2, a posttest loop (do while or do until) can always be
replaced by pairing a sequence and a pretest while loop. Which method you choose depends on your (or
your instructor’s or supervisor’s) preference.
You can see from Figure 7-15 that you are never required to use posttest loops (either a do while loop or
a do until loop). The same results always can be achieved by performing the loop body steps once before
entering a while loop. If you follow the logic of either of the loops shown in Figures 7-14 and 7- 15, you will
discover that when an employee has an inLastProduction value of 3, then exactly four labels print.
171
Likewise, when an employee has an inLastProduction value of 0, then exactly one label prints. You can
accomplish the same results with either type of loop; the posttest do while and do until loops simply are
a convenience when you need a loop’s statements to execute at least one time.
If you can express the logic you want to perform by saying “while a is true, keep doing b,” you probably
want to use a while loop. If what you want to accomplish seems to fit the statement “do a until b is true,”
you can probably use a do until loop. If the statement “do a while b is true” makes more sense, then you
might choose to use a do while loop.
As you examine Figures 7-14 and 7-15, notice that with the do until loop in Figure 7-14, the loop- controlling
question is placed at the end of the sequence of the steps that repeat. With the while loop, the loop-
controlling question is placed at the beginning of the steps that repeat. All structured loops (whether they
are while loops, do while loops, or do until loops) share these characteristics:
The loop-controlling question provides either entry to or exit from the repeating structure. The
loop-controlling question provides the only entry to or exit from the repeating structure.
You should also notice the difference between unstructured loops and the structured do until and while
loops. Figure 7-16 diagrams the outline of two unstructured loops. In each case, the decision labeled X
breaks out of the loop prematurely. In each case, the loop control variable (labeled LC) does not provide
the only entry to or exit from the loop.
Program logic gets more complicated when you must use loops within loops, or nesting loops. When one
loop appears inside another, the loop that contains the other loop is called the outer loop, and the loop
that is contained is called the inner loop. For example, suppose you work for a company that pays workers
twice per month. The company has decided on an incentive plan to provide each employee with a one-
172
fourth of one percent raise for each pay period during the coming year, and it wants a report for each
employee like that shown in Figure 7-17. A list will be printed for each employee showing the exact
paycheck amounts for each of the next 24 pay periods—two per month for 12 months. A description of
the employee input record is shown in Figure 7-18.
To produce the Projected Payroll report, you need to maintain two separate counters to control two
separate loops. One counter will keep track of the month (1 through 12), and another will keep track of
the pay period within the month (1 through 2). When nesting loops, you must maintain individual loop
control variables—one for each loops—and alters each at the appropriate time.
Figure 7-19 shows the mainline, housekeeping(), and finish() logic for the program. These modules are
standard. Besides the input file variables and the headers that print for each employee, the list of declared
variables includes two counters. One, named monthCounter, keeps track of the month that is currently
printing. The other, named checkCounter, keeps track of which check within the month is currently
printing. Three additional declarations hold the number of months in a year (12), the number of checks in
a month (2), and the rate of increase (0.0025).
Declaring these constants is not required; the program could just use the numeric constants 12, 2, and
0.0025 within its statements, but providing those values with names serves two purposes. First, the
program becomes more selfdocumenting—that is, it describes itself to the reader because the choice of
variable names is clear. When other programmers read a program and encounter a number like 2, they
173
might wonder about the meaning. Instead, if the value is named CHECKS_IN_A_MONTH, the meaning of
the value is much clearer. Second, after the program is in production, the company might choose to change
one of the values—for example, by going to an 11-month year, producing more or fewer paychecks in a
month, or changing the raise rate. In those cases, the person who modifies the program would not have
to search for appropriate spots to make those changes, but would simply redefine the values assigned to
the appropriate named constants.
FIGURE 7-19: MAINLINE LOGIC, housekeeping (), AND finish() MODULES FOR PROJECTED
PAYROLL REPORT PROGRAM
At the end of the housekeeping () module in Figure 7-19, the first employee record is read into main
memory. The program proceeds as follows:
1. The first heading prints followed by the employee name and the column headings.
2. The monthCounter variable is set to 1; monthCounter is the loop control variable for the outer loop,
and this step provides it with its initial value.
3. The monthCounter variable is compared to the number of months in a year, and because the
comparison evaluates as true, the outer loop is entered. Within this loop, the checkCounter variable is
used as a loop control variable for an inner loop.
174
4. The checkCounter variable is initialized to 1, and then compared to the number of checks in a month.
Because this comparison evaluates as true, the inner loop is entered.
5. Within this inner loop, the employee’s weekly salary is increased by one-fourth of one percent (the old
salary plus 0.0025 of the old salary).
6. The month number (currently 1), check number (also currently 1), and newly calculated salary are
printed.
7. The check number is increased (to 2), and the inner loop reaches its end; this causes the logical control
to return to the top of the inner loop, where the while condition is tested again. Because the check
number (2) is still less than or equal to the number of checks in a month, the inner loop is entered
again.
8. The pay amount increases, and the month (still 1), check number (2), and new salary are printed.
9. Then, the check number becomes 3. Now, when the loop condition is tested for the third time, the
check number is no longer less than or equal to the number of checks in a month, so the inner loop
ends.
10. As the last step in the outer loop, monthCounter becomes 2.
11. After monthCounter increases to 2, control returns to the entry point of the outer loop.
12. The while condition is tested, and because 2 is not greater than the number of months in a year, the
outer loop is entered for a second time.
13. The checkCounter variable is reset to 1 so that it will correctly count two checks for this month.
14. Because the newly reset checkCounter is not more than the number of checks in a month, the salary is
increased, and the amount prints for month 2, check 1.
15. The checkCounter variable increases to 2 and another value is printed for month 2, check 2 before the
inner loop ends and monthCounter is increased to 3.
16. Then, month 3, check 1 prints, followed by month 3, check 2. The inner loop is evaluated again. The
checkCounter value is 3, so the evaluation result is false.
17. The produceReport() module continues printing two check amounts for each of 12 months before the
outer loop is finished, when monthCounter eventually exceeds 12. Only then is the next employee
record read into memory, and control leaves the produceReport() module and returns to the mainline
logic, where the end of file is tested. If a new record exists, control returns to the produceReport()
module for the new employee, for whom headings are printed, and monthCounter is set to 1 to start
the set of 24 calculations for this employee.
175
FIGURE 7-20: THE produceReport () MODULE FOR THE PROJECTED PAYROLL REPORT PROGRAM
There is no limit to the number of loop-nesting levels a program can contain. For instance, suppose that in
the projected payroll example, the company wanted to provide a slight raise each hour or each day of each
pay period in each month for each of several years. No matter how many levels deep the nesting goes,
each loop must still contain a loop control variable that is initialized, tested, and altered.
Business reports often include totals. The supervisor requesting a list of employees who participate in the
company dental plan is often as much interested in how many such employees there are as in who they
are. When you receive your telephone bill at the end of the month, you are usually more interested in the
total than in the charges for the individual calls. Some business reports list no individual detail records, just
totals or other overall statistics such as averages. Such reports are called summary reports. Many business
reports list both the details of individual records and totals at the end.
For example, a real estate broker might maintain a file of company real estate listings. Each record in the
file contains the street address and the asking price of a property for sale. The broker wants a listing of all
the properties for sale; she also wants a total value for all the company’s listings. A typical report appears
in Figure 7-21.
176
FIGURE 7-21: TYPICAL REAL ESTATE REPORT
When you read a real estate listing record, besides printing it you must add its value to an accumulator.
An accumulator is a variable that you use to gather, or accumulate, values. An accumulator is very similar
to a counter. The difference lies in the value that you add to the variable; usually, you add just 1 to a
counter, whereas you add some other value to an accumulator. If the real estate broker wants to know
how many listings the company holds, you count them. When she wants to know total real estate value,
you accumulate it.
In order to accumulate total real estate prices, you declare a numeric variable at the beginning of the
program, as shown in the housekeep () module in Figure 7-22. You must initialize the accumulator,
accumValue, to 0. In Chapter 4, you learned that when using most programming languages, declared
variables do not automatically assume any particular value; the unknown value is called garbage. When
you read the first real estate record, you will add its value to the accumulator. If the accumulator contains
garbage, the addition will not work. Some programming languages issue an error message if you don’t
initialize a variable you use for accumulating; others let you accumulate, but the results are worthless
because you start with garbage.
177
FIGURE 7-22: THE REAL ESTATE PROGRAM
If you name the input record fields realAddress and realPrice, then the displayProperties () module of the
real estate listing program can be written as shown in Figure 7-22. For each real estate record, you print it
and add its value to the accumulator accumValue. Then you can read the next record.
After the program reaches the end of the file, the accumulator will hold the grand total of all the real estate
values. When you reach the end of the file, the finishUp () module executes, and it is within the finishUp()
module that you print the accumulated value, accumValue. After printing the total, you can close both the
input and the output files and return to the mainline logic, where the program ends.
New programmers often want to reset the accumValue to 0 after printing it. Although you can take this
step without harming the execution of the program, it does not serve any useful purpose. You cannot set
accumValue to 0 in anticipation of having it ready for the next program, or even for the next time you
execute this program. Program variables exist only for the life of the program, and even if a future program
178
happens to contain a variable named accumValue, the variable will not necessarily occupy the same
memory location as this one. Even if you run the program a second time, the variables might occupy
physical memory locations different from those they occupied during the first run. At the beginning of the
program, it is the programmer’s responsibility to initialize all variables that must start with a specific value.
There is no benefit to changing a variable’s value when it will never be used again during the current
execution of the program.
A control break is a temporary detour in the logic of a program. In particular, programmers refer to a
program as a control break program when a change in the value of a variable initiates special actions or
causes special or unusual processing to occur. You usually write control break programs to organize output
for programs that handle data records that are organized logically in groups based on the value in a field.
As you read records, you examine the same field in each record, and when you encounter a record that
contains a different value from the ones that preceded it, you perform a special action. If you have ever
read a report that lists items in groups, with each group followed by a subtotal, then you have read a type
of control break report. For example, you might generate a report that lists all company clients in order
by state of residence, with a count of clients after each state’s client list. An example of a report that breaks
after each change in state:
Some other examples of control break reports produced by control break programs include:
All employees listed in order by department number, with a new page started for each
department
All books for sale in a bookstore in order by category (such as reference or self-help), with a count
following each category of book
All items sold in order by date of sale, with a different ink color for each new month
179
Suppose you want to print a list of employees, advancing to a new page for each department. Suppose
that the employee department is a numeric field, and that the file has been presorted so that the records
will arrive in a program in department-number order.
The basic logic of the program works like this: Each time you read an employee record from the input file,
you will determine whether the employee belongs to the same department as the previous employee. If
so, you simply print the employee record and read another record, without any special processing. If there
are 20 employees in a department, these steps are repeated 20 times in a row— read an employee record
and print the employee record. However, eventually you will read an employee record that does not
belong to the same department. At that point, before you print the employee record from the new
department, you must print headings at the top of a new page. Then, you can proceed to read and print
employee records that belong to the new department, and you continue to do so until the next time you
encounter an employee in a different department. This type of program contains a single-level control
break, a break in the logic of the program (pausing or detouring to print new headings) that is based on
the value of a single variable (the department number).
However, there is a slight problem you must solve before you can determine whether a new input record
contains the same department number as the previous input record. When you read a record from an
input file, you copy the data from storage locations (for example, from a disk) to temporary computer
memory locations. After they are read, the data items that represent department, last name, and first
name occupy specific physical locations in computer memory. For each new record that is read from
storage, new data must occupy the same positions in memory as the previous record occupied, and the
previous set of data is lost. For example, if you read a record containing data for Donald Travis in
Department 1, when you read the next record for Mary Billings in Department 2, “Mary” replaces
“Donald”, “Billings” replaces “Travis”, and 2 replaces 1. After you read a new record into memory, there is
no way to look back at the previous record to determine whether that record had a different department
number. The previous record’s data has been replaced in memory by the new record’s data.
The technique you must use to “remember” the old department number is to create a special variable,
called a control break field, to hold the previous department number. With a control break field, every
time you read a record and print it, you also can save the crucial part of the record that will signal the
change or control the program break. In this case, you want to store the department number in this
specially created variable. Comparing the new and old departmentnumber values will determine when it
is time to print headings at the top of a new page.
The mainline logic for the Employees by Department report is the same as the mainline logic for all the
other programs you’ve analyzed so far. It performs a housekeeping () module, after which an eof question
controls execution of a mainLoop () module. At eof, a finish () module executes.
The housekeeping () module for this program begins like others you have seen. You declare variables,
including those you will use for the input data: empDept, empLast, and empFirst. You can also declare
variables to hold the headings, and an additional variable that is named oldDept in this example. The
purpose of oldDept is to serve as the control break field. Every time you read a record from a new
department, you can save its department number in oldDept before you read the next record. The oldDept
field provides you with a comparison for each new department so you can determine whether there has
been a change in value.
180
Note that it would be incorrect to initialize oldDept to the value of empDept when you declare oldDept in
the housekeeping () module. When you declare variables at the beginning of the housekeeping () module,
you have not yet read the first record; therefore, empDept does not yet have any usable value. You use
the value of the first empDept variable at the end of the module, only after you read the first input record.
In the housekeeping () module, after declaring variables, you also open files, print headings, and read the
first input record. Before you leave the housekeeping () module, you can set the oldDept variable to equal
the empDept value in the first input record. You will write the mainLoop () module of the program to check
for any change in department number; that’s the signal to print headings at the top of a new page. Because
you just printed headings and read the first record, you do not want to print headings again for this first
record, so you want to ensure that empDept and oldDept are equal when you enter mainLoop().
The first task within the mainLoop () module is to check whether empDept holds the same value as oldDept.
For the first record, on the first pass through mainLoop (), the values are equal; you set them to be equal
in the housekeeping () module. Therefore, you proceed without performing the newPage () module,
printing the first employee’s record and reading a second record. At the end of the mainLoop () module
the logical flow returns to the mainline logic. If it is not eof, the flow travels back into the mainLoop ()
module. There, you compare the second record’s empDept to oldDept. If the second record holds an
employee from the same department as the first employee, then you simply print that second employee’s
record and read a third record into memory. As long as each new record holds the same empDept value,
you continue reading and printing, never pausing to perform the newPage () module.
Eventually, you will read in an employee whose empDept is not the same as oldDept. That’s when the
control break routine, newPage (), executes. The newPage () module must perform two tasks: It must
print headings at the top of a new page. It must update the control break field.
When you read an employee record in which empDept is not the same as oldDept, you cause a break in
the normal flow of the program. The new employee record must “wait” while headings print and the
control break field oldDept acquires a new value. After the oldDept field has been updated, and before the
mainLoop () module ends, the waiting employee record prints on the new page. When you read the next
employee record (and it is not eof), the mainLoop () module is reentered and the next employee’s
empDept field is compared to the updated oldDept field. If the new employee works in the same
department as the one just preceding, then normal processing continues with the print-and-read
statements.
The newPage () module in the employee report program performs two tasks required in all control break
modules:
It performs any necessary processing for the new group—in this case, it prints headings. It
updates the control break field—in this case, the oldDept field.
The finish () module for the Employees by Department report program requires only that you close the
files.
Notice that in the control break program, the department numbers of employees in the input file do not
have to follow each other incrementally. That is, the departments might be 1, 2, 3, and so on, but they also
might be 1, 4, 12, 35, and so on. A control break occurs when there is a change in the control break field;
the change does not necessarily have to be a numeric change of 1.
181
Figure 7-23 shows the entire Employees by Department control break program.
182
FIGURE 7-23: THE EMPLOYEES BY DEPARTMENT CONTROL BREAK PROGRAM
Let’s say your bookstore from the last example is so successful that you have a chain of them across the
country. Every time a sale is made, you create a record with the fields bookTitle, bookPrice, bookCity, and
bookState. You want a report that prints a summary of books sold in each city and each state. A report
183
such as this one, which does not include any information about individual records, but instead includes
only group totals, is a summary report.
This program contains a multiple-level control break—that is, the normal flow of control (reading
records and counting book sales) breaks away to print totals in response to more than just one change in
condition. In this report, a control break occurs in response to either (or both) of two conditions: when the
value of the bookCity variable changes, as well as when the value of the bookState variable changes.
Every time you write a program where you need control break routines, you should check whether you
need to complete each of the following tasks within the modules:
Performing the lower-level break, if any
Performing any control break processing for the previous group
Rolling up the current-level totals to the next higher level
Resetting the current level’s totals to zero
Performing any control break processing for the new group
Updating the control break field
CHAPTER SUMMARY
When you use a loop within a computer program, you can write one set of instructions that operates
on multiple, separate sets of data.
Three steps must occur in every loop: You must initialize a loop control variable, compare the
variable to some value that controls whether the loop continues or stops, and alter the variable
that controls the loop.
A counter is a numeric variable you use to count the number of times an event has occurred. You
can count occurrences by incrementing or decrementing a variable.
You can use a variable sentinel value to control a loop.
Sometimes it is convenient to reduce, or decrement, a loop control variable on every cycle through
a loop.
Mistakes that programmers often make with loops include neglecting to initialize the loop
control variable and neglecting to alter the loop control variable. Other mistakes include using the
wrong comparison with the loop control variable, including statements inside the loop that belong
outside the loop, and initializing a variable that does not require initialization.
Most computer languages support a for statement that you can use with definite loops when you
know how many times a loop will repeat. The for statement uses a loop control variable that it
automatically initializes, evaluates, and increments.
When you want to ensure that a loop’s body executes at least one time, you can use a do while loop
or a do until loop, in which the loop control variable is evaluated after the loop body executes.
All structured loops share these characteristics: The loop-controlling question provides either entry
to or exit from the repeating structure, and the loop-controlling question provides the only entry
to or exit from the repeating structure.
When you must use loops within loops, you are using nested loops. When you create nested loops,
you must maintain two individual loop control variables and alter each at the appropriate time.
184
Business reports often include totals. Summary reports list no detail records—only totals. An
accumulator is a variable that you use to gather or accumulate values.
A control break is a temporary detour in the logic of a program; programmers refer to a program as
a control break program when a change in the value of a variable initiates special actions or causes
special or unusual processing to occur. To generate a control break report, your input records must
be organized in sorted order based on the field that will cause the breaks.
You use a control break field to hold data from a previous record. You decide when to perform a
control break routine by comparing the value in the control break field to the corresponding value
in the current record. At minimum, the simplest control break routines perform necessary
processing for the new group and update the control break field.
A control break report contains and prints totals for the previous group, rolls up the current-level
totals to the next higher level, resets the current level’s totals to zero, performs any other needed
control break processing, and updates the control break field.
In a program containing a multiple-level control break, the normal flow of control breaks away for
special processing in response to a change in more than one field. You should always test for a
major-level break before a minor-level break, and include a call to the minor break routine within
the major break module.
Every time you write a program in which you need control break routines, you should check whether
you need to perform each of the following tasks within the routines: any lower-level break, any
control break processing for the previous group, rolling up the current-level totals to the next higher
level, resetting the current level’s totals to zero, any control break processing for the new group,
and updating the control break field.
KEY TERMS
A summary report is one that does not include any information about individual records, but instead
includes only group totals.
A multiple-level control break is one in which the normal flow of control breaks away for special
processing in response to a change in more than one field.
A major-level break is a break in the flow of logic that is caused by a change in the value of a higher-
level field.
A minor-level break is a break in the flow of logic that is caused by a change in the value of a lower-
level field.
REVIEW QUESTIONS
1. The structure that allows you to write one set of instructions that operates on multiple, separate sets
of data is the _. a. sequence
b. selection
c. loop
d. case
2. Which of the following is not a step that must occur in every loop?
a. Initialize a loop control variable.
b. Compare the loop control value to a sentinel.
c. Set the loop control value equal to a sentinel.
d. Alter the loop control variable.
186
4. A counter keeps track of _.
a. the number of times an event has occurred
b. the number of modules in a program
c. the number of loop structures within a program
d. a total that prints at the end of a summary report
print a, b, c
a. 1 2 5
b. 5 22 5
c. 5 6 5
d. 6 22 9
187
endwhile print
g, h
a. nothing
b. 4 6
c. 5 6
d. 6 6
12. Which of the following is a characteristic shared by all loops—while, do while, and do until loops? a.
They all have one entry and one exit.
b. They all have a body that executes at least once.
c. They all compare a loop control variable at the top of the loop.
d. All of these are true.
14. When two loops are nested, the loop that is contained by the other is the
loop. a. inner
b. outer
c. unstructured
d. captive
15. In the following pseudocode, how many times is “Hello” printed? j=2
k=5 m=6
n=9
while j < k while m < n print
“Hello”
m=m+1
endwhile
j=j+1
188
endwhile
a. zero
b. three
c. six
d. nine
endwhile
a. zero
b. four
c. six
d. eight
18. A report that lists no details about individual records, but totals only, is a(n) report. a.
accumulator
b. final
c. summary
d. detailless
23. Placing records in sequential order based on the value in one of the fields is called
. a. sorting
b. collating
c. merging
d. categorizing
Each of the following pseudocode segments contains one or more bugs that you must find and correct.
1. This method is supposed to print every fifth year starting with 2005; that is, 2005, 2010, 2015, and
so on, for 30 years.
190
const num END_YEAR =
2035 while year > END_YEAR
print year
year = year + 1
endwhile return
2. A standard mortgage is paid monthly over 30 years. This method is intended to print 360 payment
coupons for a new borrower. Each coupon lists the month number, year number, and a friendly
reminder.
endwhile
return
3. This application is intended to print estimated monthly payment amounts for customers of the EZ
Credit Loan Company. The application reads customer records, each containing an account number,
name and address, requested original loan amount, term in months, and annual interest rate. The
interest rate per month is calculated by dividing the annual interest rate by 12. The customer’s total
payback amount is calculated by charging the monthly interest rate on the original balance every month
for the term of the loan. The customer’s monthly payment is then calculated by dividing the total
payback amount by the number of months in the loan. The application produces a notice containing the
customer’s name, address, and estimated monthly payment amount.
start
perform getReady()
while not eof
perform produceEstimate()
perform ending()
stop
191
num originalLoanAmount num
termInMonths
num annualRate
const num MONTHS_IN_YEAR = 12
const num totalPayback num
monthlyRate
num count
open files read
custRecord return
produceEstimate()
count = 1
monthlyRate = annualRate / monthsInYear while count = termInMonths
totalPayback = totalPayback + monthlyRate * originalLoanAmount count
= count + 1
endwhile
monthlyPayment = totalPayback / MONTHS_IN_YEAR print
“Loan Payment Estimate for:”
print name
print address
ending()
close files return
EXERCISES
1. Design the logic for a module that would print every number from 1 through 10. a.
Draw the flowchart.
b. Design the pseudocode.
2. Design the logic for a module that would print every number from 1 through 10 along with its square
and cube.
a. Draw the flowchart.
b. Design the pseudocode.
3. Design a program that reads credit card account records and prints payoff schedules for customers.
Input records contain an account number, customer name, and balance due. For each customer, print
the account number and name; then print the customer’s projected balance each month for the next 10
months. Assume that there is no finance charge on this account, that the customer makes no new
purchases, and that the customer pays off the balance with equal monthly payments, which are 10
percent of the original bill.
a. Design the output for this program; create either sample output or a print chart.
b. Design the hierarchy chart for this program.
192
c. Design the flowchart for this program.
d. Write pseudocode for this program.
4. Design a program that reads credit card account records and prints payoff schedules for customers.
Input records contain an account number, customer name, and balance due. For each customer, print
the account number and name; then print the customer’s payment amount and new balance each month
until the card is paid off. Assume that when the balance reaches $10 or less, the customer can pay off
the account. At the beginning of every month, 1.5 percent interest is added to the balance, and then the
customer makes a payment equal to 5 percent of the current balance. Assume the customer makes no
new purchases.
a. Design the output for this program; create either sample output or a print chart.
b. Design the hierarchy chart for this program.
c. Design the flowchart for this program.
d. Write pseudocode for this program.
5. Assume you have a bank account that compounds interest on a yearly basis. In other words, if you
deposit $100 for two years at 4 percent interest, at the end of one year you will have $104. At the end
of two years, you will have the $104 plus 4 percent of that, or $108.16. Create the logic for a program
that would (1) read in records containing a deposit amount, a term in years, and an interest rate, and (2)
for each record, print the running total balance for each year of the term.
a. Design the output for this program; create either sample output or a print chart.
b. Design the hierarchy chart for this program.
c. Design the flowchart for this program.
d. Write pseudocode for this program.
There is one record for each class section offered in the college. Design the program that would print as
many stickers as a class needs to provide one for each enrolled student, plus one for the teacher. Each
sticker would leave a blank for the student’s (or teacher’s) name, like this:
193
The border is preprinted, but you must design the program to print all the text you see on the sticker.
(You do not need to worry about the differing font sizes of the sticker text. You do not need to design a
print chart or sample output—the image of the sticker serves as a print chart.) a. Design the hierarchy
chart for this program.
b. Design the flowchart for this program.
c. Write pseudocode for this program.
7. A mail-order company often sends multiple packages per order. For each customer order, print enough
mailing labels to use on each of the separate boxes that will be mailed. The mailing labels contain the
customer’s complete name and address, along with a box number in the form “Box 9 of 9”. For example,
an order that requires three boxes produces three labels: Box 1 of 3, Box 2 of 3, and Box 3 of 3. The file
description is as follows:
SHIPPING FILE DESCRIPTION
File name: ORDERS
8. A secondhand store is having a seven-day sale during which the price of any unsold item drops 10
percent each day. The inventory file includes an item number, description, and original price on day one.
For example, an item that costs $10.00 on the first day costs 10 percent less, or $9.00, on the second
day. On the third day, the same item is 10 percent less than $9.00, or $8.10. Produce a report that shows
the price of the item on each day, one through seven.
a. Design the output for this program; create either sample output or a print chart.
b. Design the hierarchy chart for this program.
c. Design the flowchart for this program.
d. Write pseudocode for this program.
9. The state of Florida maintains a census file in which each record contains the name of a county, the
current population, and a number representing the rate at which the population is increasing per year.
The governor wants a report listing each county and the number of years it will take for the population
of the county to double, assuming the present rate of growth remains constant. CENSUS FILE
DESCRIPTION
194
File name: CENSUS
FIELD DESCRIPTION DATA TYPE EXAMPLE
County Name Character Dade
Current Population Numeric 525000
Rate of Growth Numeric 0.07
a. Design the output for this program; create either sample output or a print chart.
b. Design the hierarchy chart for this program.
c. Design the flowchart for this program.
d. Write pseudocode for this program.
10. A Human Resources Department wants a report that shows its employees the benefits of saving or
retirement. Produce a report that shows 12 predicted retirement account values for each employee—
the values if the employee saves 5, 10, or 15 percent of his or her annual salary for 10, 20, 30, or 40 years.
The department maintains a file in which each record contains the name of an employee and the
employee’s current annual salary. Assume that savings grow at a rate of 8 percent per year. a. Design
the output for this program; create either sample output or a print chart.
b. Design the hierarchy chart for this program.
c. Design the flowchart for this program.
d. Write pseudocode for this program.
11. Randy’s Recreational Vehicles pays its salespeople once every three months. Salespeople receive
one-quarter of their annual base salary plus 7 percent of all sales made in the last three-month period.
Randy creates an input file with four records for each salesperson. The first of the four records contains
the salesperson’s name and annual base salary, while each of the three records that follow contains the
name of a month and the monthly sales figure. For example, the first eight records in the file might
contain the following data:
Kimball 20000
April 30000
May 40000
June 60000
Johnson 15000
April 65000
May 78000
June 135500
Because the two types of records contain data in the same format—a character field followed by a
numeric field—you can define one input record format containing two variables that you use with either
type of record. Design the logic for the program that reads a salesperson’s record, and if not at eof, reads
the next three records in a loop, accumulating sales and computing commissions. For each salesperson,
print the quarterly base salary, the three commission amounts, and the total salary, which is the
quarterly base plus the three commission amounts.
a. Design the output for this program; create either sample output or a print chart.
b. Design the hierarchy chart for this program.
c. Design the flowchart for this program.
d. Write pseudocode for this program.
195
12. Mr. Furly owns 20 apartment buildings. Each building contains 15 units that he rents for $800 per
month each. Design the logic for the program that would print 12 payment coupons for each of the 15
apartments in each of the 20 buildings. Each coupon should contain the building number (1 through 20),
the apartment number (1 through 15), the month (1 through 12), and the amount of rent due. a. Design
the output for this program; create either sample output or a print chart.
b. Design the hierarchy chart for this program.
c. Design the flowchart for this program.
d. Write pseudocode for this program.
13. Mr. Furly owns 20 apartment buildings. Each building contains 15 units that he rents. The usual
monthly rent for apartments numbered 1 through 9 in each building is $700; the monthly rent is $850
for apartments numbered 10 through 15. The usual rent is due every month except July and
December; in those months Mr. Furly gives his renters a 50 percent credit, so they owe only half the
usual amount.
Design the logic for the program that would print 12 payment coupons for each of the 15 apartments in
each of the 20 buildings. Each coupon should contain the building number (1 through 20), the apartment
number (1 through 15), the month (1 through 12), and the amount of rent due. a. Design the output for
this program; create either sample output or a print chart.
b. Design the hierarchy chart for this program.
c. Design the flowchart for this program.
d. Write pseudocode for this program.
14. What fields might you want to use as the control break fields to produce a report that lists all
inventory items in a grocery store? (For example, you might choose to group items by grocery store
department.) Design a sample report.
15. What fields might you want to use as the control break fields to produce a report that lists all the
people you know? (For example, you might choose to group friends by city of residence.) Design a
sample report.
16. Cool’s Department Store keeps a record of every sale in the following format:
Create the logic for a program that would print each transaction’s details, with a total at the end of each
department.
a. Design the output for this program; create either sample output or a print chart. b.
Create the hierarchy chart.
c. Create the flowchart.
d. Create the pseudocode.
196
TOPIC 8
8. ARRAYS
LEARNING OUTCOMES
After Studying this topic you should be able to:
Understand how arrays are used
Understand how arrays occupy computer memory
Manipulate an array to replace nested decisions
Declare and initialize an array
Declare and initialize constant arrays
Load array values from a file
Search an array for an exact match
Use parallel arrays
Force subscripts to remain within array bounds
Improve search efficiency by using an early exit
Search an array for a range match
An array is a series or list of variables in computer memory, all of which have the same name but are
differentiated with special numbers called subscripts. A subscript is a number that indicates the position
of a particular item within an array. Whenever you require multiple storage locations for objects, you are
using a real-life counter art of a programming array. For example, if you store important papers in a series
of file folders and label each folder with a consecutive letter of the alphabet, then you are using the
equivalent of an array. If you store mementos in a series of stacked shoeboxes, each labeled with a year,
or if you sort mail into slots, each labeled with a name, then you are also using a real-life equivalent
of a programming array.
When you look down the left side of a tax table to find your income level before looking to the right to find
your income tax obligation, you are using an array. Similarly, if you look down the left side of a train
schedule to find your station before looking to the right to find the train’s arrival time, you also are using
an array.
Each of these real-life arrays helps you organize real-life objects. You could store all your papers or
mementos in one huge cardboard box, or find your tax rate or train’s arrival time if both were printed
randomly in one large book. However, using an organized storage and display system makes your life easier
in each case. Using a programming array accomplishes the same results for your data.
197
When you declare an array, you declare a programming structure that contains multiple variables. Each
variable within an array has the same name and the same data type; each separate array variable is one
element of the array. Each array element occupies an area in memory next to, or contiguous to, the others,
as shown in Figure 8-1. You indicate the number of elements an array will hold—the size of the array—
when you declare the array along with your other variables.
FIGURE 8-1: APPEARANCE OF A THREE-ELEMENT ARRAY AND A SINGLE VARIABLE IN COMPUTER MEMORY
All array elements have the same group name, but each individual element also has a unique subscript
indicating how far away it is from the first element. Therefore, any array’s subscripts are always a sequence
of integers, such as 0 through 5 or 0 through 10. Depending on the syntax rules of the programming
language you use, you place the subscript within either parentheses or square brackets following the group
name; when writing pseudocode or drawing a flowchart, you can use either form of notation. This text
uses square brackets to hold array element subscripts so that you don’t mistake array names for method
names. For example, Figure 8-1 shows how a single variable and an array are stored in computer memory.
The single variable named aNumber holds the value 15. The array named someVals contains three
elements, so the elements are someVals[0], someVals[1], and someVals[2]. The value stored in
someVals[0] is 25, someVals[1] holds 36, and someVals[2] holds 47. From the diagram in Figure 8-1, you
can see that the memory location someVals[0] is zero elements away from the beginning of the array, the
location of someVals[1] is one memory location away, and the location of someVals[2] is two elements
away from the start of the array.
Because the first element in an array in most programming languages is accessed using a subscript of value
0, the array is called a zero-based array. Because the lowest subscript you can use with an array is 0, the
highest subscript you are allowed to use with an array is one less than the number of elements in the array.
For example, an array with 10 elements uses subscripts 0 through 9, and an array with 200 elements uses
subscripts 0 through 199. When you use arrays, you must always keep the limits of subscript values in
mind.
You are never required to use arrays within your programs, but learning to use arrays correctly can make
many programming tasks far more efficient and professional. When you understand how to use arrays,
you will be able to provide elegant solutions to problems that otherwise would require tedious
programming steps.
Consider a program that keeps statistics for requests about apartments in a large apartment complex. The
developer wants to keep track of inquiries so that future building projects are more likely to satisfy
customer needs. In particular, the developer wants to keep track of how many requests there are for
studio, one-, two-, and three-bedroom apartments. Each time an apartment request is received, a clerk
adds a record to a file in the format shown in Figure 8-2.
198
FIGURE 8-2: FILE DESCRIPTION FOR APARTMENT REQUEST RECORDS
For example, if a call comes in on the third day of the month for a studio apartment, one record is created
with a 3 in the date field and a 0 in the number of bedrooms field. If the next call is on the fourth day of
the month for a three-bedroom apartment, a record with 4 and 3 is created. The contents of the data file
appear as a series of numbers, as follows:
30
43
4 0 ...
and so on.
At the end of the month, after all the records have been collected, the file might contain hundreds of
records, each holding a number that represents a date and another number (0, 1, 2, or 3) that
represents the number of bedrooms the caller wanted. You want to write a program that summarizes the
total number of each type of apartment requested during the month. A typical report appears in Figure 8-
3.
If all the records were sorted in order by the number of bedrooms requested, this report could be a control
break report. You would simply read each record representing an inquiry on a studio apartment (zero
bedrooms), counting the number of inquiries. When you read the first record requesting a different
number of bedrooms, you would print the count for the previous apartment type, reset the count to zero,
and update the control break field before continuing.
Assume, however, that the records have not been sorted by apartment type. Without using an array, could
you write a program that would accumulate the four apartment-type totals? Of course you could. The
program would have the same mainline logic as most of the other programs you have seen, as shown in
Figure 8-4.
199
FIGURE 8-4: FLOWCHART AND PSEUDOCODE FOR MAINLINE LOGIC OF APARTMENT REQUEST REPORT PROGRAM
In the housekeeping() module of the apartment request report program (Figure 8-5), you declare variables
including day and bedrooms. Then, you open the files and read the first record into memory. The headings
could print in housekeeping() or—because no other printing takes place in this program until the finish()
module—you can choose to wait and print the headings there.
FIGURE 8-5: THE housekeeping() MODULE FOR THE APARTMENT REQUEST PROGRAM WITHOUT AN ARRAY
Within the housekeeping() module, you can declare four variables, count0, count1, count2, and count3;
the purpose of these variables is to keep running counts of the number of requests for the four apartment
types. Each of these four counter variables needs to be initialized to 0. You can tell by looking at the
200
planned output that you need two heading lines, so head1 is defined as “Apartment Request Report” and
head2 as “Bedrooms Inquiries”.
Eventually, four summary lines will be printed in the report, each with a number of bedrooms and a count
of inquiries for that apartment type. These lines cannot be printed until the finish() module, however,
because you won’t have a complete count of each apartment type’s requests until all input records have
been read.
The logic within the countCategories() module of the program requires adding a 1 to count0, count1,
count2, or count3, depending on the bedrooms variable. After 1 has been added to one of the four
counters, you read the next record, and if it is not eof, you repeat the decision-making and counting
process. When all records have been read, you proceed to the finish() module, where you print the four
summary lines with the counts for the four apartment types. See Figures 8-6 and 8-7.
FIGURE 8-6: THE countCategories() MODULE FOR THE APARTMENT REQUEST PROGRAM WITHOUT
AN ARRAY
201
FIGURE 8-7: THE finish() MODULE FOR THE APARTMENT REQUEST PROGRAM WITHOUT AN ARRAY
The apartment request report program works just fine, and there is absolutely nothing wrong with it
logically; a decision is made for each of the first three types of apartments, defaulting to a three- bedroom
apartment if the request is not for zero, one, or two bedrooms. But what if there were four types of
apartments, or 12, or 30? With any of these scenarios, the basic logic of the program would remain the
same; however, you would need to declare many additional counter variables. You also would need many
additional decisions within the countCategories() module and many additional print statements within the
finish() module to complete the processing.
Using an array provides an alternative approach to this programming problem, and greatly reduces the
number of statements you need. When you declare an array, you provide a group name for a number of
associated variables in memory. For example, the four apartment-type counters can be redefined as a
single array named count. The individual elements become count[0], count[1], count[2], and count[3], as
shown in the new housekeeping() module in Figure 8-8.
203
FIGURE 8-8: MODIFIED housekeeping() MODULE FOR APARTMENT REQUEST PROGRAM THAT DECLARES
AN ARRAY TO COUNT REQUESTS
With the change to housekeeping() shown in Figure 8-8, the countCategories() module changes to the
version shown in Figure 8-9.
204
FIGURE 8-9: MODIFIED countCategories() MODULE THAT USES count ARRAY
Figure 8-9 shows that when the bedrooms variable value is 0, one is added to count[0]; when the bedrooms
value is 3, one is added to count[3]. In other words, one is added to one of the elements of the count array
instead of to a single variable named count0, count1, count2, or count3. Is this a big improvement over
the original? Of course it isn’t. You still have not taken advantage of the benefits of using the array in this
program.
The true benefit of using an array lies in your ability to use a variable as a subscript to the array, instead of
using a constant such as 1 or 4. Notice in the countCategories() module in Figure 8-9 that within each
decision, the value you are comparing to bedrooms and the constant you are using as a subscript in the
resulting “Yes” process are always identical. That is, when the bedrooms value is 0, the subscript used to
add 1 to the count array is 0; when the bedrooms value is 1, the subscript used for the count array is 1,
and so on. Therefore, why not just use the value of bedrooms as a subscript? You can rewrite the
countCategories() module as shown in Figure 8-10.
205
FIGURE 8-10: MODIFIED countCategories() MODULE USING THE VARIABLE bedrooms AS A SUBSCRIPT TO
THE count ARRAY
Of course, the code segment in Figure 8-10 looks no more efficient than the one in Figure 8-9. However,
notice that in Figure 8-10 the process that occurs after each decision is exactly the same. In each case, no
matter what the value of bedrooms, you always add one to count[bedrooms]. If you are always going to
take the same action no matter what the answer to a question is, why ask the question? Instead, you can
write the countCategories() module as shown in Figure 8-11.
The two steps in Figure 8-11 represent the entire countCategories() module! When the value of bedrooms
is 0, one is added to count[0]; when the value of bedrooms is 1, one is added to count[1], and so on. Now,
you have a big improvement to the previous countCategories() module from Figure 8-9. What’s more, this
countCategories() module does not change whether there are eight, 30, or any other number of types of
apartment requests and count array elements, as long as the values in the bedrooms variable are
numbered sequentially. To use more than four counters, you would declare additional count elements in
the housekeeping() module, but the countCategories() logic would remain the same as it is in Figure 8-11.
The finish() module originally shown in Figure 8-7 can also be improved. Instead of four separate print
statements, you can use a variable to control a printing loop, as shown in Figure 8-12. Because the finish()
module follows the eof condition, all input records have been used, and the bedrooms variable is not
currently holding any needed information. In finish(), you can set bedrooms to 0, and then print bedrooms
and count[bedrooms]. Then add 1 to bedrooms and use the same set of instructions again. You can use
206
bedrooms as a loop control variable to print the four individual count values. The improvement in this
finish() module over the one shown in Figure 8-7 is not as dramatic as the improvement in the
countCategories() module, but in a program with more count elements, the only change to the finish()
module would be in the constant value you use to control the end of the loop. Twelve or 30 count values
can print as easily as four if they are stored in an array.
Within the finish() module in Figure 8-12, the bedrooms variable is handy to use as a subscript, but any
variable could have been used as long as it was:
Numeric with no decimal places
Initialized to 0
Incremented by 1 each time the logic passed through the loop
In other words, nothing is linking bedrooms to the count array per se; within the finish() module, you can
simply use the bedrooms variable as a subscript to indicate each successive element within the count array.
The apartment request report program worked when the countCategories() module contained a long
series of decisions and the finish() module contained a long series of print statements, but the program is
easier to write when you employ arrays. Additionally, the program is more efficient, easier for other
programmers to understand, and easier to maintain. Arrays are never mandatory, but often they can
drastically cut down on your programming time and make a program easier to understand.
207
8.4 ARRAY DECLARATION AND INITIALIZATION
In the apartment request report program, the four count array elements were declared and initialized to
0s in the housekeeping() module. The count values need to start at 0 so they can be added to during the
course of the program. Originally (see Figure 8-8), you provided initialization in the housekeeping() module
as: num count[0] = 0 num count[1] = 0 num count[2] = 0
num count[3] = 0
Separately declaring and initializing each count element is acceptable only if there are a small number of
counts. If the apartment request report program were updated to keep track of 30 types of apartments,
you would have to initialize 30 separate count fields. It would be tedious to write 30 separate
declaration statements.
Programming languages do not require the programmer to name each of the 30 counts: count[0], count[1],
and so on. Instead, you can make a declaration such as one of those in Figure 8-13.
FIGURE 8-13: DECLARING A 30-ELEMENT ARRAY NAMED count IN SEVERAL COMMON LANGUAGES
All the declarations in Figure 8-13 have two things in common: They name the count array and indicate
that there will be 30 separate numeric elements. For flowcharting or pseudocode purposes, a statement
such as num count[30] indicates the same thing.
Declaring a numeric array does not necessarily set its individual elements to 0 (although it does in some
programming languages, such as BASIC, Visual Basic, and Java). Most programming languages allow the
equivalent of num count[30] all set to 0; you should use a statement like this when you want to initialize
an array in your flowcharts or pseudocode. Explicitly initializing all variables is a good programming
practice; assuming anything about noninitialized variable values is a dangerous practice. Array elements
are no exception to this rule.
Alternatively, to start all array elements with the same initial value, you can use an initialization loop within
the housekeeping() module. An initialization loop is a loop structure that provides initial values for every
element in any array. To create an initialization loop, you must use a numeric variable as a subscript. For
example, if you declare a field named sub, and initialize sub to 0, then you can use a loop like the one
shown in the housekeeping() module in Figure 8-14 to set all the array elements to 0. As the value of sub
increases from 0 through 29, each corresponding count element is assigned 0.
208
FIGURE 8-14: A housekeeping() MODULE DEMONSTRATING ONE METHOD OF INITIALIZING ARRAY
ELEMENTS
The array that you used to accumulate apartment-type requests in the previous section contained four
variables whose values were altered during the execution of the program. The values in which you were
most interested, the count of the number of requests for each type of apartment, were created during an
actual run, or execution, of the program. In other words, if 1,000 prospective tenants are interested in
studio apartments, you don’t know that fact at the beginning of the program. Instead, that value is
accumulated during the execution of the program and not known until the end.
Some arrays are not variable, but are meant to be constant. With some arrays, the final desired values are
fixed at the beginning of the program.
For example, let’s say you own an apartment building with five floors, including a basement, and you have
records for all your tenants with the information shown in Figure 8-15. The combination of each tenant’s
floor number and apartment letter provides you with a specific apartment—for example, apartment 0D or
3B.
To create a computer program that prints each tenant’s name and rent due, you could use five decisions
concerning the floor number. However, it is more efficient to use an array to hold the five rent figures. The
array’s values are constant because you set them once at the beginning of the program, and they never
change.
The mainline logic for this program is shown in Figure 8-17. The housekeeping module is named prep().
When you declare variables within the prep() module, you create an array for the five rent figures and set
num rent[0] = 350, num rent[1] = 400, and so on. The rent amounts are hard coded into the array; that is,
they are explicitly assigned to the array elements. The prep() module is shown in Figure 8-18.
FIGURE 8-17: FLOWCHART AND PSEUDOCODE FOR MAINLINE LOGIC OF RENT PROGRAM
210
FIGURE 8-18: FLOWCHART AND PSEUDOCODE FOR prep() MODULE OF RENT PROGRAM
At the end of the prep() module, you read a first record into memory. The record contains a tenant name
(tenName), floor (tenFloor), and apartment letter (tenAptLetter). When the logic enters figureRent() (the
main loop), you can print three items: “Dear ”, tenName, and “, Here is your monthly rent bill” (the quote
begins with a comma that follows the recipient’s name). Then, you must print the rent amount. Instead of
making a series of selections such as if tenFloor = 0 then print rent[0] and if tenFloor = 1 then print rent[1],
you want to take advantage of the rent array. The solution is to create a figureRent() module that looks
like Figure 8-19. You use the tenFloor variable as a subscript to access the correct rent array element.
When deciding which variable to use as a subscript with an array, ask yourself, “Of all the values available
in the array, what does the correct selection depend on?” When printing a rent value, the rent you use
depends on the floor on which the tenant lives, so the correct action is print rent[tenFloor].
FIGURE 8-19: FLOWCHART AND PSEUDOCODE FOR THE figureRent() MODULE OF THE RENT PROGRAM
The cleanUp() module for this program is very simple—just close the files. See Figure 8-20.
Without a rent array, the figureRent() module would have to contain four decisions and five different
resulting actions. With the rent array, there are no decisions. Each tenant’s rent is simply based on the
rent element that corresponds to the tenFloor variable because the floor number indicates the
positional value of the correspondingrent. Arrays can really lighten the workload required to write a
program.
211
8.6 LOADING AN ARRAY FROM A FILE
Writing the rent program from the previous section requires you to set values for five rent array elements
within the prep() module. If you write the rent program for a skyscraper, you may have to initialize 100
array elements. Additionally, when the building management changes the rent amounts, you must alter
the array element values within the program to reflect the new rent charges. If the rent values change
frequently, it is inconvenient to have hard-coded values in your program. Instead, you can write your
program so that it loads the array rent amounts from a file. The array of rent values is an example of an
array that gets its values during the execution of the program.
A file that contains all the rent amounts can be updated by apartment building management as frequently
as needed. Suppose you periodically receive a file named RENTFILE that is created by the building
management and always contains the current rent values. You can write the rent program so that it accepts
all records from this input file within the prep() module. Figure 8-21 shows how this is accomplished.
FIGURE 8-21: FLOWCHART AND PSEUDOCODE FOR prep() MODULE THAT READS RENT VALUES FROM AN
INPUT FILE
In the prep() module in Figure 8-21, you set the variable count to 0 and read a rentRec record from
RENTFILE. Each record in RENTFILE contains just one field—a numeric rentAmt value. For this program,
assume that the rent records in RENTFILE are stored in order by floor. When you read the first rentAmt,
you store it in the first element of the rent array. You increase the count to 1, read the second record, and,
212
assuming it’s not eof, you store the second rent in the second element of the rent array. After RENTFILE is
exhausted and the rent array is filled with appropriate rent amounts for each floor, you begin to read the
file containing the tenantRec records, and then the program proceeds as usual.
When you use this method—reading the rents from an input file instead of hard coding them into the
program—clerical employees can update the rentRec values in RENTFILE. Your program takes care of
loading the rents into the program array from the most recent copy of RENTFILE, ensuring that each rent
is always accurate and up to date. Using this technique, you avoid the necessity of changing code within
the program with each rent update.
In both the apartment request program and the rent program that you’ve seen in this chapter, the fields
that the arrays depend on conveniently hold small whole numbers. The number of bedrooms available in
apartments are zero through three, and the floors of the building are zero through four.
Unfortunately, real life doesn’t always happen in small integers. Sometimes, you don’t have a variable that
conveniently holds an array position; sometimes, you have to search through an array to find a value you
need.
Consider a mail-order business in which orders come in with a customer name, address, item number
ordered, and quantity ordered, as shown in Figure 8-22.
The item numbers are three-digit numbers, but perhaps they are not consecutive 000 through 999.
Instead, over the years, items have been deleted and new items have been added. For example, there
might no longer be an item with number 005 or 129. Sometimes, there might be a hundred-number gap
or more between items.
For example, let’s say that this season you are down to the items shown in Figure 8-23. When a customer
orders an item, you want to determine whether the order is for a valid item number. You could use a series
of six decisions to determine whether the ordered item is valid; in turn, you would compare whether each
customer’s item number is equal to one of the six allowed values. However, a superior approach is to
create an array that holds the list of valid item numbers. Then, you can search through the array for an
exact match to the ordered item. If you search through the entire array without finding a match for the
item the customer ordered, you can print an error message, such as “No such item.”
Suppose you create an array with the six elements shown in Figure 8-24. If a customer orders item 307, a
clerical worker can tell whether it is valid by looking down the list and verifying that 307 is a member of
the list. In a similar fashion, you can use a loop to test each validItem against the ordered item number.
213
FIGURE 8-23: AVAILABLE ITEMS IN MAIL-ORDER COMPANY FIGURE 8-24: ARRAY OF VALID ITEM NUMBERS
The technique for verifying that an item number exists involves setting a subscript to 0 so that you can
start searching from the first array element, and initializing a flag variable to indicate that you have not yet
determined whether the customer’s order is valid. A flag is a variable that you set to indicate whether
some event has occurred; frequently, it holds a True or False value. For example, you can set a character
variable named foundIt to “N”, indicating “No”. Then you compare the customer’s ordered item number
to the first item in the array. If the customer-ordered item matches the first item in the array, you can set
the flag variable to “Y”, or any other value that is not “N”. If the items do not match, you increase the
subscript and continue to look down the list of numbers stored in the array. If you check all six valid item
numbers and the customer item matches none of them, then the flag variable foundIt still holds the value
“N”. If the flag variable is “N” after you have looked through the entire list, you can issue an error message
indicating that no match was ever found. Assuming you declare the customer item as custItemNo and the
subscript as x, then Figure 8-25 shows a flowchart segment and the pseudocode that accomplishes the
item verification.
FIGURE 8-25: FLOWCHART AND PSEUDOCODE SEGMENTS FOR FINDING AN EXACT MATCH TO A CUSTOMER
ITEM NUMBER
214
8.8 USING PARALLEL ARRAYS
In a mail-order company, when you read a customer’s order, you usually want to accomplish more than
simply verifying that the item exists. You want to determine the price of the ordered item, multiply that
price by the quantity ordered, and print a bill. Suppose you have prices for six available items, as shown in
Figure 8-26.
You could write a program in which you read a customer order record and then use the customer’s item
number as a subscript to pull a price from an array. To use this method, you need an array with at least
689 elements. If a customer orders item 405, the price is found at validItem[custItemNo], which is
validItem[405], or the 406th element of the array (because the 0th element is the first element of the
array). Such an array would need 689 elements (because the highest item number is 688), but because
you sell only six items, you would waste 683 of the memory positions. Instead of reserving a large quantity
of memory that remains unused, you can set up this program to use two arrays.
Consider the mainline logic in Figure 8-27 and the ready() module in Figure 8-28. Two arrays are set up
within the ready() module. One contains six elements named validItem; all six elements are valid item
numbers. The other array also has six elements. These are named validItemPrice; all six elements are
prices. Each price in this validItemPrice array is conveniently and purposely in the same position as the
corresponding item number in the other validItem array. Two corresponding arrays such as these are
parallel arrays because each element in one array is associated with the element in the same relative
position in the other array.
215
FIGURE 8-27: MAINLINE LOGIC FOR THE PRICE PROGRAM
You can write the getPrice() module as shown in Figure 8-29. The general procedure is to read each item
number, look through each of the validItem values separately, and when a match for the custItemNo
variable on the input record is found, pull the corresponding parallel price out of the list of
validItemPrice values.
216
FIGURE 8-29: THE getPrice() MODULE FOR THE PRICE PROGRAM
You must create a variable to use as a subscript for the arrays. If you name the subscript x (see the
declaration of x in the variable list in Figure 8-28), then you can start by setting x equal to 0. Then, if
custItemNo is the same as validItem[x], you can use the corresponding price from the other table,
validItemPrice[x], to calculate the customer’s bill.
Within the getPrice() module, the variable used as a subscript, x, is set to 0. If custItemNo is not the same
as validItem[x], then add 1 to x. Because x now holds the value 1, you next compare the customer’s
requested item number to validItem[1]. The value of x keeps increasing, and eventually a match between
custItemNo and some validItem[x] should be found.
After you find a match for the custItemNo variable in the validItem array, you know that the price of that
item is in the same position in the other array, validItemPrice. When validItem[x] is the correct item,
validItemPrice[x] must be the correct price.
Suppose that a customer orders item 457, and walk through the flowchart yourself to see if you come up
with the correct price.
8.9 REMAINING WITHIN ARRAY BOUNDS
The getPrice() module in Figure 8-29 is not perfect. The logic makes one dangerous assumption: that every
customer will order a valid item number. If a customer is looking at an old catalog and orders item 107,
the program will never find a match. The value of x will just continue to increase until it reaches a value
217
higher than the number of elements in the array. At that point, one of two things happens. When you use
a subscript value that is higher than the number of elements in an array, some programming languages
stop execution of the program and issue an error message. Other programming languages do not issue an
error message but continue to search through computer memory beyond the end of the array. Either way,
the program doesn’t end elegantly. When you use a subscript that is not within the range of acceptable
subscripts, your subscript is said to be out of bounds. Ordering a wrong item number is a frequent
customer error; a good program should be able to handle the mistake and not allow the subscript to go
out of bounds.
You can improve the price-finding program by adding a flag variable and a test to the getPrice() module.
You can set the flag when you find a valid item in the validItem array, and after searching the array, check
whether the flag has been altered. See Figure 8-30.
218
FIGURE 8-30: THE getPrice() MODULE USING THE foundIt FLAG
In the ready() module, you can declare a variable named foundIt that acts as a flag. When you enter the
getPrice() module, you can set foundIt equal to “No”. Then, after setting x to 0, check to see if x is still less
than 6. If it is, compare custItemNo to validItem[x]. If they are equal, you know the position of the item’s
price, and you can use the price to print the customer’s bill and set the foundIt flag to “Yes”. If custItemNo
is not equal to validItem[x], you increase x by 1 and continue to search through the array. When x is 6, you
shouldn’t look through the array anymore; you’ve gone through all six legitimate items, and you’ve
reached the end. The legitimate subscripts for a six-element array are 0 through 5; your subscript variable
should not be used with the array when it reaches 6. If foundIt doesn’t have a “Yes” in it at this point, it
219
means you never found a match for the ordered item number; you never took the Yes path leading from
the custItemNo = validItem[x]? question. If foundIt does not have “Yes” stored in it, you should print an
error message; the customer has ordered a non-existent item.
The mail-order program is still a little inefficient. The problem is that if lots of customers order item 106 or
108, their price is found on the first or second pass through the loop. The program continues searching
through the item array, however, until x reaches the value 6. One way to stop the search once the item
has been found, and foundIt is set to “Yes”, is to set x to 6 immediately. (Setting a variable to a specific
value, particularly when the new value is an abrupt change, is also called forcing the variable to that value.)
Then, when the program loops back to check whether x is still less than 6, the loop will be exited and the
program won’t bother checking any of the higher item numbers. Leaving a loop as soon as a match is found
is called an early exit; it improves the program’s efficiency. The larger the array, the more beneficial it
becomes to exit the searching loop as soon as you find what you’re looking for.
Figure 8-31 shows the final version of the price program. Notice the improvement to the getPrice() module.
You search the validItem array, element by element. If an item number is not matched in a given location,
the subscript is increased and the next location is checked. As soon as an item number is located in the
array, you print a line, turn on the flag, and force the subscript to a high number (6) so the program will
not check the item number array any further.
220
FIGURE 8-31: THE FINAL VERSION OF THE PRICE PROGRAM THAT EFFICIENTLY SEARCHES FOR PRICES BASED
ON THE ITEM A CUSTOMER ORDERS
In the previous example, customer item numbers needed to exactly match item numbers stored in a table
to determine the correct price of an item. Sometimes, however, instead of finding exact matches,
programmers want to work with ranges of values in arrays. A range of values is any set of contiguous
values, such as 1 through 5.
221
Recall the customer file description from earlier in this chapter, shown again in Figure 8-32. Suppose the
company decides to offer quantity discounts, as shown in Figure 8-33.
You want to be able to read a record and determine a discount percentage based on the value in the
quantity field. One ill-advised approach might be to set up an array with as many elements as any customer
might ever order, and store the appropriate discount for each possible number, as shown in Figure 8-34.
A better approach is to create just four discount array elements, one for each of the possible discount
rates, as shown in Figure 8-35.
num discount[0] = 0
num discount[1] = 10
222
num discount[2] = 15
num discount[3] = 25
FIGURE 8-35: SUPERIOR DISCOUNT ARRAY
With the new four-element discount array, you need a parallel array to search through, to find the
appropriate level for the discount. At first, beginning programmers might consider creating an array named
discountRange and testing whether the quantity ordered equals one of the four stored values.
For example:
num discountRange[0] = 0 through 9 num
discountRange[1] = 10 through 24 num
discountRange[2] = 25 through 48 num
discountRange[3] = 49 and higher
However, you cannot create an array like the previous one. Each element in any array is simply a single
variable. Any variable can hold a value such as 6 or 12, but it can’t hold every value 6 through 12. Similarly,
the discountRange[0] variable can hold a 1, 2, 9, or any other single value, but it can’t hold 0 through 9;
there is no such numeric value.
One solution is to create an array that holds only the low-end value of each range, as Figure 8-36 shows.
Using such an array, you can compare each custQuantity value with each discountRange value in turn. You
can start with the last range limit (discountRange[3]). If custQuantity is at least that value, 49, the customer
gets the highest discount rate (discount[3]). If custQuantity is not at least discountRange[3], then you
check to see if it is at least discountRange[2], or 25. If so, the customer receives discount[2], and so on. If
you declare a variable named rate to hold the correct discount rate, and another variable named sub to
use as a subscript, then you can use the determineDiscount() module shown in Figure 8- 37. This module
uses a loop to find the appropriate discount rate for an order, then calculates and prints a customer bill.
223
FIGURE 8-37: FLOWCHART AND PSEUDOCODE FOR DISCOUNT DETERMINATION
When using an array to store range limits, you use a loop to make a series of comparisons that would
otherwise require many separate decisions. Your program is written using fewer instructions than would
be required if you did not use an array, and modifications to your program will be easier to make in the
future.
CHAPTER SUMMARY
An array is a series or list of variables in computer memory, all of which have the same name but are
differentiated with special numbers called subscripts.
When you declare an array, you declare a programming structure that contains multiple
elements, each of which has the same name and the same data type. Each array element has a
unique integer subscript indicating how far away the individual element is from the first element.
You often can use a variable as a subscript to an array, replacing multiple nested decisions.
224
You can declare and initialize all of the elements in an array using a single statement that provides
a type, a name, and a quantity of elements for the array. You also can initialize array values within
an initialization loop.
You can use a constant array when the final desired values are fixed at the beginning of the program.
You can load an array from a file. This step is often performed in a program’s housekeeping module.
Searching through an array to find a value you need involves initializing a subscript, using a loop to
test each array element, and setting a flag when a match is found.
In parallel arrays, each element in one array is associated with the element in the same relative
position in the other array.
Your programs should ensure that subscript values do not go out of bounds—that is, take on a value
out of the range of legal subscripts.
When you need to compare a value to a range of values in an array, you can store either the low- or
high-end value of each range for comparison.
KEY TERMS
An array is a series or list of variables in computer memories, all of which have the same name but
are differentiated with special numbers called subscripts.
A subscript is a number that indicates the position of a particular item within an array.
An index is a subscript.
Each separate array variable is one element of the array.
The size of an array is the number of elements it can hold.
In a zero-based array, the first element is accessed using a subscript of 0.
Off-by-one errors usually occur when you assume an array’s first subscript is 1 but it actually is 0.
An initialization loop is a loop structure that provides initial values for every element in any array.
Hard-coded values are explicitly assigned.
A flag is a variable that you set to indicate whether some event has occurred.
Parallel arrays are two or more arrays in which each element in one array is associated with the
element in the same relative position in the other array or arrays.
When you use a subscript that is not within the range of acceptable subscripts, your subscript is said
to be out of bounds.
Forcing a variable to a value is assigning a specific value to it, particularly when the assignment
causes a sudden change in value.
Leaving a loop as soon as a match is found is called an early exit. A
range of values is any set of contiguous values.
REVIEW QUESTIONS
1. A subscript is a(n) .
a. element in an array
b. alternate name for an array
c. number that indicates the position of a particular item within an array
225
d. number that represents the highest value stored within an array
5. Suppose you have an array named number, and two of its elements are number[1] and number[4].
You know that _.
a. the two elements hold the same value
b. the two elements are at the same memory location
c. the array holds exactly four elements
d. there are exactly two elements between those two elements
6. Suppose you want to write a program that reads customer records and prints a summary of the
number of customers who owe more than $1,000 each, in each of 12 sales regions. Customer fields
include name, zipCode, balanceDue, and regionNumber. At some point during record processing, you
would add 1 to an array element whose subscript would be represented by _. a. name
b. zipCode
c. balanceDue
d. regionNumber
8. Suppose you create a program with a seven-element array that contains the names of the days of the
week. In the housekeeping() module, you display the day names using a subscript named dayNum.
In the same program, you display the same array values again in the finish() module. In the finish()
module, you as a subscript to the array. a. must use dayNum
b. can use dayNum, but can also use another variable
c. must not use dayNum
d. must use a numeric constant
226
9. Declaring a numeric array sets its individual elements’ values to _.
a. zero in every programming language
b. zero in some programming languages
c. consecutive digits in every programming language
d. consecutive digits in some programming languages
10. A array is one in which the stored values are fixed permanently at the start of the program.
a. constant
b. variable
c. persistent
d. continual
11. When you create an array of values that you explicitly set upon creation, using numeric constants,
the values are said to be _. a. postcoded
b. precoded
c. soft coded
d. hard coded
12. Many arrays contain values that change periodically. For example, a bank program that uses an array
containing mortgage rates for various terms might change several times a day. The newest values are
most likely _.
a. typed into the program by a programmer who then recompiles the program before it is used
b. calculated by the program, based on historical trends
c. read into the program from a file that contains the current rates
d. typed in by a clerk each time the program is executed for a customer
14. Two arrays in which each element in one array is associated with the element in the same relative
position in the other array are arrays. a. cohesive
b. perpendicular
c. hidden
d. parallel
15. In most programming languages, the subscript used to access the last element in an array declared
as num values[12]is .
a. 0
b. 11
c. 12
d. 13
16. In most programming languages, a subscript for a 10-element array is out of bounds when it
. a. is lower than 0
b. is higher than 9
227
c. both of these
d. neither a nor b
17. If you perform an early exit from a loop while searching through an array for a match, you _. a.
quit searching as soon as you find a match
b. quit searching before you find a match
c. set a flag as soon as you find a match, but keep searching for additional matches
d. repeat a search only if the first search was unsuccessful
20. After the annual dog show in which the Barkley Dog Training Academy awards points to each
participant, the Academy assigns a status to each dog based on the following criteria: Points Earned
Level of Achievement
0–5 Good
6–7 Excellent
8–9 Superior
10 Unbelievable
The Academy needs a program that compares a dog’s points earned with the grading scale, in order to
award a certificate acknowledging the appropriate level of achievement. Of the following, which set of
values would be most useful for the contents of an array used in the program? a. 0, 6, 9, 10
b. 5, 7, 8, 10
c. 5, 7, 9, 10
d. any of these
Each of the following pseudocode segments contains one or more bugs that you must find and correct.
1. This application prints a summary report for an aluminum can recycling drive at a high school. When
a student brings in cans, a record is created that contains two fields—the student’s year in school (1, 2,
3, or 4) and the number of cans submitted. Student records have not been sorted. The report lists each
of the four classes and the total number of cans recycled for each class.
start
perform housekeeping()
228
while not eof perform accumulateCans()
endwhile
perform finish()
stop
housekepping() declare
variables
studentRec
read studentRec
return
finish()
print heading1
print heading2
year = 1
while year < SIZE
2. This application prints a report card for each student at Pedagogic College. A record has been created
for each student containing the student’s name, address, and zip code, as well as a numer ic average
(from 0 through 100) for all the student’s work for the semester. A report card is printed for each student
containing the student’s name, address, city, state, and zip code, as well as a letter grade based on the
following scale:
229
90–100 A
80–89 B
70–79 C
60–69 D
59 and below F
The student’s city and state are determined from the student’s zip code. A file is read containing three
fields—zip code, city, and state—for each of the 100 zip codes the college serves. For this program,
assume that all the student averages have been verified to be between 0 and 100 inclusive and that all
the zip codes have been verified as valid and stored in the zip code file.
start perform
housekeeping()
while not eof perform
produceGradeReport()
endwhile
perform finish()
stop
housekepping() declare
variables
studentRec
charƒname
charƒaddress num
zipCode num
average
zipRec
num zip
char city
char state
const num ZIPSIZE = 100
num storedZip[ZIPSIZE]
char storedCity[ZIPSIZE]
char storedState[SIZE]
230
const char grade[0] = 'A'
const char grade[1] = 'B'
const char grade[2] = 'C'
const char grade[3] = 'S'
const char grade[4] = 'F'
num zipCodeCount
char zipFound
zipCodeCount = 0
read zipRec
produceGradeReport() print
“Grade Report” print
name
print address
zipFound = “N”
sub = 0
while zipFound = “N” if zipCode =
storedZip[ZIPCODESIZE] print
storedCity[ZIPCODESIZE] print
storedState[ZIPCODESIZE] print
zipCode
zipFound = “Y”
endif sub = sub + 1
endwhile sub
=0
while sub < GRADESIZE if average >=
gradeLevel[sub] then
print grade[sub]
sub = 0
endif
endwhile
read studentRec
231
return
finish()
close files return
EXERCISES
1. The city of Cary is holding a special census. The census takers collect one record for each citizen, as
follows:
a. Design the output for this program; create either sample output or a print chart. b.
Create the hierarchy chart.
c. Draw the flowchart.
d. Write the pseudocode.
2. The Midville Park District maintains records containing information about players on its soccer teams.
Each record contains a player’s first name, last name, and team number. The teams are:
Soccer Teams
TEAM NUMBER TEAM NAME
1 Goal Getters
2 The Force
3 Top Guns
4 Shooting Stars
5 Midfield Monsters
Design the logic for a report that lists all players along with their team numbers and team names.
a. Design the output for this program; create either sample output or a print chart. b.
Create the hierarchy chart.
c. Draw the flowchart.
d. Write the pseudocode.
232
3. Create the logic for a program that produces a count of the number of players registered for each team
listed in Exercise 2.
a. Design the output for this program; create either sample output or a print chart. b.
Create the hierarchy chart.
c. Draw the flowchart.
d. Write the pseudocode.
4. An elementary school contains 30 classrooms numbered 1 through 30. Each classroom can contain any
number of students up to 35. Each student takes an achievement test at the end of the school year and
receives a score from 0 through 100. One record is created for each student i n the school; each record
contains a student ID, classroom number, and score on the achievement test. Design the logic for a
program that lists the total points scored for each of the 30 classroom groups.
a. Design the output for this program; create either sample output or a print chart. b.
Create the hierarchy chart.
c. Draw the flowchart.
d. Write the pseudocode.
5. Modify Exercise 4 so that each classroom’s average of the test scores prints, rather than each
classroom’s total.
6. The school in Exercises 4 and 5 maintains a file containing the teacher’s name for each classroom. Each
record in this file contains a room number from 1 through 30, and the last name of the teacher. Modify
Exercise 5 so that the correct teacher’s name appears on the list with his or her class’s average.
Design the logic for a program that reads a record containing a customer number and item name, and
then prints either the correct price or the message “Sorry, we do not carry that” as output.
8. Each week, the home office for a fast-food restaurant franchise distributes a file containing new prices
for the items it carries. The file contains the item name and current price. Design the logic for a program
that loads the current values into arrays. Then, the program reads a record containing a customer
number and item name, and prints either the correct price or the message “Sorry, we do not carry that”
as output.
Design the logic of a program that produces a count of the number of citizens in each of the following
age groups: under 18, 18 through 30, 31 through 45, 46 through 64, and 65 and older.
a. Design the output for this program; create either sample output or a print chart. b.
Create the hierarchy chart.
c. Draw the flowchart.
d. Write the pseudocode.
10. A company desires a breakdown of payroll by department. Input records are as follows:
a. Design the output for this program; create either sample output or a print chart. b.
Create the hierarchy chart.
c. Draw the flowchart.
d. Write the pseudocode.
11. Modify Exercise 10 so that the report lists department names as well as numbers. The department
names are:
12. Modify the report created in Exercise 11 so that it prints a line of information for each employee
before printing the department summary at the end of the report. Each detail line must contain the
employee’s name, department number, department name, hourly wage, hours worked, gross pay,
and withholding tax. Withholding taxes are based on the following percentages of gross pay:
Withholding Taxes
WEEKLY SALARY WITHHOLDING %
0.00–200.00 10
200.01–350.00 14
350.01–500.00 18
500.01–up 22
13. The Perfect Party Catering Company keeps records concerning the events it caters as follows:
Day Numeric 15
Additionally, a meal file contains the meal selection codes (such as 4), name of entree (such as “Roast
beef”), and current price per guest (such as 19.50). Assume there are eight numbered meal records in
the file.
Design the logic for a program that produces a report that lists each event number, host name, date,
meal, guests, gross total price for the party, and price for the party after discount. Print the month
name—for example, “October”—rather than “10”. Print the meal selection—for example, “Roast
beef”—rather than “4”. The gross total price for the party is the price per guest for the meal times the
number of guests. The final price includes a discount based on the following table:
a. Design the output for this program; create either sample output or a print chart. b.
Create the hierarchy chart.
c. Draw the flowchart.
d. Write the pseudocode.
14. Daily Life Magazine wants an analysis of the demographic characteristics of its readers. The
Marketing Department has collected reader survey records in the following format:
a. Create the logic for a program that would produce a count of readers by age groups as follows: under
20, 20–29, 30–39, 40–49, and 50 and older.
b. Create the logic for a program that would produce a count of readers by gender within age group—
that is, under 20 females, under 20 males, under 30 females, under 30 males, and so on.
c. Create the logic for a program that would produce a count of readers by income groups as follows:
under $20,000, $20,000–$24,999, $25,000–$34,999, $35,000–$49,999, and $50,000 and up.
15. Glen Ross Vacation Property Sales employs seven salespeople as follows:
Salespeople
ID NUMBER NAME
103 Darwin
104 Kratz
201 Shulstad
319 Fortune
367 Wickert
388 Miller
435 Vick
When a salesperson makes a sale, a record is created including the date, time, and dollar amount of the
sale, as follows: The time is expressed in hours and minutes, based on a 24-hour clock. The sale amount
is expressed in whole dollars.
236
File name: SALES
FIELD DESCRIPTION DATA TYPE EXAMPLE
Salesperson Numeric 319
Month Numeric 02
Day Numeric 21
Year Numeric 2008
Time Numeric 1315
Sale Amount Numeric 95900
Salespeople earn a commission that differs for each sale, based on the following rate schedule:
Commission Rates
SALE AMOUNT RATE
$0–$50,000 .04
$50,001–$125,000 .05
$125,001–$200,000 .06
$200,001 and up .07
Design the output and either the flowchart or pseudocode that produces each of the following
reports:
a. A report listing each salesperson number, name, total sales, and total commissions
b. A report listing each month of the year as both a number and a word (for example, “01 January”), and
the total sales for the month for all salespeople
c. A report listing total sales as well as total commissions earned by all salespeople for each of the following
time frames, based on hour of the day: 00–05, 06–12, 13–18, and 19–23
TOPIC 9
LEARNING OUTCOMES
After Studying this topic you should be able to:
Understand sequential files and the need for merging them
Create the mainline and housekeeping() logic for a merge program
Create the mergeFiles() and finishUp() modules for a merge program
Modify the housekeeping() module to check for eof
Understand master and transaction file processing
Match files to update master file fields
Allow multiple transactions for a single master file record
Update records in sequential files
237
9.1 UNDERSTANDING SEQUENTIAL DATA FILES AND THE NEED FOR MERGING FILES
A sequential file is a file in which records are stored one after another in some order. One option is to store
records in a sequential file in the order in which the records are created. For example, if you maintain
records of your friends, you might store the records as you make the friends; you could say the records
are stored in temporal order—that is, in order based on time. At any point in time, the records of your
friends will be stored in sequential order based on how long you have known them—the data stored about
your best friend from kindergarten is record 1, and the data about the friend you just made last week could
be record 30.
Instead of temporal order, records in a sequential file are more frequently stored based on the contents
of one or more fields within each record. Perhaps it is most useful for you to store your friends’ records
sequentially in alphabetical order by last name, or maybe in order by birthday.
Businesses often need to merge two or more sequential files. Merging files involves combining two or
more files while maintaining the sequential order. For example:
Suppose you have a file of current employees in Social Security number order and a file of newly
hired employees, also in Social Security number order. You need to merge these two files into one
combined file before running this week’s payroll program.
Suppose you have a file of parts manufactured in the Northside factory in part-number order and a
file of parts manufactured in the Southside factory, also in part-number order. You need to merge
these two files into one combined file, creating a master list of available parts.
Suppose you have a file that lists last year’s customers in alphabetical order and another file that lists
this year’s customers in alphabetical order. You want to create a mailing list of all customers in
order by last name.
Before you can easily merge files, two conditions must be met:
For example, suppose your business has two locations, one on the East Coast and one on the West Coast,
and each location maintains a customer file in alphabetical order by customer name. Each file contains
fields for name and customer balance. You can call the fields in the East Coast file eastName and
eastBalance, and the fields in the West Coast file westName and westBalance. You want to merge the two
files, creating one master file containing records for all customers. Figure 9-1 shows some sample data for
the files; you want to create a merged file like the one shown in Figure 9-2.
238
FIGURE 9-1: SAMPLE DATA CONTAINED IN TWO CUSTOMER FILES
9.2 CREATING THE MAINLINE AND housekeeping() LOGIC FOR A MERGE PROGRAM
The mainline logic for a program that merges two files is similar to the main logic you’ve used before in
other programs: it contains a housekeeping() module, a mergeFiles() module that repeats until the end of
the program, and a finishUp() module. Most programs you have written would repeat the main, central
module (in this program, the mergeFiles() module) until the eof condition occurs. In a program that merges
files, there are two input files, so checking for eof on one of them is insufficient. Instead, the mainline logic
will check a flag variable that you create with a name such as bothAtEof. You will set the bothAtEof flag to
“Y” after you have encountered eof in both input files. Figure 9-3 shows the mainline logic.
FIGURE 9-3: FLOWCHART AND PSEUDOCODE FOR MAINLINE LOGIC OF THE MERGE PROGRAM
239
When you declare variables within the housekeeping() module, you must declare the bothAtEof flag and
initialize it to “N” to indicate that the input files have not yet reached the end-of-file condition. In addition,
you need to define two input files, one for the file from the East Coast office and one for the file from the
West Coast office. Figure 9-4 shows that the files are called eastFile and westFile. Their variable fields are
eastName, eastBalance, westName, and westBalance, respectively.
At the end of a housekeeping() module, typically you read the first file input record into memory. In this
filemerging program with two input files, you will read one record from each input file into memory at the
end of the housekeeping() module.
The output from the merge program is a new, merged file containing all records from the two original
input files. Logically, writing to a file and writing a printed report are very similar—each involves sending
data to an output device. The major difference is that when you write a data file, typically you do not
include headings or other formatting for people to read, as you do when creating a printed report. A data
file contains only data for another computer program to read.
FIGURE 9-4: FLOWCHART AND PSEUDOCODE FOR THE housekeeping() MODULE IN THE MERGE PROGRAM,
VERSION 1
9.3 CREATING THE mergeFiles() AND finishUp() MODULES FOR A MERGE PROGRAM
When you begin the mergeFiles() module, two records—one from eastFile and one from westFile— are
sitting in the memory of the computer. One of these records needs to be written to the new output file
first. Which one? Because the two input files contain records stored in alphabetical order, and you want
the new file to store records in alphabetical order, you first output the input record that has the lower
alphabetical value in the name field. Therefore, the mergeFiles() module begins as shown in Figure 9-5.
240
FIGURE 9-5: BEGINNING OF THE mergeFiles() MODULE OF THE MERGE PROGRAM
Using the sample data from Figure 9-1, you can see that the record from the East Coast file containing
“Able” should be written to the output file, while Chen’s record from the West Coast file waits in memory
because the eastName value “Able” is alphabetically lower than the westName value “Chen”. After you
write Able’s record, should Chen’s record be written to the output file next? Not necessarily. It depends
on the next eastName following Able’s record in eastFile. When data records are read into memory from
a file, a program typically does not “look ahead” to determine the values stored in the next record.
Instead, a program usually reads the record into memory before making decisions about its contents. In
this program, you need to read the next eastFile record into memory and compare it to “Chen”. Because
in this case the next record in eastFile contains the name “Brown”, another eastFile record is written; no
westFile records are written yet.
After the first two eastFile records, is it Chen’s turn to be written now? You really don’t know until you
read another record from eastFile and compare its name value to “Chen”. Because this record contains
the name “Dougherty”, it is indeed time to write Chen’s record. After Chen’s record is written to output,
should you now write Dougherty’s record? Until you read the next record from westFile, you don’t know
whether that record should be placed before or after Dougherty’s record.
Therefore, the mergeFiles() module proceeds like this: compare two records, write the record with the
lower alphabetical name, and read another record from the same input file. See Figure 9-6.
241
FIGURE 9-6: CONTINUATION OF THE mergeFiles() MODULE FOR THE MERGE PROGRAM
Recall the names from the two original files (see Figure 9-7) and walk through the processing steps.
1. Compare “Able” and “Chen”. Write Able’s record. Read Brown’s record from eastFile.
2. Compare “Brown” and “Chen”. Write Brown’s record. Read Dougherty’s record from eastFile.
3. Compare “Dougherty” and “Chen”. Write Chen’s record. Read Edgar’s record from westFile.
4. Compare “Dougherty” and “Edgar”. Write Dougherty’s record. Read Hanson’s record from eastFile.
5. Compare “Hanson” and “Edgar”. Write Edgar’s record. Read Fell’s record from westFile.
6. Compare “Hanson” and “Fell”. Write Fell’s record. Read Grand’s record from westFile.
7. Compare “Hanson” and “Grand”. Write Grand’s record. Read from westFile, encountering eof.
What happens when you reach the end of the West Coast file? Is the program over? It shouldn’t be,
because records for Hanson, Ingram, and Johnson all need to be included in the new output file, and none
of them is written yet. You need to find a way to write the Hanson record as well as read and write all the
remaining eastFile records. And you can’t just write statements to read and write from eastFile;
sometimes, when you run this program, records in eastFile will finish first alphabetically, and in that case
you need to continue reading from westFile.
An elegant solution to this problem involves setting the field on which the merge is based to a “high” value
when the end of the file is encountered. A high value is one that is greater than any possible value in a
field. Programmers often use all 9s in a numeric field and all Zs in a character field to indicate a high value.
Every time you read from westFile you can check for eof, and when it occurs, set westName to “ZZZZZ”.
Similarly, when reading eastFile, set eastName to “ZZZZZ” when eof occurs. When both eastName and
westName are “ZZZZZ”, then you set the bothAtEof variable to “Y”.
242
Using the sample data in Figure 9-7, after Grand’s record is processed, westFile is read and eof is
encountered, so westName gets set to “ZZZZZ”. Now, when you enter the mergeFiles() module again,
eastName and westName are compared, and eastName is still “Hanson”. The eastName value (Hanson) is
lower than the westName value (ZZZZZ), so the data for eastName’s record writes to the output file, and
another eastFile record (Ingram) is read.
The complete run of the file-merging program now executes the first six of the seven steps as listed
previously, and then proceeds as follows, starting with a modified Step 7:
7. Compare “Hanson” and “Grand”. Write Grand’s record. Read from westFile, encountering eof and
setting westName to “ZZZZZ”.
8. Compare “Hanson” and “ZZZZZ”. Write Hanson’s record. Read Ingram’s record.
9. Compare “Ingram” and “ZZZZZ”. Write Ingram’s record. Read Johnson’s record.
10. Compare “Johnson” and “ZZZZZ”. Write Johnson’s record. Read from the eastFile, encountering eof
and setting eastName to “ZZZZZ”. 11. Now that both names are “ZZZZZ”, set the flag bothAtEof equal to
“Y”.
endif
endif
if eastName = "ZZZZZ" then if
westName = "ZZZZZ" then
bothAtEof = "Y"
endif
endif
return
When the bothAtEof flag variable equals “Y” at the end of the mergeFiles() module, the mainline logic then
proceeds to the finishUp() module. See Figure 9-8.
243
FIGURE 9-8: THE finishUp() MODULE FOR THE MERGE PROGRAM
9.4 MODIFYING THE housekeeping() MODULE IN THE MERGE PROGRAM TO CHECK FOR eof
Recall that in the housekeeping() module for the merge program that combines East Coast and West Coast
customer files, you read one record from each of the two input files. Although it is unlikely that you will
reach the end of the file after attempting to read the first record in a file, it is good practice to check for
eof every time you read. In the housekeeping() module, you first read from one of the input files. Whether
you encounter eof or not, you then read from the second input file. If both files are at eof, then both name
fields are set to “ZZZZZ”, and you can set the bothAtEof flag to “Y”. Then, when the housekeeping() module
ends, if the value of bothAtEof is “Y”, it means that there are no records to merge, and the mainline logic
will immediately send the program to the finishUp() module. The complete merge program, including
the newly modified housekeeping() module that checks for the end of each input file.
THE COMPLETE FILE MERGE PROGRAM
start
perform housekeeping()
while bothAtEof = “N”
perform mergeFiles()
endwhile perform finishUp()
stop
endif
endif
244
return
endif
endif
if eastName = “ZZZZZ” then if
westName = “ZZZZZ” then
bothAtEof = “Y”
endif
endif
return
finishUp()
close files return
When two related sequential files seem “equal,” in that they hold the same type of information —for
example, when one holds customers from the East Coast and one holds customers from the West Coast—
you often need to merge the files to use them as a single unit. When you merge records from two or more
files, the records (almost) always contain the same fields in the same order; in other words, every record
in the merged file has the same format.
Some related sequential files, however, are unequal and you do not want to merge them. For example,
you might have a file containing records for all your customers, in which each record holds a customer ID
number, name, address, and balance due. You might have another file that contains data for every
purchase made, containing the customer ID number and other purchase information such as a dollar
amount. Although both files contain a customer ID number, the file with the customer names and
addresses is an example of a master file. You use a master file to hold relatively permanent data, such as
customers’ names. The file containing customer purchases is a transaction file, a file that holds more
temporary data generated by the actions of the customers. You may maintain certain customers’ names
and addresses for years, but the transaction file will contain new data daily, weekly, or monthly, depending
on your organization’s billing cycle. Commonly, you periodically use a transaction file to find a matching
record in a master file—one that contains data about the same customer. Sometimes, you match records
so you can update the master file by making changes to the values in its fields. For example, the file
containing transaction purchase data might be used to update each master file record’s balance due
field. At other times, you might match a transaction file’s records to its master file counterpart, creating
245
an entity that draws information from both files—an invoice, for example. This type of program requires
matching, but no updating. Whether a program simply matches records in master and transaction files, or
updates the master file, depending on the application, there might be none, one, or many transaction
records corresponding to each master file record.
Here are a few other examples of files that have a master-transaction relationship:
A library maintains a master file of all patrons and a transaction file with information about each
book or other items checked out.
A college maintains a master file of all students and a transaction file for each course
registration.
A telephone company maintains a master file for every telephone line (number) and a
transaction file with information about every call.
When you update a master file, you can take two approaches:
You can actually change the information in the master file. When you use this approach, the
information that existed in the master file prior to the transaction processing is lost.
You can create a copy of the master file, making the changes in the new version. Then, you can
store the previous version of the master file for a period of time, in case there are questions or
discrepancies regarding the update process. The saved version of a master file is the parent file;
the updated version is the child file. This approach is used later in this chapter.
The logic you use to perform a match between master and transaction file records is similar to the logic
you use to perform a merge. As with a merge, you must begin with both files sorted in the same order on
the same field.
Assume you have a master file with the fields shown in Figure 9-9.
The custTotalSales field holds the total dollar amount of all purchases the customer has made
previously; in other words, it holds the total amount the customer has spent prior to the current week. At
the end of each week, you want to update this field with any new sales transaction that occurred during
the week. Assume a transaction file contains one record for every transaction that has occurred and that
each record holds a transaction number, the number of the customer who made the transaction, the
transaction date, and the amount of the transaction. The fields in the transaction file are shown in Figure
9-10.
246
FIGURE 9-10: TRANSACTION FILE DESCRIPTION
You want to create a new master file in which almost all information is the same as in the original file, but
the custTotalSales field increases to reflect the most recent transaction. The process involves going
through the old master file, one record at a time, and determining whether there is a new transaction for
that customer. If there is no transaction for a customer, the new customer record will contain exactly the
same information as the old customer record. However, if there is a transaction for a customer, the
transAmount value adds to the custTotalSales field before you write the updated master file record to
output. Imagine you were going to update master file records by hand instead of using a computer
program, and imagine each master and transaction record was stored on a separate piece of paper. The
easiest way to accomplish the update would be to sort all the master records by customer number and
place them in a stack, and then sort all the transactions by customer number (not transaction number)
and place them in another stack. You then would examine the first transaction, and look through the
master records until you found a match. You would then correct the matching master record and examine
the next transaction. The computer program you write to perform the update works exactly the same way.
The mainline logic (see Figure 9-11) and housekeeping() module (see Figure 9-12) for this matching
program look similar to their counterparts in a file-merging program. Two records are read, one from the
master file and one from the transaction file. When you encounter eof for either file, store a high value
(999) in the customer number field. Using the readCust() and readTrans() modules moves the reading of
files and checking for eof off into their individual modules, as shown in Figure 9-13.
247
FIGURE 9-12: THE housekeeping() MODULE FOR THE FILE-MATCHING PROGRAM.
248
FIGURE 9-13: THE readTrans() AND readCust() MODULES FOR THE FILE-MATCHING PROGRAM
In the file-merging program, your first action in the mainline mergeFiles() module was to determine which
file held the record with the lower value; then, you wrote that file to output. In a main module within a
matching program, you need to determine more than whether one file’s comparison field is larger than
another’s; it’s also important to know if they are equal. In this example, you want to update the master
file record’s custTotalSales field only if the transaction record transCustNumber field contains an
exact match for the customer number in the master file record. Therefore, in the file- matching module
(called matchFiles() in this example), you compare custNumber from custRec and transCustNumber from
transRec. Three possibilities exist:
249
When you compare records from the two input files, if custNumber and transCustNumber are equal, you
add transAmount to custTotalSales, and then write the updated master record to the output file. Then,
you read in both a new master record and a new transaction record.
If transCustNumber is higher than custNumber, there wasn’t a sale for that customer. That’s all right; not
every customer makes a transaction every period. If transCustNumber is higher than custNumber when
you compare records, you simply write the original customer record to output with exactly the same
information it contained when input; then, you get the next customer record to see if this customer
made the transaction currently under examination.
Finally, when you compare records from the master and transaction files, if transCustNumber is lower than
custNumber in the master file, you are trying to record a transaction for which no master record exists.
That means there must be an error, because a transaction should always have a master record. You can
handle this error in a variety of ways; here, you will write an error message to an output device before
reading the next transaction record. A human operator can then read the message and take appropriate
action.
Whether transCustNumber was higher than, lower than, or equal to custNumber, at the bottom of the
matchFiles() module you check whether both custNumber and transCustNumber are 999; when they are,
you set the bothAtEof flag to “Y”.
Figure 9-14 shows some sample data you can use to walk through the logic for this program, and Figure 9-
15 shows the pseudocode and flowchart.
250
FIGURE 9-15: THE matchFiles() MODULE LOGIC FOR THE FILE-MATCHING PROGRAM
1. Read customer 100 from the master file and customer 100 from the transaction file. Customer
numbers are equal, so 400.00 from the transaction file is added to 1000.00 in the master file, and a new
master file record is written with a 1400.00 total sales figure. Then, read a new record from each input file.
2. The customer number in the master file is 102 and the customer number in the transaction file is
105, so there are no transactions today for customer 102. Write the master record exactly the way it came
in, and read a new master record.
251
3. Now, the master customer number is 103 and the transaction customer number is still 105. This
means customer 103 has no transactions, so you write the master record as is and read a new one.
4. Now, the master customer number is 105 and the transaction number is 105. Because customer 105
had a 75.00 balance and now has a 700.00 transaction, the new total sales figure is 775.00, and a new
master record is written. Read one record from each file.
5. Now, the master number is 106 and the transaction number is 108. Write customer record 106 as is,
and read another master.
6. Now, the master number is 109 and the transaction number is 108. An error has occurred. The
transaction record indicates that you made a sale to customer 108, but there is no master record for
customer number 108. Either there is an error in the transaction’s customer number or the transaction is
correct but you have failed to create a master record. Either way, write an error message so th at a clerk
is notified and can handle the problem. Then, get a new transaction record.
7. Now, the master number is 109 and the transaction number is 110. Write master record 109 with no
changes and read a new one.
8. Now, the master number is 110 and the transaction number is 110. Add the 400.00 transaction to
the previous 500.00 figure, and write a new record with a 900.00 value in the custTotalSales field. Read
one record from each file.
9. Because both files are finished, end the job. The result is a new master file in which some records
contain exactly the same data they contained going in, but others (for which a transaction has occurred)
have been updated with a new total sales figure.
In the last example, the logic provided for, at most, one transaction record per master customer record.
You would use very similar logic if you wanted to allow multiple transactions for a single customer. Figure
9-16 shows the new logic. A small but important difference exists between logic that allows multiple
transactions and logic that allows only a single transaction per master file record. If a customer can have
multiple transactions, whenever a transaction matches a customer, you add the transaction amount to the
master total sales field. Then, you read only from the transaction file. After you exit mainLoop() and reenter
it, the next transaction might also pertain to the same master customer. (Compare the first “Yes” branch
in Figure 9-16 with the one in Figure 9-15; the readCust()module is removed in Figure 9-16.) Only when a
transaction number is greater than a master file customer number do you write the customer master
record.
252
FIGURE 9-16: THE matchFiles() LOGIC ALLOWING MULTIPLE TRANSACTIONS FOR EACH MASTER FILE
RECORD
In the example in the preceding section, you needed to update a field in some of the records in a master
file with new data. A more sophisticated update program allows you not only to make changes to data in
a master file record, but also to update a master file either by adding new records or by eliminating the
ones you no longer want.
Assume you have a master employee file, as shown on the left side of Figure 9-17. Sometimes, a new
employee is hired and a record must be added to this file, or an employee quits and the employee’s record
must be removed from the file. Sometimes, you need to change an employee record by recording
a raise in salary, for example, or a change of department.
For this kind of update program, it’s common to have a transaction file in which each record contains all
the same fields as the master file records do, with one exception. The transaction file has one extra field
253
to indicate whether this transaction is meant to be an addition, a deletion, or a change—for example, a
one-letter code of “A”, “D”, or “C”. Figure 9-17 shows the master and transaction file layouts.
FIGURE 9-17: MASTER AND TRANSACTION FILES FOR THE UPDATE PROGRAM
The master file records contain data in each of the fields shown in Figure 9-17—an employee number,
name, salary, and department number. The three types of transaction records stored in the transaction
file would differ as follows:
An addition record in a transaction file actually represents a new master file record. An addition
record would contain data in each of the fields—the employee number, name, salary, and
department; because an addition record represents a new employee, data for all the fields must be
captured for the first time. Also, in this example, such a record contains an “A” for “Addition” in the
transaction code field.
A deletion record in a transaction file flags a master file record that should be removed from the file.
In this example, a deletion record really needs data in only two fields—a “D” for “Deletion” in the
transaction code field and a number in the employee number field. If a “D” transaction record’s
employee number matches an employee number on a master record, then you have identified a
record you want to delete. You do not need data indicating the salary, department, or anything else
for a record you are deleting.
A change record indicates an alteration that should be made to a master file record. In this case, it
contains a “C” code for “Change” and needs data only in the employee number field and any fields
that are going to be changed. In other words, if an employee’s salary is not changing, the salary
field in the transaction record will be blank; but if the employee is transferring to Department 28,
then the department field of the transaction record will hold a 28.
The mainline logic for an update program is very similar to the merging and matching programs shown in
Figures 9-3 and 9-11, respectively. After housekeeping() and before finishUp(), the module that does the
real work of the program executes repeatedly. Within the housekeeping() module, you declare the
variables, open the files, and read the first record from each file. You can use the readEmp() and
readTrans() modules to set the key fields empNum and transEmpNum to high values at eof. See Figures 9-
18, 9-19, and 9-20.
254
FIGURE 9-18: THE MAINLINE LOGIC FOR THE UPDATE PROGRAM
255
FIGURE 9-19: THE housekeeping() MODULE FOR THE UPDATE PROGRAM
FIGURE 9-20: THE readEmp() AND readTrans() MODULES FOR THE UPDATE PROGRAM
The updateMaster() module of the update program begins like the matchFiles() module in the matching
program. You need to know whether empNum in the master file and transEmpNum in the transaction file
are equal, or, if not, then you need to know which value is higher. To keep the updateMaster() module
simple, you can create modules for each of the three possible scenarios: theyAreEqual(),
empIsLargerThanTrans(), and transIsLargerThanEmp(). (Of course, you might choose shorter module
names; the long names used here are intended to help you remember what condition preceded the
execution of each module.) At the end of the updateMaster() module, after one of the three
submodules has finished, you can set the bothAtEof flag variable to “Y” if both files have completed. Figure
9-21 shows the updateMaster() module.
256
FIGURE 9-21: THE updateMaster() MODULE OF THE UPDATE PROGRAM
You perform the theyAreEqual() module only if a record in the master file and a record in the
transaction file contain the same employee number. This should be the situation when a change is made
to a record (for example, a change in salary) or when a record is to be deleted. If the master file and the
transaction file records are equal, but the transCode value in the transaction record is an “A”, then an error
has occurred. You should not attempt to add a full employee record when the employee already exists in
the master file.
As shown in Figure 9-22, within the theyAreEqual() module, you check transCode and perform one of three
actions:
If the code is an “A”, print an error message. But what is the error? (Is the code wrong? Was this
meant to be a change or a deletion of an existing employee? Is the employee number wrong— was
this meant to be the addition of some new employee?) Because you’re not completely sure, you
can only print an error message to let an employee know that an error has occurred; then, the
employee can handle the error. You should also write the existing master record to output exactly
the same way it came in, without making any changes.
If the code is a “C”, you need to make changes. You must check each field in the transaction record.
If any field is blank, the data in the new master record should come from the old master record. If,
however, a field in the transaction record contains data, this data is intended to constitute a
change, and the corresponding field in the new master record should be created from the
transaction record. Then, for each changed field, you replace the contents of the old field in the
257
master file with the new value in the corresponding field in the transaction file, and then write the
master file record.
If the code is not an “A” or a “C”, it must be a “D” and the record should be deleted. How do you
delete a record from a new master file? Just don’t write it out to the new master file! In other
words, as Figure 9-22 shows, no action is necessary when a record is deleted.
Finally, at the end of the theyAreEqual() module, after the appropriate action has been taken with the
matching master and transaction file records, you read one new record from each of the two input files.
Suppose that within the updateMaster() module in Figure 9-21, the master file record and the
transaction file record do not match. If the master file record has a higher number than the transaction
file record, this means you have read a transaction record for which there is no master file record, so you
execute the empIsLargerThanTrans() module. See Figure 9-23.
258
FIGURE 9-23: THE empIsLargerThanTrans() MODULE
Within the empIsLargerThanTrans() module, if the transaction record contains code “A”, that’s fine
because an addition transaction shouldn’t have a master record. The transaction record data simply
become the data for the new master record, so each of its fields is written to the new output file.
However, if the transaction code is “C” or “D” in the empIsLargerThanTrans() module, an error has
occurred. Either you are attempting to make a change to a record that does not exist or you are attempting
to delete a record that does not exist. Either way, a mistake has been made, and you must print an error
message.
At the end of the empIsLargerThanTrans() module, you should not read another master file record. After
all, there could be several more transactions that represent new additions to the master file. You want to
keep reading transactions until a transaction matches or is greater than a master record. Therefore, only
a transaction record should be read.
The final possibility in the updateMaster() module in Figure 9-21 is that a master file record’s empNum
field is smaller than the transaction file record’s transEmpNum field in memory. If there is no transaction
for a given master file record, it just means that the master file record has no changes or deletions;
259
therefore, when you perform the transIsLargerThanEmp() module, you simply write the new master record
out exactly like the old master record and read another master record. See Figure 9-24.
At some point, one of the files will reach eof. If the transaction file reaches the end first, transEmpNum is
set to 999 in the readTrans() module. Each time the updateMaster() module is entered after
transEmpNumis set to 999, empNum will be lower than transEmpNum and the transIsLargerThanEmp()
module will execute. That module writes records from the master file without alteration, and this is exactly
what you want to happen. Obviously, there were no transactions for these final records in the master file,
because all the records in the transaction file were used to apply to earlier master file records.
On the other hand, if the master file reaches its end first, empNum is set to 999 in the readEmp() module.
Now, each time the program enters the updateMaster() module, transEmpNum will be lower than
empNum. The empIsLargerThanTrans() module will execute for all remaining transaction records. In turn,
each remaining transaction will be compared to the possible code values. If any remaining transaction
records are additions, they will write to the new master as new records. However, if the remaining
transaction records represent changes or deletions, a mistake has been made, because there are no
corresponding master file records. In other words, error messages will then be printed for the remaining
change and deletion transaction records as they go through the updateMaster() process.
Whichever file reaches the end first, the other continues to be read and processed. When that file reaches
eof, the bothAtEof flag will finally be set to “Y”. Then, you can perform the finishUp() module, as shown
with the complete program in Figure 9-25.
Merging files, matching files, and updating a master file from a transaction file require a significant number
of steps, because as you read each new input record you must account for many possible scenarios.
Planning the logic for programs like these takes a fair amount of time, but by planning the logic carefully,
you can create programs that perform valuable work for years to come. Separating the various outcomes
into manageable modules keeps the program organized and allows you to develop the logic one step at a
time.
260
FIGURE 9-25: COMPLETE PROGRAM THAT UPDATES MASTER FILE USING TRANSACTION RECORDS THAT
CONTAIN ADD, CHANGE, OR DELETE CODES
CHAPTER SUMMARY
A sequential file is a file whose records are stored one after another in some order. The field on which
you sort records is the key field. Merging files involves combining two or more files while
maintaining the sequential order. Each file used in a merge must be sorted in the same order in the
same field as the others.
The mainline logic for a program that merges two files contains a housekeeping module, a module
that matches files and repeats until the end of the program, and a final module that performs
finishing tasks. The mainline logic checks a flag variable that is turned on when both input files are
finished.
When beginning the repeating module that merges files in a merge program, you compare records
from each input file. You write the appropriate record from one of the files to output, and then
read a record from the same file. When you encounter eof on one of the two input files, set the
field on which the merge is based to a high value.
You use a master file to hold relatively permanent data, and a transaction file to hold more temporary
data that corresponds to records in the master file. When you update a master file, you can take
two approaches: you can actually change the information in the master file, or you can create a
copy of the master file, making the changes in the new version.
The logic you use to perform a match between master and transaction file records involves comparing
the files to determine whether there is a transaction for each master record; when there is, you
update the master record. When a master record has no transaction, you write the master record
as is; when a transaction record has no corresponding master, you have an error.
261
Using the logic that allows multiple transactions per master file record, whenever a transaction
matches a master file record, you process the transaction and then you read only from the
transaction file. Only when a transaction file key field is greater than a master file key field do you
write the master record.
A sophisticated update program allows you to make changes to data in a record and update a master
file by adding new records or eliminating records you no longer want. For this kind of program, it’s
common to have a transaction file in which each record contains all the same fields as the master
file, with an additional code that indicates the type of transaction.
KEY TERMS
A sequential file is a file in which records are stored one after another in some order.
Records that are stored in temporal order are stored in order based on their creation time.
Merging files involves combining two or more files while maintaining the sequential order.
A data file contains only data for another computer program to read, not headings or other
formatting.
A high value is one that is greater than any possible value in a field.
You use a master file to hold relatively permanent data.
A transaction file holds more temporary data generated by the entities represented in the
master file.
A matching record is a transaction file record that contains data about the same entity in a master
file record.
To update a master file means to make changes to the values in its fields based on transaction
records.
The saved version of a master file is the parent file; the updated version is the child file.
An addition record in a transaction file is one that represents a new master record.
A deletion record in a transaction file flags a record that should be removed from a master file.
A change record in a transaction file indicates an alteration that should be made to a master file
record.
REVIEW QUESTIONS
1. A file in which records are stored one after another in some order is a(n)
file. a. temporal
b. sequential
c. random
d. alphabetical
2. When you combine two or more sorted files while maintaining their sequential order based on a field,
you are the files. a. tracking
b. collating
c. merging
d. absorbing
262
3. When you write a program that combines two sorted files into one larger, sorted file, you must create
an additional work variable whose purpose is to . a. count the files
b. count the records
c. flag when both files encounter eof
d. flag when two records in the files contain identical data
4. Unlike when you print a report, when a program’s output is a data file, you do not .
a. include headings or other formatting
b. open the files
c. include all the fields represented as input
d. all of the above
5. In a program that merges two sorted files, the first task in the main mergeFiles() module is to .
a. read a record from each input file
b. compare the values of the fields on which the files are sorted
c. output the record with the lower value in the field on which the files are sorted
d. output the record with the higher value in the field on which the files are sorted
6. Assume you are writing a program to merge two files named FallStudents and SpringStudents. Each
file contains a list of students enrolled in a programming logic course during the semester indicated, and
each file is sorted in student ID number order. After the program compares two records and
subsequently writes a Fall student to output, the next step is to . a. read a SpringStudents record
b. read a FallStudents record
c. write a SpringStudents record
d. write another FallStudents record
7. A value that is greater than any possible legal value in a field is called a(n) value. a.
great
b. illegal
c. merging
d. high
8. When you merge records from two or more sequential files, the usual case is that the records in the
files .
a. contain the same data
b. have the same format
c. are identical in number
d. are sorted on different fields
9. A file that holds more permanent data than a transaction file is a file. a.
master
b. primary
c. key
d. mega-
11. The saved version of a file that does not contain the most recently applied transactions is known as
a file. a. master
b. child
c. parent
d. relative
12. Ambrose Bierce High School maintains a master file containing records for each student in a class.
Each record contains fields such as student ID, student name, home phone number, and grade on each
exam. A transaction file is created after each exam; it contains records that each hold a test number, a
student ID, and the student’s grade on the exam. You would write a matching program to match the
records in the field. a. student ID
b. student name
c. test number
d. grade on the exam
13. Larry’s Service Station maintains a master file containing records for each vehicle Larry services. Each
record contains fields such as vehicle ID, owner name, date of last oil change, date of last tire rotation,
and so on. A transaction file is created each day; it contains records that hold a vehicle ID and the name
of the service performed. When Larry performs a match between these two files so that the most recent
date can be inserted into the master file, which of the following should cause an error condition?
a. A specific vehicle is represented in each file.
b. A specific vehicle is represented in the master file, but not in the transaction file.
c. A specific vehicle is represented in the transaction file, but not in the master file.
d. A specific vehicle is not represented in either file.
14. Sally’s Sandwich Shop maintains a master file containing records for each preferred customer. Each
record contains a customer ID, name, e-mail address, and number of sandwiches purchased. A
transaction file record is created each time a customer makes a purchase; the fields include customer ID
and number of sandwiches purchased as part of the current transaction. After a customer
surpasses 12 sandwiches, Sally e-mails the customer a coupon for a free sandwich. When Sally runs the
match program with these two files so that the master file can be updated with the most recent
purchases, which of the following should indicate an error condition? a. master ID is greater than
transaction ID
b. master ID is equal to transaction ID
c. master ID is less than transaction ID
d. none of the above
18. In a program that updates a master file, if a transaction record indicates a change, then it is an error
when the transaction record’s matching field is the field in a master file’s record. a. greater than
b. less than
c. both of these
d. neither a nor b
19. In a program that updates a master file, if a master and transaction file match, then it is an error if
the transaction record is a(n) record. a. addition
b. change
c. deletion
d. two of the above
20. In a program that updates a master file, if a master file’s comparison field is larger than a
transaction file’s comparison field, then it is an error if the transaction record is a(n) record. a.
addition
b. change
c. deletion
d. two of the above
The following pseudocode contains one or more bugs that you must find and correct.
1. Each time a salesperson sells a car at the Pardeeville New and Used Auto Dealership, a record is
created containing the salesperson’s name and the amount of the sale. Sales of new and used cars are
kept in separate files because several reports are created for one type of sale or the other. However,
management has requested a merged file so that all of a salesperson’s sales, whether the vehicle was
new or used, are displayed together. The following code is intended to merge the files that have already
been sorted by salesperson ID number. start
perform housekeeping()
endwhile
perform finish()
265
return
num newSalePrice
usedFile char
usedIdNumber
num usedSalePrice
char bothAtEof
open files read
newFile
if eof then
newIdNumber = 9999999
endif read
usedFile
if eof then usedIdNumber =
9999
endif
if newIdNumber = 9999999 then if
usedIdNumber = 9999999 then
bothAtEof = “Y”
endif endif
return
mergeModule() if newIdNumber =
usedIdNumber then write newIdNumber,
newSalePrice
read newFile
if eof then
newIdNumber = 9999999
else endif
finish()
close files return
EXERCISES
1. The Springwater Township School District has two high schools—Jefferson and Audubon. Each
school maintains a student file with fields containing student ID, last name, first name, and address. Each
file is in student ID number order. Write the flowchart or pseudocode for a program that merges the two
files into one file containing a list of all students in the district, maintaining student ID number order.
2. The Redgranite Library keeps a file of all books borrowed every month. Each file is in Library of
Congress number order and contains additional fields for author and title.
a. Write the flowchart or pseudocode for a program that merges the files for January and February to
create a list of all books borrowed in the two-month period.
b. Modify the program from Exercise 2a so that if there is more than one record for a book number,
you print the book information only once.
c. Modify the program from Exercise 2b so that if there is more than one record for a book number,
you not only print the book information only once, you print a count of the total number of times the book
was borrowed.
3. Hearthside Realtors keeps a transaction file for each salesperson in the office. Each transaction
record contains the salesperson’s first name, date of the sale, and sale price. The records for the year
are sorted in descending sale price order. Two salespeople, Diane and Mark, have formed a partnership.
Write the flowchart or pseudocode that produces a merged list of their transactions (including name of
salesperson, date, and price) in descending order by price.
4. Dartmoor Medical Associates maintains two patient files—one for the Lakewood office and one
for the Hanover office. Each record contains the name, address, city, state, and zip code of a patient,
with the file maintained in zip code order. Write the flowchart or pseudocode that merges the two files
to produce one master name and address file that the Dartmoor office staff can use for addressing the
practice’s monthly Healthy Lifestyles newsletter mailing in zip code order.
5. The Willmington Walking Club maintains a master file that contains a record for each of its
members. Fields in the master file include the walker’s ID number, first name, last name, and total miles
walked to the nearest one-tenth of a mile. Every week, a transaction file is produced; the transaction file
contains a walker’s ID number and the number of miles the walker has logged that week. Each file is
sorted in walker ID number order.
267
a. Create the flowchart or pseudocode for a program that matches the master and transaction file
records and updates the total miles walked for each club member by adding the current week’s miles to
the cumulative total for each walker. Not all walkers submit walking reports each week. The output is the
updated master file and an error report listing any transaction records for which no master record exists.
b. Modify the program in Exercise 5a to print a certificate of achievement each time a walker exceeds
the 500-mile mark. That is, the certificate—containing the walker’s name and an appropriate
congratulatory message—is printed during the run of the update program when a walker’s mile total
changes from a value below 500 to one that is 500 or greater.
6. The Timely Talent Temporary Help Agency maintains an employee master file that contains an
employee ID number, last name, first name, address, and hourly rate for each of the temporary
employees it sends out on assignments. The file has been sorted in employee ID number order. Each
week, a transaction file is created with a job number, address, customer name, employee ID, and hours
worked for every job filled by Timely Talent workers. The transaction file is also sorted in employee ID
order.
a. Create the flowchart or pseudocode for a program that matches the master and transaction file
records, and print one line for each transaction, indicating job number, employee ID number, hours
worked, hourly rate, and gross pay. Assume each temporary worker works at most one job per week; print
one line for each worker who has worked that week.
b. Modify Exercise 6a so that any individual temporary worker can work any number of separate jobs
in a week. Print one line for each job that week.
c. Modify Exercise 6b so that, although any worker can work any number of jobs in a week, you
accumulate the worker’s total pay for all jobs and print one line per worker.
7. Claypool College maintains a student master file that contains a student ID number, last name, first
name, address, total credit hours completed, and cumulative grade point average for each of the
students who attend the college. The file has been sorted in student ID number order. Each semester, a
transaction file is created with the student’s ID, the number of credits completed during the new
semester, and the grade point average for the new semester. The transaction file is also sorted in student
ID order.
Create the flowchart or pseudocode for a program that matches the master and transaction file records
and updates the total credit hours completed and the cumulative grade point average on a new master
record. Calculate the new grade point average as follows:
Multiply the credits in the master file by the grade point average in the master file, giving master
honor points—that is, honor points earned prior to any transaction. The honor points value is useful
because it is weighted—the value of the honor points is more for a student who has accumulated
100 credits with a 3.0 grade point average than it is for a student who has accumulated only 20
credits with a 3.0 grade point average.
Multiply the credits in the transaction file by the grade point average in the transaction file, giving
transaction honor points.
Add the two honor point values, giving total honor points.
Add master and transaction credit hours, giving total credit hours. Divide total
honor points by total credit hours, giving the new grade point average.
268
8. The Amelia Earhart High School basketball team maintains a record for each team player, including
player number, first and last name, minutes played during the season, baskets attempted, baskets made,
free throws attempted, free throws made, shooting average from the floor, and shooting average from
the free throw line. (Shooting average from the floor is calculated by dividing baskets made by baskets
attempted; free throw average is calculated by dividing free throws made by free throws attempted.)
The master records are maintained in player number order.
After each game, a transaction record is produced for any player who logged playing time. Fields in each
transaction record contain player number, minutes played during the game, baskets attempted, baskets
made, free throws attempted, and free throws made.
Design the flowchart or pseudocode for a program that updates the master file with the transaction file,
including recalculating shooting averages, if necessary.
9. The Tip-Top Talent Agency books bands for social functions. The agency maintains a master file in
which the records are stored in order by band code. The records have the following format:
The agency has asked you to write an update program, so that once a month the agency can make
changes to the file, using transaction records with the same format as the master records, plus one
additional field that holds a transaction code. The transaction code is “A” if the agency is adding a new
band to the file, “C” if it is changing some of the data in an existing record, and “D” if it is deleting a band
from the file.
An addition transaction record contains a band code, an “A” in the transaction code field, and the new
band’s data. During processing, an error can occur if you attempt to add a band code that already exists
in the file. This is not allowed, and an error message is printed.
A change transaction record contains a band code, a “C” in the transaction code field, and data for only
those fields that are changing. For example, a band that is raising its hourly rate from $75 to $100 would
contain empty fields for the band name, contact person information, and style of music, but the hourly
rate field would contain the new rate. During processing, an error can occur if you attempt to change
data for a band number that doesn’t exist in the master file; print an error message.
269
A deletion transaction record contains a band code, a “D” in the transaction code field, and no other
data. During processing, an error can occur if you attempt to delete a band number that doesn’t exist in
the master file; print an error message.
Two forms of output are created. One is the updated master file with all changes, additions, and
deletions. The other is a printed report of errors that occurred during processing. Rather than just a list
of error messages, each line of the printed output should list the appropriate band code along with the
corresponding message.
a. Design the print chart or create sample output for the error report.
b. Design the hierarchy chart for the program.
c. Create either a flowchart or pseudocode for the program.
10. Cozy Cottage Realty maintains a master file in which records are stored in order by listing number, in
the following format:
The realty company has asked you to write an update program so that, every day, the company can make
changes to the file, using transaction records with the same format as the master records, plus one
additional field that holds a transaction code. The transaction code is “A” to add a new listing, “C” to
change some of the data in an existing record, and “D” to delete a listing that is sold or no longer on the
market.
An addition transaction record contains a listing number, an “A” in the transaction code field, and the
new house listing’s data. During processing, an error can occur if you attempt to add a listing number
that already exists in the file. This is not allowed, and an error message is printed.
A change transaction record contains a listing number, a “C” in the transaction code field, and data for
only those fields that are changing. For example, a listing that is dropping in price from $139,900 to
$133,000 would contain empty fields for the address, bedrooms, and baths, but the price field would
contain the new list price. During processing, an error can occur if you attempt to change data for a
listing number that doesn’t exist in the master file; print an error message.
A deletion transaction record contains a listing code number, a “D” in the transaction code field, and no
other data. During processing, an error can occur if you attempt to delete a listing number that doesn’t
exist in the master file; print an error message.
Two forms of output are created. One is the updated master file with all changes, additions, and
deletions. The other is a printed report of errors that occurred during processing. Rather than just a list
270
of error messages, each line of the printed output should list the appropriate house listing number along
with the corresponding message.
a. Design the print chart or create sample output for the error report.
b. Design the hierarchy chart for the program.
c. Create either a flowchart or pseudocode for the program.
11. Crown Greeting Cards maintains a master file of its customers stored in order by customer
number, in the following format:
The card store has asked you to write an update program so that, every week, the store can make
changes to the file, using transaction records with the same format as the master records, plus one
additional field that holds a transaction code. The transaction code is “A” to add a new customer, “C” to
change some of the data in an existing record, and “D” to delete a customer. In a transaction record, the
amount field represents a new transaction instead of the total value of merchandise purchased.
An addition transaction record contains a customer number, an “A” in the transaction code field, and
the new customer’s name, address, phone number, and first purchase amount. During processing, an
error can occur if you attempt to add a customer number that already exists in the file. This is not
allowed, and an error message is printed.
A change transaction record contains a customer number, a “C” in the transaction code field, and data
for only those fields that are changing. For example, a customer might have a new address or phone
number. In a change record, if a value appears in the merchandise value field, it represents an amount
that should be added to the total merchandise value in the master record. During processing, an error
can occur if you attempt to change data for a customer number that doesn’t exist in the master file; print
an error message.
A deletion transaction record contains a customer number, a “D” in the transaction code field, and no
other data. During processing, an error can occur if you attempt to delete a customer number that
doesn’t exist in the master file; print an error message.
Three forms of output are created. One is the updated master file with all changes, additions, and
deletions. The second output is a printed report of errors that occurred during processing. Rather than
just list error messages, each line of the printed output should list the appropriate customer number
along with the corresponding message. The third output is a report listing all customers who have
currently met or exceeded the $1,000 purchase threshold for the year.
271
a. Design the print chart or create sample output for the error report, along with the hierarchy chart
and either a flowchart or pseudocode for the program.
b. Modify the program in Exercise 11a so that the third output is not a report of all customers who have
met or exceeded the $1,000 purchase threshold this year, but a report listing all customers who have just
passed the $100 purchase threshold this week.
272