1 / 81

Chapter 4 : Conditionals

Chapter 4 : Conditionals. Objectives. After studying this chapter you should understand the following: the notions of preconditions, postconditions, and invariants; the purpose of a conditional statement; the function of boolean expressions; the purpose of a compound statement.

mikkel
Télécharger la présentation

Chapter 4 : Conditionals

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Chapter 4 : Conditionals

  2. Objectives • After studying this chapter you should understand the following: • the notions of preconditions, postconditions, and invariants; • the purpose of a conditional statement; • the function of boolean expressions; • the purpose of a compound statement. • Also, you should be able to: • write and evaluate boolean expressions; • write conditional statements of various forms; • implementation methods that use conditional statements; • implement a class tester which automatically verifies test results. NH-Chapter4

  3. Postconditions and invariants • Method currentCount in Counter is specified as • Specification stipulates invoking method returns a value of type int. /** * The number of items counted. */ public int currentCount () { … NH-Chapter4

  4. Postconditions and invariants • Can be more precise in specifying result : integer result is non- negative. • Postcondition: condition that implementor promises will be satisfied when method completes execution. • Implementor must make sure that the method satisfies the postcondition. /** * The number of items counted. * * @ensure this.currentCount() >= 0 */ public int currentCount () { … NH-Chapter4

  5. Postconditions and invariants • Need to make sure instance variable used to store current count will never contain a negative value. • Document this via a class invariant: private int count; // current count // invariant: count >= 0 • A class invariant will always be true of all instances of the class. NH-Chapter4

  6. Postconditions and invariants • If we add decrementCount to Counter: public void decrementCount () Decrement positive count by 1; zero count remains zero. • In implementation, need to add guard to be sure not to decrement when count == 0 NH-Chapter4

  7. The if-then statement if (condition) statement B E G I N true condition false statement E N D NH-Chapter4

  8. Implemeting decrementCount /** * Decrement positive count by 1; * zero count remains zero */ public void decrementCount () { if (count > 0) count = count - 1; } NH-Chapter4

  9. Explorer: invariants and guards • Restrict Explorer’s tolerance to be a non-negative integer. • Need to insure value assigned in each case is not negative. private int tolerance; // current tolerance // invariant: tolerance >= 0 /** * Damage (hit points) required to defeat * this Explorer. * * @ensure tolerance >= 0 */ public int tolerance () { return tolerance; } NH-Chapter4

  10. Explorer: invariants and guards • Consider method takeThat. • Need to guard the two statements: if (hitStrength <= tolerance) tolerance = tolerance - hitStrength; if (hitStrength > tolerance) tolerance = 0; • But, only one of those should execute when invokingtakeThat. NH-Chapter4

  11. if-then-else statement if (condition) statement1 else statement2 B E G I N false true condition statement statement 2 1 E N D NH-Chapter4

  12. Implementing method takeThat public void takeThat (int hitStrength) { if (hitStrength <= tolerance) tolerance = tolerance - hitStrength; else tolerance = 0; } NH-Chapter4

  13. Implementing constructor public Explorer (String name, Room location,int strength, int tolerance) { … if (tolerance >= 0) this.tolerance = tolerance; else this.tolerance = 0; … } NH-Chapter4

  14. if (condition) { statement1 … statementN } if (condition) { statement11 … statement1N }else { statement21 … statement2M } Compound statements NH-Chapter4

  15. Conditions: boolean expressions • Boolean expressions: • Produce boolean values when evaluated; • Evaluate to true or false. • Can declare boolean variables, and assign values: tooBig = true; Or tooBig = size > 10; private boolean tooBig; • And can assign values to it: NH-Chapter4

  16. Handling multiple cases • A conditional statement divides problem into two cases to be considered independently. • In many problems, there are more than two cases, or cases need to be further divided into subcases. • Use nesting conditional statements. NH-Chapter4

  17. Handling multiple cases • Assume class Date with properties day, month,year. • Implement a Date’s query that will tell whether or not a date occurs in a leap year. public boolean isLeapYear () This Date occurs in a leap year. NH-Chapter4

  18. Case: year not divisible by 4 not a leap year. Case: year divisible by 4 ??? Case: divisible by 100 ??? Case: not divisible by 100is leap Case: divisible by 400is leap Case: not divisible by 400is not leap Handling multiple cases isLeapYear NH-Chapter4

  19. Handling multiple cases // This Date occurs in a leap year. public boolean isLeapYear () { boolean aLeapYear; if (year % 4 == 0) if (year % 100 == 0) // if divisible by 100, // must also be divisible by 400 aLeapYear = (year % 400 == 0); else // divisible by 4, not by 100 aLeapYear = true; else // not divisible by 4 aLeapYear = false; return aLeapYear; } NH-Chapter4

  20. Cascading conditionals • When problem splits into more than two cases: • “cascade” if-then-else statements. if (case1) handleCase1 else if (case2) handleCase2 … else if (penultimateCase) handlePenultimateCase else handleLastCase NH-Chapter4

  21. change : case: light is GREEN case: light is YELLOW case: light is RED change to GREEN change to YELLOW change to RED TrafficLight’s change() method NH-Chapter4

  22. TrafficLight’s change() method public void change () { if (light == GREEN) light = YELLOW; else if (light == YELLOW) light = RED; else // light == RED light = GREEN; } NH-Chapter4

  23. Dangling else • There is an ambiguity as to whether the structure • Is it an if-then nested in an if-then-else, or an if-then-else nested in an if-then? if (condition1) if (condition2) statement1 else statement2 NH-Chapter4

  24. Dangling else NH-Chapter4

  25. if (condition1) if (condition2) statement1 else statement2 if (condition1) { if (condition2) statement1 else statement2 } Dangling else: equivalent statements NH-Chapter4

  26. Example: combination lock • Responsibilities: • Know: • The combination • whether unlocked or locked • Do: • lock • unlock NH-Chapter4

  27. CombinationLock class • Class: CombinationLock • Queries: • is open • Commands: • lock • unlock NH-Chapter4

  28. Class CombinationLock specifications publicclass CombinationLock Contructor: public CombinationLock (int combination) Queries: public boolean isOpen() Commands: public void close () public void open(int combination) NH-Chapter4

  29. Class CombinationLock implementation Component variables: private int combination; private boolean isOpen; NH-Chapter4

  30. Structure for a simple test public class CombinationLock { private int combination; private boolean isOpen; public CombinationLock (int combination) { } public boolean isOpen () { return true; } public void close () { } public void open (int combinationToTry) { } } NH-Chapter4

  31. Structure for a simple test class CombinationLockTest { private CombinationLock lock; public CombinationLockTest () { } publicvoid runTest () { } } public class TestCombinationLock { public static void main (String[] argv) { (new CombinationLockTest()).runTest(); } } NH-Chapter4

  32. Precondition • A condition client of a method must make sure holds when method is invoked. • “Require”s : Constructor and method enterhave requirements that clients must meet for them to execute properly. NH-Chapter4

  33. Constructor specifications /** * Create a lock with the specified combination. * * @require: * 0 <= combination && combination <= 999 * @ensure: * this.isOpen() */ public CombinationLock (int combination) … NH-Chapter4

  34. Testing locks • Need method to create and test lock with given combination: • Invoke this method in runTest for each lock to test. private void testLock (int combination) Test a lock with the specified combination. public void runTest () { testLock(0); testLock(123); testLock(999); } NH-Chapter4

  35. Automating checking of test results private void verify (boolean test, String message) { if (!test) System.out.println( "Verification failed: " + message); } NH-Chapter4

  36. testLock method • testLock method must create lock and run initial state test: private void testLock (int combination) { lock = new CombinationLock(combination); testInitialState(); } NH-Chapter4

  37. testLock method • Initial state test should make sure that lock is open. • So, instead of writing the test method: • Write: private void testInitialState() { System.out.println("Initial state: " + lock.isOpen()); } private void testInitialState() { verify(lock.isOpen(), "initial state"); } NH-Chapter4

  38. Class CombinationLock implementation • The straightforward implementations: public CombinationLock (int combination) { this.combination = combination; this.isOpen = true; } public boolean isOpen () { return isOpen; } NH-Chapter4

  39. Class CombinationLock implementation • In constructor, there are two variables with same name. • Component variable and • local variable combination. • this.combination refers to component variable. • If variable does not include object reference this in front of it, it is a reference to local variable. NH-Chapter4

  40. Class CombinationLock implementation NH-Chapter4

  41. Method to test close • write method to test close, and invoke it from testLock: private void testClose() { lock.close(); verify(!lock.isOpen(), "close open lock"); lock.close(); verify(!lock.isOpen(), "close closed lock"); } private void testLock (int combination) { lock = new CombinationLock(combination); testInitialState(); testClose(); } NH-Chapter4

  42. Implementing close in Lock • Command close is also easy to implement: public void close () { isOpen = false; } NH-Chapter4

  43. Method to test open • Test for the method open: four cases to test: • closed lock, correct combination: lock opens; • open lock, correct combination: lock remains open; • closed lock, incorrect combination: lock remains closed. • open lock, incorrect combination: lock remains open; • Test depends on combination, so pass correct combination as argument: privatevoidtestOpen (int combination) NH-Chapter4

  44. testOpen method private void testOpen (int combination) { int badCombination = (combination + 1) % 1000; // test with correct combination: lock.close(); lock.open(combination); // open closed lock verify(lock.isOpen(), "open closed lock"); lock.open(combination); // open opened lock verify(lock.isOpen(), "open opened lock"); // test with incorrect combination: lock.open(badCombination); // try opened lock verify(lock.isOpen(), "bad comb, opened lock"); lock.close(); lock.open(badCombination); // try closed lock verify(!lock.isOpen(), "bad comb, closed lock"); } NH-Chapter4

  45. testOpen method • Add an invocation of this method to testLock: private void testLock (int combination) { lock = new CombinationLock(combination); testInitialState(); testClose(); testOpen(combination); } NH-Chapter4

  46. Method open implementation • The following implementation of open fails the tests. • test will produce the following output: • Verification failed: bad comb, opened lock • Verification failed: bad comb, opened lock • Verification failed: bad comb, opened lock • Root of problem: attempt to open an already opened lock with incorrect combination should not close it. public void open (int combination) { isOpen = (this.combination == combination) } NH-Chapter4

  47. Method open implementation • Correct implementation of method uses a conditional statement that opens the lock if the combination is correct, and does nothing if the combination is not correct: public void open (int combinationToTry) { if (this.combination == combinationToTry) isOpen = true; } NH-Chapter4

  48. Digit by digit lock • This lock has a 3 digit combination. • To open the lock, client provides the digits one at a time. • If client enters three digits of combination in order, lock opens. • It doesn’t matter how many digits client provides, as long as combination is given. NH-Chapter4

  49. Digit by digit lock: combination 123 Digit Entered 4 1 2 4 3 1 2 3 Digit Entered 1 2 3 4 7 Lock Status closed closed closed closed closed closed closed open Lock Status closed closed open open open NH-Chapter4

  50. Digit by digit lock: combination 123 • if client gives command close when combination has been partly entered, Client Command Lock Status enter 1 closed enter 2 closed close closed enter 3 ? Client Command Lock Status open enter 1 open enter 2 open close closed enter 3 ? • command close resets lock, entire combination must be entered. NH-Chapter4

More Related