CS 210 – Fundamentals of Programming I  An Analysis and Design Style Guideline

advertisement
CS 210 – Fundamentals of Programming I An Analysis and Design Style Guideline
The purpose of the analysis and design is to outline a program before it is implemented. There are several reasons why this required. First, spending time writing out the analysis and design can greatly decrease the time it takes to implement a solution to a problem. The programmer is able to concentrate on what needs to be done to solve the problem rather than on the intricacies of the compiler or the syntax of the language of implementation. Second, often the person who designs the program is not the person who implements the program. As such, the analysis and design clearly documents what is needed to solve the problem without using code­specific jargon that the programmer may not be familiar with. In some cases, the implementation language is chosen after the analysis and design is completed.
For this course, the analysis and design phase functions primarily as specifications for assignments and documentation of the student's design efforts on assignments. As such, the instructor uses a formal notation when specifying programs, but the student is to embedded their analysis and design in the comments as shown.
An analysis describes the data objects needed to solve the problem. It includes a description of the object, its type, whether its movement relative to the function being defined, and its name in the program. The analysis corresponds to the variable and constant declarations of a program. The analysis also describes the interfaces (the types of the argument and returned objects) of the functions used in the program (called function prototypes in C++), as well as the variables and constants that must be declared within the function.
A design is the "outline" of the computational steps. It is often used synonymously with the term algorithm. There is a design for each function in a program as well as the main program itself. When implementing a function, the design corresponds to the executable statements needed to compute the result. The analysis and design format in this document is a shortened and modified version of the Object­Centered Design approach used in Adams, Leestma, and Nyhoff, C++: An Introduction to Computing, 2/e. Analysis for Main Programs and Functions
The main purpose of the analysis is to specify the objects that the program uses. Objects are data items that have values. They usually correspond to the nouns in the problem statement. For each object, we need to specify a description (what it is), its type (the class of values it might be), how its value is obtained or transmitted (its movement), and perhaps a name. Movement specifications include:
●
●
●
●
●
●
●
input ­ value obtained outside the program from the user or a file
output ­ value displayed to the user or written to a file
received ­ value passed into a function
passed back ­ value transmitted out of a function via an argument
returned ­ value transmitted out of a function via a return
local ­ value computed locally (i.e., no movement).
constant ­ value is a constant
01/15/2011
Page 1 of 9
D. Hwang
Objects may "move" in more than one way. For example, a function argument could be both received and passed back when a function both uses its passed in value and changes it for transmission back to the caller. Another example would be a function that outputs results that are passed into it. In this case, the result objects are both received and output.
There should an analysis for the main program, and each subprogram (function). Formally, analysis in in the form of a table. For the main program all objects are constant, input, output, or local even if the actual input or output happens in a function. Most constants should be listed in the main program analysis unless they are being defined in a library. For example, an analysis for a main program that computes the area of two circles given their radii might look like: Objects
Type
Movement
Name
Mathematical  (3.14159)
double
constant
PI
Radius of first circle
double
input
radius1
Radius of second circle
double
input
radius2
Area of first circle
double
output
area1
Area of second circle
double
output
area2
The corresponding implementation comments would look like:
/* Main program analysis
Objects
Type
Movement
Name
---------------------------------------------------------Mathematical p (3.14159) double
Constant
PI
Radius of first circle
double
Input
radius1
Radius of second circle double
Input
radius2
Area of first circle
double
Output
area1
Area of second circle
double
Output
area2
*/
#define PI 3.14159
int main ()
{
double radius1,
radius2,
area1,
area2;
...
}
/* Mathematical constant */
/*
/*
/*
/*
radius of first circle */
radius of second circle */
area of first circle
*/
area of second circle */
For a function analysis the order of the received arguments in the analysis is the order expected in the implementation. An analysis for the function that actually computes the area of a circle might look like: 01/15/2011
Page 2 of 9
D. Hwang
Objects
Type
Movement
Name
Radius of a circle
double
received
radius
Area of a circle
double
returned
area
The corresponding implementation comments would look like:
/* Main program analysis
Objects
Type
Movement
Name
---------------------------------------------------------Radius of circle
double
Received
radius
Area of circle
double
Returned
area
*/
double compute_circle_area (double radius)
{
double area; /* area of a circle */
...
}
Design for Main Programs and Functions
A design should list the main steps needed to solve the problem at hand. The steps should be numbered and the substeps should be subnumbered. Each step should be explained in the language of the problem. For the main function, this means that the steps are in the language of the original problem statement. For other functions, the steps are in the language of the subproblem being solved which is at a more detailed level than at the main program level. That is, we start describing how to compute the data item in question. But at the same time, if at this level, a step is better described abstractly rather than concretely, one would use a function to compute it and say so accordingly. The format for various design constructs are as follows: ●
Input from keyboard
/* 1. Get <list of objects> from user */
●
Input from a file
/* 2. Read in <list of objects> from the input file */
●
Output to screen /* 3. Display/print list of objects */
●
Output to a file /* 4. Write <list of objects> to the output file */
01/15/2011
Page 3 of 9
D. Hwang
●
Initialization
/* 5. Initialize/set object to initial value */
●
Computation
/* 6. Compute object [as expression] */
The explanation is optional depending on whether the computation is straightforward or not. Computation should be expressed in English or standard mathematical notation, not in programming language notation. In particular, the use of C operators like ++ or *= is not appropriate. Instead, these computations might be expressed as
/* 7. Increment object */
/* 8. Multiply object by some value */
●
Computation that will be done using a function should be indicated
/* 9. Compute object using a function */
●
Function return /* 10. Return object */
●
Branching selection. The condition and else bodies are subnumbered consecutively.
/* 11. Check for condition */
if (<condition code>)
/* 11.1 Do something */
<code to do something>
else
/* 11.2 Do something else */
<code to do something else>
Note the else portion is optional.
●
Multi­way branch selection ­ each branch is numbered consecutively.
/* 12. Check for condition1 */
if (<condition1 code>)
/* 12.1 Do something1 */
<code to do something1>
/* 13. Check for condition2 */
else if (condition2)
/* 13.1 Do something2 */
<code to do something2>
/* 14. Otherwise no conditions match */
else
/* 14.1 Do something else */
<code to do something else?
01/15/2011
Page 4 of 9
D. Hwang
●
Case selection ­ each case is subnumbered consecutively
/* 15. Select on expression */
switch (expression)
{
case case1value:
/* 15.1 Do case 1 */
<code for case 1>
case case2value:
/* 15.2 Do case 2 */
<code for case 2>
…
}
●
Counted repetition ­ header indicates loop control variable, starting value, stopping value, and step size (assumed to be 1 if omitted). Body is subnumbered. /* 16. For lcv from initial value to final value [by step size] */
for (lcv = <init value>; lcv <= <final value>; lcv++)
{
/* 16.1 Do something */
<code to do something>
}
Note that the construct implies that the loop control variable is automatically initialized and updated for each iteration. If the counting loop is being used to access elements of an indexed collection, the header indicates such and the loop control variable.
/* 17. For each element in arr indexed by lcv */
for (lcv = 0; lcv < num_elements; lcv++)
{
/* 17. Do something with arr[lcv] */
<code to do something with arr[lcv]>
}
●
Pre­test conditional repetition (including loop control variable initialization and update). Body is subnumbered. /* 18. Loop while condition is met */
lcv = <init value>
while (condition)
{
/* 18.1 Do something */
<code to do something>
...
.../* 18.n Update lcv */
<code to update lcv
}
01/15/2011
Page 5 of 9
D. Hwang
●
Post­test conditional repetition. Body is subnumbered /* 19. Repeat while condition is met */
do
{
/* 19.1 Do something */
...<code to do something>
} while (condition);
Example Analysis and Design for Simple Program Problem Statement The New Telephone Company has the following rate structure for long­distance calls:
The regular rate for a call is $0.40 per minute. Any call started at or after 6:00pm (1800 hours) but before 8:00am (0800 hours) is discounted 50 percent. ● Any call longer than 60 minutes receives a 15 percent discount on its cost (after any other discount is subtracted). ● All calls are subject to a 4 percent federal tax on their final cost. ●
●
Write a program that reads the start time for a call based on a 24­hour clock and the length of the call. The gross cost (before any discounts or tax) should be printed, followed by the net cost (after discounts are deducted and tax is added). For the purposes of this example, we will break this program up into two pieces, the main program and a function that computes the net cost of the phone call. Main Program Analysis Objects
Type
Movement
Name
regular call rate (.40)
double
constant
REGULAR_RATE
night discount (.50)
double
constant
NIGHT_DISCOUNT
length discount (.15)
double
constant
LENGTH_DISCOUNT
federal tax rate (.04)
double
constant
FEDERAL_TAX_RATE
start of night time (1800)
int
constant
NIGHT_START
end of night time (800)
int
constant
NIGHT_END
long call length (60)
int
constant
LONG_CALL_LENGTH
time of day the call started in military time
int
input
start_time
number of minutes the call lasted
int
input
call_length
cost of call before discounts and tax
double
output
gross_cost
cost of call after discounts and tax
double
output
net_cost
01/15/2011
Page 6 of 9
D. Hwang
Main Program Design 1.
2.
3.
4.
Get the start time and call length from the user
Compute gross cost
Compute net cost using a function
Display gross cost and net cost Function compute_net_cost Analysis We specified in the main program design that we would use a function to compute the net cost of a call. Here is a possible analysis of this function:
Objects
Type
Movement
Name
time call started
int
received
start
number of minutes the call lasted
int
received
length
gross cost of the call
double
received
gross
net cost of the call
double
returned
net
amount of tax
double
local
tax
Function compute_net_cost Design 1. Check for a night call
1.1. Compute net cost after applying the night discount
Otherwise
1.2. Net cost is the gross cost
2. Check for a long call
2.1. Compute net cost after subtracting the long call discount
3. Compute federal tax
4. Add the tax to the net cost
5. Return net cost
A complete program file with corresponding analysis and design comments might look like:
/* File: design.c
* Example program for A&D guideline
*/
/* Libraries */
#include <stdio.h>
/* scanf, printf */
/* Constant definitions */
#define REGULAR_RATE 0.40
#define NIGHT_DISCOUNT 0.50
#define LENGTH_DISCOUNT 0.15
#define FEDERAL_TAX_RATE 0.04
01/15/2011
/*
/*
/*
/*
Regular call rate
Discount for night calls
Discount for long calls
Federal tax rate
Page 7 of 9
*/
*/
*/
*/
D. Hwang
#define NIGHT_START 1800
#define NIGHT_END 800
#define LONG_CALL_LENGTH 60
/* Start of night rate, 6pm */
/* End of night rate, 8am
*/
/* Long calls are > 60 min. */
/* Function prototypes */
double compute_net_cost (int start, int length, double gross);
/* Main program analysis
Objects
Type
Movement
Name
---------------------------------------------------------Start time of call
int
Input
start_time
Length of call
int
Input
call_length
Gross cost of call
double
Output
gross_cost
Net cost of call
double
Output
net_cost
*/
int main ()
{
int start_time,
/* Time call started in military time
call_length;
/* Length of call in minutes
double gross_cost,
/* Cost of call before discounts
net_cost;
/* Cost of call after discounts & taxes
*/
*/
*/
*/
/* 1. Get start time and call length from user */
printf ("Enter the start time of your call in military format: ");
scanf ("%d", &start_time);
printf ("Enter the length of your call in minutes: ");
scanf ("%d", &call_length);
/* 2. Compute gross cost */
gross_cost = call_length * REGULAR_RATE;
/* 3. Compute net cost using a function */
net_cost = compute_net_cost (start_time, call_length, gross_cost);
/* 4. Display gross and net costs */
printf ("The gross cost of this call is $%.2lf.\n", gross_cost);
printf ("After discounts and taxes, the net cost of this call is $%.2lf.\n",
net_cost);
return 0;
}
/* Function: compute_net_cost
Objects
Type
Movement
Name
---------------------------------------------------------Start time of call
int
Received
start
Length of call
int
Received
length
Gross cost of call
double
Received
gross
Net cost of call
double
Returned
net
*/
double compute_net_cost (int start, int length, double gross)
{
double net, /* net cost for this call
*/
tax; /* federal taxes for this call */
01/15/2011
Page 8 of 9
D. Hwang
/* 1. Check if the call is at night */
if ((start >= NIGHT_START) || (start < NIGHT_END))
/* 1.1 Apply the night discount */
net = gross * NIGHT_DISCOUNT;
else
/* 1.2 Otherwise, net is same as gross */
net = gross;
/* 2. Check if call is long */
if (length >= LONG_CALL_LENGTH)
/* 2.1 Deduct long call discount */
net = net - (net * LENGTH_DISCOUNT);
/* 3. Compute federal tax */
tax = net * FEDERAL_TAX_RATE;
/* 4. Add federal tax to the net cost */
net = net + tax;
/* 5. Return net cost */
return net;
}
01/15/2011
Page 9 of 9
D. Hwang
Download