Presentation is loading. Please wait.

Presentation is loading. Please wait.

19. General Control Issues

Similar presentations


Presentation on theme: "19. General Control Issues"— Presentation transcript:

1 19. General Control Issues
CSC-3004 Introduction to Software Development Spring 2015 Dr. James Skon

2 Topics Boolean Expressions Compound Statements (Blocks)
Null Statements Taming Dangerously Deep Nesting A Programming Foundation: Structured Programming Control Structures and Complexity

3 Boolean Expressions Use the identifiers true and false in boolean expressions rather than using values like 0 and 1. int printerError; int reportSelected; int summarySelected; ... If (printerError == 0) { InitializePrinter(); } If (printerError == 1) {Then NotifyUserOfError();} If (reportSelected == 1) Then PrintReport(); } If (summarySelected == 1) Then PrintSummary(); } If (printerError == 0) { CleanupPrinter(); }

4 Boolean Expressions Use the identifiers true and false in boolean expressions rather than using values like 0 and 1. int printerError; int reportSelected; int summarySelected; ... If (printerError == 0) { InitializePrinter(); } If (printerError == 1) {Then NotifyUserOfError();} If (reportSelected == 1) Then PrintReport(); } If (summarySelected == 1) Then PrintSummary(); } If (printerError == 0) { CleanupPrinter(); }

5 Boolean Expressions boolean printerError; boolean reportSelected;
boolean summarySelected; ... If (printerError == false) { InitializePrinter(); } If (printerError == true) {Then NotifyUserOfError();} If (reportSelected == true) Then PrintReport(); } If (summarySelected == true) Then PrintSummary(); } If (printerError == false) { CleanupPrinter(); } Better, but not great

6 Boolean Expressions boolean printerError; boolean reportSelected;
boolean summarySelected; ... If (!printerError) { InitializePrinter(); } If (printerError) {Then NotifyUserOfError();} If (reportSelected) Then PrintReport(); } If (summarySelected) Then PrintSummary(); } If (!printerError) { CleanupPrinter(); } Much better!

