control structures chapter 14-19. outline 2 organizing straight-line code using conditionals ...
TRANSCRIPT
Control Structures
Chapter 14-19
Outline
2
Organizing Straight-Line Code Using Conditionals Table-Driven Methods Control Structures and Complexity
Organizing Straight-Line Code
3
Putting statements and blocks of statements in sequential order - a trivial task? fopen( )
fread( ) // fclose( ) should go here ProcessData( ) printf( ) fclose( )
But some organizational subtleties influence code quality, correctness, readability and maintainability
Problem: dependencies
Statements in a Specific Order
4
Statements in which order counts: obviousdata = readData();results = calculateResultsFromData(data);printResults(results);
The 2nd statement depends on the 1st
The 3rd statement depends on the 2nd
Statements in which order counts: less obvious
revenue.computeMonthly();revenue.computeQuarterly();revenue.computeAnnually();
Hidden Dependencies: Example
5
computeMarketingExpense();computeSalesExpense();computeTravelExpense();computePersonnelExpense();displayExpenseSummary();
Suppose computeMarketingExpense() initializes the variables that other routines put their data into
It needs to be called before the other routines!
Guidelines
6
Organize code to make dependencies obvious initializeExpenseData()
Name routines to make dependencies obvious computeMarketExpense() is misnamed – it does
more than compute marketing expenses computeMarketingExpenseAndInitializeData
Use parameters to make dependencies obvious initializeExpenseData(expenseData); computeMarketExpense(expenseData); or
expenseData=computeMarketExpense(expenseData);
Making Dependencies Obvious: Example
7
initializeExpenseData(expenseData);computeMarketingExpense(expenseData);computeSalesExpense(expenseData);computeTravelExpense(expenseData);computePersonnelExpense(expenseData);displayExpenseSummary(expenseData);
What if initializeExpenseData(expenseData) fails?
Guidelines - cont
8
Check for dependencies with assertions or error-handling code, if the code is critical enough Constructor may initialize isExpenseDataInitialized
to false, then initializeExpenseData sets it to true Each function depending on expenseData’s
initialization can check isExpenseDataInitialized. The benefits should be weighted against the
additional complexity. It creates new variables and new checking code – all of
which create additional possibilities for error.
Document unclear dependencies with comments
Making Dependencies Obvious: Example
9
initializeExpenseData(expenseData);if (isExpenseDataInitialized) {
computeMarketingExpense(expenseData);computeSalesExpense(expenseData);computeTravelExpense(expenseData);
computePersonnelExpense(expenseData);displayExpenseSummary(expenseData);
}
Statements Whose Order Doesn’t Matter
10
MarketingData marketingData;SalesData salesData;TravelData travelData;
travelData.computerQuartly();salesData.computeQuartly();marketingData.computeQuartly
();
travelData.computerAnually();salesData.computeAnnually();marketingData.computeAnnuall
y();
travelData.print();salesData.print();marketingData.print();
Bad code that jumps around!
How marketingData is calculated?
Start at the last line and track all references back to the first line
Although used in a few places, you have to keep in mind how it is used everywhere between the first and last references
Making Code Read from Top to Bottom
11
Experts agree that top-down order contributes most to readability
Better organizationMarketingData marketingData;marketingData.computeQuartly();marketingData.computeAnually();marketingData.print();…
References to each object are kept close together The # of LOC in which the objects are “live” is small The code now looks as if it could be broken into
separate routines for marketing, sales, and travel data.
Grouping Related Statements
12
Statements are related because they operate on the same data, perform similar tasks, or depending on each other’s being performed in
order
13
If the code is well organized into groups, boxes drawn around related sections don't overlap. They might be nested
If the code is organized poorly, boxes drawn around related sections overlap
14
Using Conditionals Put the normal case after the if rather than after the else
if(){normal case;
}else{
unnormal case}
Don't use NULL then clauses
Can You Improve This Code?
15
if ( ( (‘a’<=inputChar) && (inputChar <=‘z’)) || ( (‘A’<=inputChar) && (inputChar <=‘Z’))) {
charType = CharacterType.Letter;}else if ( (inputChar==‘ ‘) ||(inputChar == ‘,’) ||
(inputChar==‘.‘) || (inputChar==‘!‘) || (inputChar==‘(‘) ||(inputChar==‘)‘) || (inputChar==‘:‘) || (inputChar==‘;‘) ||(inputChar==‘?‘) || (inputChar==‘-‘)) {charType = CharacterType.Punctuation;
} else if ((‘0’<=inputChar) && (inputChar <=‘9’)) {charType = CharacterType.Digit; }
16
Simplify complicated tests with boolean function calls
17
Put the most common cases first
18
Make sure that all cases are covered Code a final else clause with an error message or assertion to catch cases you
didn't plan for.
19
Replace if-then-else chains with other constructs if your language
supports them
Can You Improve This Code?
20
if (month==1) days =31;
else if (month==2)days = 28;
else if (month==3)days = 31;
…else if (month == 12)
days = 31;
Leap year: more complicated
21
Controlling loop
22
23
Guidelines
24
25
26
27
28
29
30
Calculate charge movies Three types: regular, new released, kid Regular
$2 for 2 days, $1.5 for each extra day
New released $3 per day
Kid $1.5 for 3 days $1.5 for each extra day
31
Table-Driven Methods
32
Can You Improve This Code?
33
If your filing status is single If your filing status is marriedTax Bracket Percentage Tax Bracket Percentage
$0 … $21,450 15% $0 … $35,800 15%
Amount over $21,451, up to $51,900
28% Amount over $35,800, up to $86,500
28%
Amount over $51,900
31% Amount over $86,500
31%
TaxReturn.java: 1992 tax return Filing status: single, married (jointly/separately) Cutoffs/rates
Table-Driven Methods
34
What is a table-driven method? A scheme that allows you to look up info in table Rather than using logic statements (if and case) to
figure it out Why?
In simple cases, logic statements are easier and more direct
As the logic chain becomes more complex, tables become increasingly attractive
35
The CharacterType Example
36
Use a lookup table Store the type of each character in an array that’s
accessed by character code charType = charTypeTable[inputChar]; Assume charTypeTable has been set up earlier
Put your program’s knowledge into its data rather than into its logic (if tests)
The Days-in-Month Example
37
int daysPerMonth[] = {31,28, 31, 30,…, 31};
days = daysPerMonth[month-1];
Leap year days = daysPerMonth[month-1] + leapYearIndex(); // 0/1
38
Stair-Step Access
Stair-Step Access Tables
39
Entries in a table are valid for ranges of data rather than for distinct data points
Example<=100.0 A<90.0% B<75.0% C<65.0% D<50.0% F
Table structure?
Example
40
double rangeLimit[] = {50.0, 65.0, 75.0, 90.0, 100.0};String grade[] = {“F”, “D”, “C”, “B”, “A”};int maxGradeLevel = grade.length -1;
int gradeLevel = 0;String studentGrade = “A”;while (studentGrade==“A” &&
gradeLevel<maxGradeLevel) {if (studentScore>rangeLimit[gradeLevel]
studentGrade = grade[gradeLevel];gradeLevel = gradeLevel+1;
}
41
Try it out!
42
Boolean Expression
43
Boolean Expression – cont’ I ain't not no undummy
44
45
Boolean Expression – cont’ Apply DeMorgan's Theorems to simplify boolean tests
with negatives
46
Boolean Expression – cont’ Using Parentheses to Clarify Boolean
Expressions
47
Boolean Expression – cont’ Short-circuit evaluation
if the first operand of the and is false, the second isn't evaluated because the whole expression would be false anyway.
if ( SomethingFalse && SomeCondition ) ... Only SomethingFalse will be evaluated Evaluation stops as soon as SomethingFalse is
identified as false
48
Boolean Expression – cont’ using number-line ordering for boolean tests
Subtleties
49
Watch the endpoints Consider using a binary search rather than a
sequential search for a larger list Consider using indexed access
Control Structures and Complexity
50
Three Components of Structured Programming Sequence, Selection, Iteration Any control flow can be created Use of any other structure should be viewed with a
critical eye: break, continue, return, throw-catch Control structures are a big contributor to
overall program complexity Poor use of control structures increases
complexity. Programming complexity
Number of mental objects you have to keep in mind simultaneously in order to understand a program
How to Measure Complexity?
51
McCabe’s Cyclomatic Number C = E-N+2 E (number of edges), N (number of nodes) C = R+1, R is the number of legitimate regions C = D+1, D is the number of primitive decisions
How to Measure Complexity
52
McCabe’s Decision Points Start with 1 for the straight path through the
routine Add 1 for each of the following keywords, or their
equivalence: if, while, repeat, for, and, or Add 1 for each case in a case statement
Exampleif ((status==Success) && done) || (!done && (numLines >=maxLines)))…
5 decision points
Decision Points and Complexity
53
0-5: probably fine 6-10: start to think about ways to simplify 10+: brake part of the routine
It just moves the decision points around; doesn’t reduce the overall complexity
Reduces the amount of complexity you have to deal with at any ONE time
10 isn’t an absolute limit – use it as a warning flag Don’t use it as an inflexible rule
It might be foolish to break up a case statement with many cases
Reducing Complexity
54
Improve your own mental juggling abilities by doing mental exercises Programming itself is usually enough exercise People seem to have trouble juggling more than
about 5 to 9 mental entities Decrease the complexity of your programs
and the amount of concentration required to understand them