The Personal Software Process: an Independent Study | ||
---|---|---|
Prev | Chapter 7. Lesson 7: Design and Code Reviews | Next |
Define a process for analyzing your PSP data and producing a report. Use this process to produce report R4. You will update this process to produce the final report at the end of the course.
Task 1-- Develop a process for analyzing the data and creating a report on programs 1A through 6A. This should include the results listed below under Task 3. This process must include a planning phase, the task performance phases, and a postmortem phase. Produce and submit a process script and planning forms for enacting this process. Task 2-- Plan and enact the process defined in Task 1. Use the planning form to record the planned time for this work and track and record the actual time you spend. Submit the planned and actual process data together with the analysis report. Task 3-- Analyze the data for programs 1 through 6. Spreadsheet analyses are suggested and graphical summaries and presentations are encouraged. At a minimum, produce the following:
Result: Use the GQM method to draw conclusions and set personal improvement goals. Submit the required analyses, tables, and checlists, together with a brief written report. Use graphs wherever possible. Table 7-1. D23: Percentage of defects injected and removed by phase
Table 7-2. D24: Percentage of Defects Found in Compile
| ||||||||||||||||||||||||
--[Humphrey95] |
Without much guidance, I'll be flailing a bit on this, but I'll base this process "script" off Humphrey's format for the PSP scripts.
Table 7-3. Report R4 Development Script
Phase Number | Purpose | To guide the reporting of PSP data |
Entry Criteria |
| |
1 | Planning |
|
2 | Data Collation |
|
3 | Data analysis |
|
4 | Report generation |
|
5 | Postmortem | Complete a report summary with actual time data |
Exit criteria |
|
LOC data is taken from programs 2A through 6A; first graph is a depiction of rough-guess estimated LOC vs actual program LOC, showing the best-fit linear regression line through the data points. As the graph shows, the data is not particularly accurate, and the "best fit" approximation is not particularly good.
Rough-guess estimated new/changed LOC vs actual program new/changed LOC; with these four data points, the fit is fairly bad.
A more "calibrated" comparison is the comparison of PROBE- generated estimates vs actual LOC; the "actual" numbers are the same as the last graph, but the estimates are those generated from the full PROBE algorithm. A "perfect fit" line is plotted to show how the PROBE estimates varied from a perfect 1-to-1 match
PROBE estimates vs actual data. The samples are still very scattered and not particularly accurate-looking.
In fact, it doesn't look like we're doing well on accuracy at all, until we take a closer look at accuracy by using the "percent error" equation on the numbers.
Percent error in each estimation. Note the downward trend.
A look at the time figures reveals some similar trends:
Estimated development time vs actual development time. Aside from an obvious outlier, this has actually been fairly regular.
Percent error in each time estimation; note the similarity to the LOC percent error graph.
...and a similar analysis of the time estimation error reveals an extremely similar curve. This makes sense, since the time estimates are made directly from size estimates; they should form similar curves. Still, it's good to see that they are similar-- and that our estimation abilities seem to be getting better over time. Note the very large spike in percent error near the beginning of the graphs; this is program 2a, which was significantly larger than predicted and certainly took a great deal of time.
Table 7-4. Percentage of defects injected and removed by phase -- C++
Number Injected | Percentage Injected | Number Removed | Percentage Removed | |||||
Type | Design | Code | Design | Code | Compile | Test | Compile | Test |
md (missing design) | 15 | 1 | 10.6 | 0.7 | 1 | 2 | 0.9 | 4.3 |
me (missing error-handling) | 0 | 1 | 0 | 0.7 | 0 | 1 | 0 | 0.7 |
wn (wrong name) | 1 | 19 | 0.7 | 13.5 | 15 | 6 | 10.6 | 4.3 |
mi (missing implementation) | 0 | 1 | 0 | 0.7 | 0 | 1 | 0 | 0.7 |
wa (wrong algorithm) | 4 | 8 | 2.8 | 5.7 | 0 | 13 | 0 | 9.2 |
wc (wrong condition) | 2 | 0 | 1.4 | 0 | 0 | 2 | 0 | 1.4 |
ch | 0 | 1 | 0 | 0.7 | 1 | 0 | 0.7 | 0 |
wt (wrong type) | 0 | 4 | 0 | 2.8 | 3 | 1 | 2.1 | 0.7 |
we (wrong expression) | 2 | 1 | 1.4 | 0.7 | 0 | 3 | 0 | 2.1 |
is (interface specification) | 0 | 1 | 0 | 0.7 | 0 | 1 | 0 | 0.7 |
ic (interface capability) | 17 | 5 | 12.1 | 3.5 | 2 | 4 | 1.4 | 2.8 |
sy (syntax) | 0 | 43 | 0 | 30.5 | 43 | 0 | 30.5 | 0 |
id (interface description) | 1 | 1 | 0.7 | 0.7 | 1 | 0 | 0.7 | 0 |
ma (missing assignment) | 0 | 1 | 0 | 0.7 | 0 | 1 | 0 | 0.7 |
iu (interface use) | 0 | 8 | 0 | 5.7 | 5 | 4 | 3.5 | 2.8 |
Eiffel | ||||||||
mc (missing call) | 0 | 5 | 0 | 5.5 | 4 | 1 | 4.4 | 1.1 |
md (missing design) | 2 | 0 | 2.2 | 0 | 1 | 1 | 1.1 | 1.1 |
wn (wrong name) | 0 | 13 | 0 | 14.3 | 10 | 3 | 11.0 | 3.3 |
mi (missing implementation) | 0 | 2 | 0 | 2.2 | 0 | 2 | 0.0 | 2.2 |
wa (wrong algorithm) | 0 | 10 | 0 | 11 | 1 | 9 | 1.1 | 9.9 |
wc (wrong condition) | 0 | 3 | 0 | 3.3 | 0 | 3 | 0.0 | 3.3 |
sy (syntax) | 0 | 31 | 0 | 34.1 | 31 | 1 | 34.1 | 1.1 |
wt (wrong type) | 0 | 1 | 0 | 1.1 | 1 | 0 | 1.1 | 0 |
is (interface specification) | 0 | 1 | 0 | 1.1 | 1 | 0 | 1.1 | 0 |
ic (interface capability) | 2 | 5 | 2.2 | 5.5 | 5 | 1 | 5.5 | 1.1 |
ma (missing assignment) | 0 | 8 | 0 | 8.8 | 4 | 4 | 4.4 | 4.4 |
iv (invariant) | 0 | 1 | 0 | 1.1 | 0 | 1 | 0 | 1.1 |
Table 7-5. D24: Percentage of Defects Found in Compile -- C++
Defect Type | Number of defects at compile entry | Number of defects found in compile | Percentage of type found by the compiler |
md | 3 | 1 | 33 |
me | 1 | 0 | 0 |
wn | 21 | 15 | 71 |
mi | 1 | 0 | 0 |
wa | 13 | 0 | 0 |
wc | 2 | 0 | 0 |
wc | 2 | 0 | 0 |
ch | 1 | 1 | 100 |
wt | 4 | 3 | 75 |
we | 3 | 0 | 0 |
sy | 43 | 43 | 100 |
ic | 6 | 2 | 33 |
is | 1 | 0 | 0 |
id | 1 | 1 | 100 |
ma | 1 | 0 | 0 |
iu | 9 | 5 | 55 |
Eiffel | |||
mc | 5 | 4 | 80 |
md | 2 | 1 | 50 |
wn | 13 | 10 | 77 |
mi | 2 | 0 | 0 |
wa | 10 | 1 | 10 |
wc | 3 | 0 | 0 |
sy | 32 | 31 | 97 |
wt | 1 | 1 | 100 |
ic | 6 | 5 | 83 |
is | 1 | 1 | 100 |
ma | 8 | 4 | 50 |
iv | 1 | 0 | 0 |
Table 7-6. Defect Fix Times
C++ | |||||||||||||||||||||
Defects found in compile | Defects found in test | Total Defects found | |||||||||||||||||||
Defects injected in design |
|
|
| ||||||||||||||||||
Defects injected in code |
|
|
| ||||||||||||||||||
Total defects injected |
|
|
| ||||||||||||||||||
Eiffel | |||||||||||||||||||||
Defects found in compile | Defects found in test | Total Defects found | |||||||||||||||||||
Defects injected in design |
|
|
| ||||||||||||||||||
Defects injected in code |
|
|
| ||||||||||||||||||
Total defects injected |
|
|
|
It's interesting to note that defects found in test seem to be substantially larger, or at least require longer fix times. The too-simple conclusion is that errors found later in the development cycle "cost more" than errors found earlier. This is probably true, but it's also true that the compiler is catching very simple errors automatically-- errors which couldn't be caught during test, because the program simply won't compile enough to test without them.
The largest categories of design-injected failures are "missing design" and "interface capability" (which is essentially a lesser manifestation of "missing design"). Less frequent are "wrong name", "wrong algorithm", "wrong expression" (a lesser manifestation of wrong algorithm), and "wrong expression" (a boolean manifestation of wrong expression).
It's tough to know where to start with this. These are all fairly fuzzy things; I'll start with Humphrey's design review checklist on [Humphrey95] page 705, and attempt to expand it as necessary. The problem is, there isn't much necessary-- the "missing design" errors are covered by the "complete" category, and and "wrong algorithm" errors are covered mostly by the "logic" section. Still, I've added a few minor items, shown by emphasis.
Table 7-7. Design Review Checklist
Purpose | To guide you in conducting an effective design review | |
General |
| |
Complete | Ensure that the requirements, specifications, and high-level design are completely covered by the design:
| |
Logic |
| |
Special Cases | Check all special cases:
| |
Functional Use |
| |
Names | Verify the Following:
| |
Contracts | Check/create require/ensure/check/invariant contracts for all methods and classes | |
Standards | Review the design for conformance to all applicable design standards |
Big items injected in the coding phase are wrong name and syntax, with interface use, wrong algorithm, interface capability, and wrong type finishing up. With C++, wrong type is very sneaky, because it's good at automatically converting without any input from the programmer.
Humphrey gives us a C++ code review checklist, so I'll supplement it with emphasized lines (and modifications). I'll try and merge the Eiffel code review checklist with this, noting the obvious places.
Table 7-8. Code Review Checklist
Purpose | To guide an effective code review | |
General |
| |
Complete | Verify that the code covers all the design | |
Includes (ignore for Eiffel) | Verify that includes are complete | |
Initialization | Check variable and parameter initialization:
| |
Calls | Check function call formats:
| |
Names | Check name spelling and use
| |
Pointers (C++ only) | Check that
| |
Output format | Check the output format:
| |
Block closure | Ensure that blocks are properly opened/closed (brace matching in C++, proper closure in Eiffel) | |
Logic operators/assignment |
| |
Line-by-line check | Check every LOC for
| |
Standards/prettify |
| |
File open/close | Verify that all files are
| |
Special interest items |
|
Time preparing this report was spent as follows:
Table 7-9. Time Recording Log
Student: | Victor B. Putz | Date: | 000117 |
Program: | R4 |
Start | Stop | Interruption Time | Delta time | Phase | Comments |
000117 14:07:57 | 000117 14:31:55 | 0 | 23 | estimation accuracy | |
000117 14:31:58 | 000117 14:48:23 | 0 | 16 | defect injection/removal | |
000117 14:49:10 | 000117 14:55:34 | 0 | 6 | defects found by compiler | |
000117 14:55:38 | 000117 15:06:13 | 0 | 10 | defect fix times | |
000117 15:08:17 | 000117 15:41:27 | 0 | 33 | design review checklist | |
000117 15:41:29 | 000117 15:57:34 | 0 | 16 | code review checklist | |
I'm not doing an extensive postmortem on this because I don't feel the time involved would justify the reward. If I continue using the PSP, this section will have to be heavily automated, and will differ so much from the current hand-drawn method that it will no longer be recognizable.