220 likes | 323 Views
Specification Clearly state the purpose of the software, including full details of the problem being solved. Maintenance Respond to “bugs” and “sugs”, and determine when the system has become obsolete. Design
E N D
Specification Clearly state the purpose of the software, including full details of the problem being solved. Maintenance Respond to “bugs” and “sugs”, and determine when the system has become obsolete. Design Develop a solution to the problem, modularizing it and determining specific pre- and post-conditions. Production Distribute, install and use the system. Risk Analysis Determine the risks associated with the project, e.g., time, health, ethics, economics, and training. DOCUMENTATION!!! Refinement Improve the algorithms used in the solution and eliminate any unrealistic simplifying assumptions. Verification Prove the validity of the solution’s algorithms, using such tools as loop invariants. Testing Design test scenarios for individual modules, interaction between modules, and the entire system. Coding Program the modules using a bottom-up approach (with dummy drivers) or a top-down approach (with stubs). The Software System Life Cycle CS 150
For example, this input: should produce this output: and this legend: Moe total: 1659 Larry total: 2108 Curly total: 6797 Shemp total: 1840 : \\\:::: \\\\::::: O\\\\::::## OOO\\:::### OOOO\::#### OOOOOO:###### OOOOOOOO### OOOOOOOOOOO OOOOOOOOOOO OOOOOOOOO OOOOOOO O : - Moe: 13.375% # - Larry: 16.995% O - Curly: 54.797% \ - Shemp: 14.834% Specification Example • Produce a program which will: • Request four values from the user, representing the popularity of the four stooges (Moe, Larry, Curly, and Shemp), based upon a recent survey. • Compute the percentage popularity for each stooge. • Display the result in a pie chart composed of ASCII characters, with a different character used for each stooge. • Display a character legend indicating which character is associated with which stooge. CS 150
main Module Supervises user input, percentage calculations, and output of pie chart and symbol legend. Precondition: None. Postcondition: Execution window contains pie chart of user-specified values, as well as legend. queryUser Module Asks user for popularity survey results for the four stooges. Precondition: Integer parameters containing survey totals for Moe, Larry, Curly, Shemp, and all stooges are uninitialized. Postcondition: Moe, Larry, Curly, and Shemp totals have user-specified values; total for all stooges contains four-stooge total. calculate Module Calculates the popularity percentage and pie-chart angle for a designated stooge. Precondition: Integer parameter containing survey total for one stooge is initialized; double parameters for the stooge’s percentage and angle are uninitialized. Postcondition: Double parameters for the stooge’s percentage and angle are calculated. outputPie Module Outputs the pie chart for the four stooges’ survey results. Precondition: Double parameters for each stooge’s percentage and angle are initialized. Postcondition: The execution window contains a pie chart of the survey results. outputLegend Module Outputs the legend of ASCII characters used for each stooge in the pie chart. Precondition: Double parameter for each stooge’s percentage is initialized. Postcondition: The execution window contains a legend of the characters used for each stooge, and each stooge’s percentage. Design Example CS 150
Risk Analysis Example • Ethical Risks • Displaying these survey results might be considered an invasion of privacy by one or more of the stooges. • No information about the validity of the survey results is being provided. • Time Risks • Having an interactive session instead of just reading the survey data from a file might delay the production of the pie chart. • Economic Risks • Having an interactive session instead of just reading the survey from a file might waste the user’s time. • To adequately present the pie chart and legend information, more expensive display equipment might be necessary. • Training users to correctly input the survey data, and to correctly interpret the output results, could prove expensive. • Health Risks • Moe might poke the software development team in the eyes if he doesn’t like the survey results. • Curly might mistake the pie chart for a real pie and tossing the computer monitor into someone’s face. • More seriously, the choice of ASCII characters used in the pie chart might create headache-inducing patterns. CS 150
Verification Example • Calculating Popularity Percentages • Convert survey total for specified stooge into a double value. • Divide stooge’s total by the total number of people surveyed. • The result is the fraction of people surveyed who prefer the specified stooge. • To obtain actual percentage, this value must be multiplied by 100. • Calculating Pie-Chart Angles • Preset an “angle-so-far” value to zero; it represents the amount of the circular pie which has already been traversed (i.e., the angle at which the current stooge’s pie wedge begins). • Add the product of 2. and the specified stooge’s popularity percentage to obtain the angle at which the current stooge’s pie wedge ends. • Reset the “angle-so-far” to the newly computed value, in preparation for the the next stooge’s calculation. • All angles are measured in radians to facilitate the use of the angle operations defined in math.h. • Determining Stooge Character at Position (x,y) • The pie chart is being mapped to a square grid of ASCII characters, indexed from -MAXRADIUS to +MAXRADIUS (for some hard-coded value of MAXRADIUS, the radius of the circular pie chart). • For each (x,y) position, compute the pie-chart angle of this position by using arctan(x/y). • Angles between zero and Moe’s maximum angle will cause the position to be filled with Moe’s ASCII character; angles between Moe’s maximum and Larry’s maximum will result in the Larry character; angles between Larry’s maximum and Curly’s maximum will result in the Curly character; and angles greater than Curly’s maximum will result in Shemp’s character. CS 150
Coding Example ////////////////////////////////////////////////////////////////////////////////// // This program requests four values from the user, representing survey results // // from a poll which was taken to determine people's favorite Three Stooges // // character: Moe, Larry, Curly, or Shemp. Percentages are computed and the // // results are displayed in a pie chart composed entirely of characters. // ////////////////////////////////////////////////////////////////////////////////// #include <iostream> #include <iomanip> #include <cmath> using namespace std; void queryUser(int total[], int &stgTot); void calculate(int tot, int stgTot, double &pct, double &ang); void outputPie(double angle[]); void outputLegend(double percent[]); const int MAXRADIUS = 6; // Pie chart radius (in characters) const double PI = 3.141592653589793; // Extremely precise approximation const char MOECHAR = ':', // Pie chart character for Moe LARRYCHAR = '#', // " " " " Larry CURLYCHAR = 'O', // " " " " Curly SHEMPCHAR = '\\'; // " " " " Shemp CS 150
Coding Example (Continued) void main() { int surveyTotal[4]; // The survey results for the four stooges, indicating // how many respondents selected each character as // their favorite stooge; #0 is Moe, #1 is Larry, // #2 is Curly, #3 is Shemp. int stoogeTotal; // The total number of survey respondents (i.e., the // sum of the four surveyTotal values). double surveyPercent[4]; // The percentage of the survey results allocated to // each stooge; #0 is Moe, #1 is Larry, #2 is Curly, // #3 is Shemp. double surveyAngle[4]; // The angle (in radians) encompassed by each section // of the pie chart. Thus, Moe's section goes from 0 // to surveyAngle[0], Larry's from surveyAngle[0] to // surveyAngle[1], etc. int i; // Loop iteration variable. queryUser(surveyTotal, stoogeTotal); for (i = 0; i <= 3; i++) calculate(surveyTotal[i], stoogeTotal, surveyPercent[i], surveyAngle[i]); outputPie(surveyAngle); outputLegend(surveyPercent); return; } CS 150
Coding Example (Continued) //////////////////////////////////////////////////////////////////////////// // Query the user for the survey results, compute percentages and angles. // //////////////////////////////////////////////////////////////////////////// void queryUser(int total[], int &stgTot) { int i; // Loop iteration variable. cout << "How many people surveyed chose Moe as their favorite Stooge? "; cin >> total[0]; cout << "How many people surveyed chose Larry as their favorite Stooge? "; cin >> total[1]; cout << "How many people surveyed chose Curly as their favorite Stooge? "; cin >> total[2]; cout << "How many people surveyed chose Shemp as their favorite Stooge? "; cin >> total[3]; stgTot = 0; for (i = 0; i <= 3; i++) stgTot += total[i]; return; } CS 150
Coding Example (Continued) ////////////////////////////////////////////////////////////////////////// // Calculate the popularity percentage and maximum pie-chart angle for // // the designated stooge, using a running tally of the pie-chart angle // // that has already been traversed by previous stooge calculations. // ////////////////////////////////////////////////////////////////////////// void calculate(int tot, int stgTot, double &pct, double &ang) { static double angleSoFar = 0.0; // This static variable tallies the // total of all of the angles for // the previously computed stooges. pct = double(tot) / stgTot; ang = angleSoFar + 2 * PI * pct; angleSoFar = ang; return; } CS 150
Coding Example (Continued) ////////////////////////////////////////////////////////////////////////// // Cycle point by point through the character positions. For any char- // // acter within the pie chart's boundaries, determine which stooge's // // pie wedge it lies within, and insert the appropriate character. // ////////////////////////////////////////////////////////////////////////// void outputPie(double angle[]) { int x, // The horizontal and vertical coordinates y; // of the pie chart point being considered. double distanceFromCenter; // The distance (in characters) from the // pie chart's center to the point which // is currently being considered. double currentAngle; // The angle (in radians) formed by the three // points: the point at the top of the pie // chart, the center of the pie chart, and the // point which is currently being considered. CS 150
Coding Example (Continued) cout << endl; for (y = MAXRADIUS; y >= -MAXRADIUS; y--) { cout << '\t'; for (x = -MAXRADIUS; x <= MAXRADIUS; x++) { distanceFromCenter = sqrt(x * x + y * y); if (distanceFromCenter > MAXRADIUS) cout << ' '; else { currentAngle = atan2(x, y); // Library function atan2 returns arctan if (currentAngle < 0) // of x/y (adjusting if y=0); 2*PI may be currentAngle += 2 * PI; // added to yield angles betw 0 and 2*PI. if (currentAngle <= angle[0]) cout << MOECHAR; else if (currentAngle <= angle[1]) cout << LARRYCHAR; else if (currentAngle <= angle[2]) cout << CURLYCHAR; else cout << SHEMPCHAR; } } cout << endl; } return; } CS 150
Coding Example (Continued) ////////////////////////////////////////////////////////////// // A small legend is added below the pie chart to indicate // // which character is associated with which of the stooges. // ////////////////////////////////////////////////////////////// void outputLegend(double percent[]) { cout.setf(ios::fixed); cout << setprecision(3); cout << "\t\t\t\t" << MOECHAR << " - Moe: " << (percent[0] * 100) << "%\n"; cout << "\t\t\t\t" << LARRYCHAR << " - Larry: " << (percent[1] * 100) << "%\n"; cout << "\t\t\t\t" << CURLYCHAR << " - Curly: " << (percent[2] * 100) << "%\n"; cout << "\t\t\t\t" << SHEMPCHAR << " - Shemp: " << (percent[3] * 100) << "%\n"; cout << endl; return; } CS 150
Testing Example CS 150
Refinement Example REFINEMENT: Since displayed characters are 50% taller than they are wide, change output algorithm to print 50% more characters on each line, making pie chart look more circular. for (y = MAXRADIUS; y >= -MAXRADIUS; y--) { cout << '\t'; for (x = int(-1.5*MAXRADIUS); x <= int(1.5*MAXRADIUS); x++) { distanceFromCenter = sqrt((2.0*x/3.0) * (2.0*x/3.0) + y * y); if (distanceFromCenter > MAXRADIUS) cout << ' '; else { currentAngle = atan2(2.0*x/3.0, y); // atan2 returns arctan of 2x/3y if (currentAngle < 0) // (adjusting if y=0); 2*PI may be currentAngle += 2 * PI; // added to yield angles in [0,2*PI]. if (currentAngle <= angle[0]) cout << MOECHAR; else if (currentAngle <= angle[1]) cout << LARRYCHAR; else if (currentAngle <= angle[2]) cout << CURLYCHAR; else cout << SHEMPCHAR; } } cout << endl; } Modified Loop Modified Output CS 150
User’s Guide Release 1.0 Production Example CS 150
Hey, knucklehead, I found a bug in your so-called program! Whenever the survey says that nobody prefers Moe, the pie chart still contains a thin Moe wedge! Of course, the survey would never say anything as nutty as that, so what’d the difference? I know you’d have to change your operating system and develop an entirely new user interface, but could we have three-dimensional color pie-charts instead of these cheesy character-oriented charts? Nyuk, nyuk nyuk! I’ve got a suggestion: how about letting the user decide which ASCII characters to use for each stooge? Isn’t it a bug to limit the program to just four stooges? What about Joe and Curly Joe? Maintenance Example CS 150
Procedural Abstraction & Information Hiding To simplify the implementation of each module, functional specifications should be hidden from public view, i.e., other modules should not be aware of the specifications of a separate module. Does any module besides queryUser need to know how the survey values are set? Does any module besides outputPie need to know how the wedges on the pie are printed? Does any module besides calculate need to know how the angles are calculated? Does the outputLegend module need to know anything besides the survey result values? Does the queryUser module need to accept the stooge total parmeter as a call-by-reference parameter? CS 150
Object-Oriented Design • By viewing programming from an object-oriented perspective instead of a procedural perspective, additional mechanisms for hiding information (and thus safeguarding our programs) have been developed: • Encapsulation • Place the specific implementation details inside the object being manipulated (e.g., how a list object is searched or sorted, how a string object is output). • Inheritance • An object class that shares major features with a previously defined object class can just “inherit” those features from the old class without having them rewritten (e.g., a credit card account class could inherit from a more generic bank account class). • Polymorphism • Operators can be overloaded to mean different things, depending on what class of object is using them (e.g., the addition operator for integers might be very different than the addition operator for bank accounts, but both would use the + symbol to denote addition). • We’ll examine these mechanisms in further detail as we proceed into the concept of C++ classes. CS 150
Advantages of Modularity • Simplifies the construction of a program • Writing various small functions is simpler than orchestrating a huge single-unit program. • Simplifies the debugging of a program • Isolating errors to particular modules is made possible, and testing individual functions is easier than debugging a massive piece of code. • Improves the readability of a program • It’s easy to get lost in a huge program, but separating functionality into self-contained modules makes it easier to follow the logic of what’s happening in the code (especially, if the functions are well named and documented). • Enables a program to be easily modified • Modifications to algorithms are isolated to a small set of modules, if each module has been set up to perform a single cohesive task. • Eliminates redundant code • Similar functionality occurring in various locations in the program can be implemented as a generic function instead of repetitive code. • Enables a programmer to reuse code segments in other programs • Well-written generic modules can be cut and pasted into other programs, rather than rewriting them from scratch. CS 150
Modifiability Guidelines • Using functions • Writing every simple task relegated to a separate module makes it much easier to determine what code segments must be altered when execution details are being modified. • Named constants • Declaring a constant value at the beginning of the program (e.g., the size of an array, a default value for certain types of variables) and using that constant’s name in the body of the program, greatly simplifies later modifications (e.g., using the code with an array of a different size, using the code with a different type of variable). For example, using • const char HORIZ_BAR = ‘_’; • can be easily replaced with • const char HORIZ_BAR = ‘-’; • Type definitions • Declaring a generic type definition at the beginning of a program (using a typedef statement) can eliminate the need to alter parameter and local variable types when modifications are needed. For example, using • typedef int number; • can be easily replaced with • typedef long unsigned int number; CS 150
Improving I/O • Interactive sessions with the user should be clear and concise • The user should be prompted for any input. • Good: • Enter a Social Security Number of the form ###-##-####: • Bad: • SSN: • The input should be echoed back to the user as validation and for clarity. • Good: • Enter the current number of goldfish: 27 • Specify the average age of the 27 goldfish (in months): 3 • Specified: 27 goldfish with an average age of 3 months. • Bad: • Enter the current number of goldfish: 27 • Specify the average age of the goldfish (in months): 3 • Invalid input should be detected and corrected by the user (if possible). • Good: • Enter your current age (in years): 1975 • INVALID NUMBER - TOO LARGE. PLEASE TRY AGAIN. • Enter your current age (in years): • Output should be clearly labeled. • Good: • Enter the name of the file containing the monthly data: mnth.txt • MONTHLY SALES FIGURES FOR 1997 (SOURCE: mnth.txt) • ------------------------------------------------- • MONTH: 1 2 3 4 5 6 7 8 9 10 11 12 • SALES: $10 $22 $31 $45 $50 $63 $77 $82 $96 $112 $138 $172 CS 150
Do’s and Don’t’s of Programming Style 1. DO use functions extensively; every non-trivial task in the program should have its own function. 2. DO call by value (or by constant-reference - we’ll see that later) when passing parameters that should not be modified in the subroutine. 3. DO use valued functions when the function is producing a single value to be returned; use reference arguments if multiple values are being produced. 4. DO check for invalid input values and use assert statements whenever other logical errors might be easily detected. 5. DO include explanatory comments at the beginning of the program, summarizing the program’s purpose, at the beginning of each function, specifying the function’s task, and internal to the code, whenever the algorithm being used is particularly complicated. 6. DO name variables, constants, and functions in a meaningful way. 1. DON’T use global variables ever (although global constants are okay). 2. DON’T usegotostatements ever. Loops and conditional statements should be used whenever flow control is desired. CS 150