7 MAKING COMPLICATED EXPRESSIONS SIMPLE
If ((document.AtEndOfStream ) && ( !inputError )) && (( MIN_LINES <= lineCount ) && ( lineCount <= MAX_LINES )) && ( !ErrorProcessing( )) { // do something or other ... }

8 MAKING COMPLICATED EXPRESSIONS SIMPLE
Boolean DocumentIsValid( Document documentToCheck, int lineCount, int inputError) { boolean allDataRead; boolean legalLineCount; allDataRead = documentToCheck.AtEndOfStream && !inputError; legalLineCount = (MIN_LINES <= lineCount) && (lineCount <= MAX_LINES); return (allDataRead && legalLineCount && !ErrorProcessing() ) }

9 MAKING COMPLICATED EXPRESSIONS SIMPLE
If ( DocumentIsValid( document, lineCount, inputError ) ) { // do something or other ... } Much Nicer!

10 MAKING COMPLICATED EXPRESSIONS SIMPLE
If you use the test only once, you might not think it's worthwhile to put it into a routine. But putting the test into a well-named function improves readability and makes it easier for you to see what your code is doing, and that's a sufficient reason to do it.

11 MAKING COMPLICATED EXPRESSIONS SIMPLE
The new function name introduces an abstraction into the program that documents the purpose of the test in code. That's even better than documenting the test with comments because the code is more likely to be read than the comments and it's more likely to be kept up to date, too.

12 FORMING BOOLEAN EXPRESSIONS POSITIVELY
if ( !statusOK ) { // do something (A) ... } else { // do something else (B)

13 FORMING BOOLEAN EXPRESSIONS POSITIVELY
if ( statusOK ) { // do something else (B) ... } else { // do something (A)

14 FORMING BOOLEAN EXPRESSIONS POSITIVELY
Apply DeMorgan's Theorems to simplify boolean tests with negatives. if ( !displayOK || !printerOK ) ... if ( !( displayOK && printerOK ) ) ...

15 DeMorgan's Theorems

16 KNOWING HOW BOOLEAN EXPRESSIONS ARE EVALUATED
Compilers for some languages evaluate each term in a boolean expression before combining the terms and evaluating the whole expression. Compilers for other languages have "short- circuit" or "lazy" evaluation, evaluating only the pieces necessary. Why does this matter?

17 KNOWING HOW BOOLEAN EXPRESSIONS ARE EVALUATED
Consider: while (i < MAX_ELEMENTS and item[ i ] <> 0) { ... } while ( i < MAX_ELEMENTS ) if ( item[ i ] <> 0 ) then Works ONLY with short circuit while ( i < MAX_ELEMENTS ) { if ( item[ i ] <> 0 ) { … } } Works without short circuit

18 Short Circuit Evaluation
if ( SomethingFalse && SomeCondition ) ... Evaluation stops as soon as SomethingFalse is identified as false. if ( somethingTrue || someCondition ) ... The evaluation stops as soon as somethingTrue is identified as true

19 Java Short Circuit Evaluation
if (( denominator != 0 ) && (( item / denominator ) > MIN_VALUE )) ... Works! if ((( item / denominator ) > MIN_VALUE ) && ( denominator != 0 )) ... Breaks!

20 Short Circuit Evaluation
Different languages use different kinds of evaluation, and language implementers tend to take liberties with expression evaluation, so check the manual for the specific version of the language you're using to find out what kind of evaluation your language uses.

21 EXPRESSIONS IN NUMBER-LINE ORDER
Organize numeric tests so that they follow the points on a number line. MIN_ELEMENTS <= i and i <= MAX_ELEMENTS i < MIN_ELEMENTS or MAX_ELEMENTS < i

22 EXPRESSIONS IN NUMBER-LINE ORDER
If you're testing i against MIN_ELEMENTS only, the position of i varies depending on where i is when the test is successful. If i is supposed to be smaller, you'll have a test like this: while ( i < MIN_ELEMENTS ) ... But if i is supposed to be larger, you'll have a test like this: while ( MIN_ELEMENTS < i ) ...

23 GUIDELINES FOR COMPARISONS TO 0
Programming languages use 0 for several purposes. It's a numeric value. It's a null terminator in a string. It's the value of a null pointer. It's the value of the first item in an enumeration. It's false in logical expressions. Write code that highlights the specific way 0 is used.

24 GUIDELINES FOR COMPARISONS TO 0
while ( !done ) … while ( balance != 0 ) … while ( balance ) … while ( *charPtr != '\0' ) … while ( *charPtr ) … while ( bufferPtr != NULL ) … while ( bufferPtr ) … 0 is false Balance is number \0 is a null character NULL is a pointer character

25 COMMON PROBLEMS WITH BOOLEAN EXPRESSIONS
In C-derived languages, put constants on the left side of comparisons. Why? if ( MIN_ELEMENTS = i ) ... if ( i = MIN_ELEMENTS ) ... MIN_ELEMENTS is a constant Will Not Compile! What does this mean? What was intended? Will Compile!

26 Null Statements while ( recordArray.Read( index++ ) != recordArray.EmptyRecord() ); { // Some Code } Null Statement Look at this code carefully …

27 Makes null statements visible
If you must use them, make it obvious! while ( recordArray.Read( index++ ) ) != recordArray.EmptyRecord() ) {} while ( recordArray.Read( index++ ) != recordArray.EmptyRecord() ) { ; } Makes null statements visible

28 Null Statements #define DoNothing() ...
while ( recordArray.Read( index++ ) != recordArray.EmptyRecord() ) { DoNothing(); } RecordType record = recordArray.Read( index ); index++; while ( record != recordArray.EmptyRecord() ) { record = recordArray.Read( index ); }

29 Nested Code if ( inputStatus == InputStatus_Success ) {
// lots of code ... if ( printerRoutine != NULL ) { if ( SetupPage() ) { if ( AllocMem( &printData ) ) { }

30 Nested Code - Retesting
if ( inputStatus == InputStatus_Success ) { // lots of code ... if ( printerRoutine != NULL ) { } if ( ( inputStatus == InputStatus_Success ) && ( printerRoutine != NULL ) && SetupPage() ) { if ( AllocMem( &printData ) ) {

31 Nested Code – break Block
do { // begin break block if ( inputStatus != InputStatus_Success ) { break; // break out of block } // lots of code ... if ( printerRoutine == NULL ) { if ( !SetupPage() ) { if ( !AllocMem( &printData ) ) { } while (FALSE); // end break block

32 Nested Code – Overgrown Decision Tree
if ( 10 < quantity ) { if ( 100 < quantity ) { if ( 1000 < quantity ) { discount = 0.10; } else { discount = 0.05; discount = 0.025; discount = 0.0;

33 Nested Code – IF-Then-Else
if ( 1000 < quantity ) { discount = 0.10; } else if ( 100 < quantity ) { discount = 0.05; else if ( 10 < quantity ) { discount = 0.025; else { discount = 0;

34 Control Structures and Complexity
One reason so much attention has been paid to control structures is that they are a big contributor to overall program complexity. Poor use of control structures increases complexity; good use decreases it. Make things as simple as possible—but no simpler. — Albert Einstein

35 Complexity "The competent programmer is fully aware of the strictly limited size of his own skull; therefore, he approaches the programming task in full humility" (Dijkstra 1972)

36 GENERAL GUIDELINES FOR REDUCING COMPLEXITY
Techniques for Counting the Decision Points in a Routine Start with 1 for the straight path through the routine. Add 1 for each of the following keywords, or their equivalents: if while repeat for and or Add 1 for each case in a case statement.

37 GENERAL GUIDELINES FOR REDUCING COMPLEXITY
if (((status = Success) && done) || (!done && (numLines >= maxLines)) } ... } 1 to start 2 for if 3 for && 4 for || 5 for && 5 decision points total

38 Complexity Measurement
Score Evaluation 0-5 The routine is probably fine. 6-10 Start to think about ways to simplify the routine. 10+ Break part of the routine into a second routine and call it from the first routine.

39 Key Points Making boolean expressions simple and readable contributes substantially to the quality of your code. Deep nesting makes a routine hard to understand. Fortunately, you can avoid it relatively easily. Structured programming is a simple idea that is still relevant: you can build any program out of a combination of sequences, selections, and iterations. Minimizing complexity is a key to writing high-quality code.


Download ppt "19. General Control Issues"

Similar presentations


Ads by Google