Title: Chapter 4 : Conditionals
1Chapter 4 Conditionals
2Objectives
- 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.
3Postconditions and invariants
- Method currentCount in Counter is specified as
/ The number of items counted. / public
int currentCount ()
- Specification stipulates invoking method returns
a value of type int.
4Postconditions and invariants
- Can be more precise in specifying result
integer result is non- negative.
/ The number of items counted. _at_ensure
this.currentCount() gt 0 / public int
currentCount ()
- Postcondition condition that implementor
promises will be satisfied when method completes
execution. - Implementor must make sure that the method
satisfies the postcondition.
5Postconditions 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 gt 0
- A class invariant will always be true of all
instances of the class.
6Postconditions 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
7The if-then statement
B
E
G
I
N
true
condition
false
statement
E
N
D
8Implemeting decrementCount
- /
- Decrement positive count by 1
- zero count remains zero
- /
- public void decrementCount ()
- if (count gt 0)
- count count - 1
-
9Explorer invariants and guards
- Restrict Explorers tolerance to be a
non-negative integer.
private int tolerance // current
tolerance // invariant tolerance gt 0 /
Damage (hit points) required to defeat this
Explorer. _at_ensure tolerance gt 0 / public
int tolerance () return tolerance
- Need to insure value assigned in each case is not
negative.
10Explorer invariants and guards
- Consider method takeThat.
- Need to guard the two statements
if (hitStrength lt tolerance) tolerance
tolerance - hitStrength if (hitStrength gt
tolerance) tolerance 0
- But, only one of those should execute when
invoking takeThat.
11if-then-else statement
- if (condition)
- statement1
- else
- statement2
B
E
G
I
N
true
false
condition
statement
statement
1
2
E
N
D
12Implementing method takeThat
- public void takeThat (int hitStrength)
- if (hitStrength lt tolerance)
- tolerance tolerance - hitStrength
- else
- tolerance 0
-
13Implementing constructor
- public Explorer (String name, Room
location, int strength, int tolerance) -
- if (tolerance gt 0)
- this.tolerance tolerance
- else
- this.tolerance 0
-
-
14Compound statements
- if (condition)
- statement1
-
- statementN
- if (condition)
- statement11
-
- statement1N
- else
- statement21
-
- statement2M
-
15Conditions boolean expressions
- Boolean expressions
- Produce boolean values when evaluated
- Evaluate to true or false.
- Can declare boolean variables, and assign values
private boolean tooBig
- And can assign values to it
- tooBig true
- Or
- tooBig size gt 10
16Handling 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.
17Handling multiple cases
- Assume class Date with properties day,
month,year. - Implement a Dates query that will tell whether
or not a date occurs in a leap year.
public boolean isLeapYear () This Date occurs in
a leap year.
18Handling multiple cases
isLeapYear
19Handling 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
20Cascading 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
21TrafficLights change() method
22TrafficLights change() method
public void change () if (light
GREEN) light YELLOW else if (light
YELLOW) light RED else // light
RED light GREEN
23Dangling else
- There is an ambiguity as to whether the structure
if (condition1) if (condition2) statement1 else
statement2
- Is it an if-then nested in an if-then-else, or an
if-then-else nested in an if-then?
24Dangling else
25Dangling else equivalent statements
- if (condition1)
- if (condition2)
- statement1
- else
- statement2
- if (condition1)
- if (condition2)
- statement1
- else
- statement2
26Example combination lock
- Responsibilities
- Know
- The combination
- whether unlocked or locked
- Do
- lock
- unlock
27CombinationLock class
- Class CombinationLock
- Queries
- is open
- Commands
- lock
- unlock
28Class CombinationLock specifications
- public class CombinationLock
- Contructor
- public CombinationLock (int combination)
- Queries
- public boolean isOpen()
- Commands
- public void close ()
- public void open(int combination)
29Class CombinationLock implementation
private int combination private boolean isOpen
30Structure 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)
-
31Structure for a simple test
- class CombinationLockTest
- private CombinationLock lock
- public CombinationLockTest ()
-
- public void runTest ()
-
public class TestCombinationLock public
static void main (String argv) (new
CombinationLockTest()).runTest()
32Precondition
- A condition client of a method must make sure
holds when method is invoked. - Requires Constructor and method enter have
requirements that clients must meet for them to
execute properly.
33Constructor specifications
- /
- Create a lock with the specified combination.
-
- _at_require
- 0 lt combination combination lt 999
- _at_ensure
- this.isOpen()
- /
- public CombinationLock (int combination)
34Testing locks
- Need method to create and test lock with given
combination
private void testLock (int combination) Test a
lock with the specified combination.
- Invoke this method in runTest for each lock to
test.
public void runTest () testLock(0) testLock(1
23) testLock(999)
35Automating checking of test results
- private void verify (boolean test, String
message) - if (!test)
- System.out.println(
- "Verification failed " message)
36testLock method
- testLock method must create lock and run initial
state test
private void testLock (int combination) lock
new CombinationLock(combination) testInitialStat
e()
37testLock method
- Initial state test should make sure that lock is
open. - So, instead of writing the test method
private void testInitialState()
System.out.println("Initial state "
lock.isOpen())
private void testInitialState()
verify(lock.isOpen(), "initial state")
38Class CombinationLock implementation
- The straightforward implementations
- public CombinationLock (int combination)
- this.combination combination
- this.isOpen true
-
- public boolean isOpen ()
- return isOpen
39Class 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.
40Class CombinationLock implementation
41Method 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(combina
tion) testInitialState() testClose()
42Implementing close in Lock
- Command close is also easy to implement
public void close () isOpen false
43Method 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 - private void testOpen (int combination)
44testOpen 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")
45testOpen method
- Add an invocation of this method to testLock
private void testLock (int combination) lock
new CombinationLock(combination) testInitialStat
e() testClose() testOpen(combination)
46Method open implementation
- The following implementation of open fails the
tests.
public void open (int combination) isOpen
(this.combination combination)
- 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.
47Method 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
48Digit 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 doesnt matter how many digits client
provides, as long as combination is given.
49Digit 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 clo
sed closed open Lock Status closed closed open op
en open
50Digit 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.
51Digit by digit lock
- If combination is 123 and digits 1-2-2 are
entered, we need three digits to open the lock - Digit Entered Lock Status
- 1 closed (need 2-3 to open)
- 2 closed (need 3 to open)
- 2 closed (need 1-2-3 to open)
- If combination is 223 and the digits 2-2-2 are
entered, a 3 will still open the lock - Digit Entered Lock Status
- 2 closed (need 2-3 to open)
- 2 closed (need 3 to open)
- 2 closed (still need 3 to open)
52Class CombinationLock
- Constructor
- public CombinationLock (int combination)
- require combination gt 0 combination lt999
- Queries
- public boolean isOpen ()
- Commands
- public void close ()
- public void enter (int digit)
- require digit gt0 digit lt9
53CombinationLock responsibilities
- Know
- the 3-digit combination.
- whether locked or unlocked.
- the last three digits entered.
- Do
- lock.
- unlock, when given the proper combination.
- accept a digit.
54Getting digits from integers.
- Using and / operators, can extract each digit.
- Suppose combination 123.
- 123 10 -gt 3
- 123 / 10 -gt 12
- 12 10 -gt 2
- 12 / 10 -gt 1
- 10 gets last digit
- / 10 gets remaining digits.
55CombinationLock implementation
- private boolean isOpen // lock is unlocked
- private int digit1 // 1st combination digit
- private int digit2 // 2nd combination digit
- private int digit3 // 3rd combination digit
- // invariant
- // digit1 gt 0 digit1 lt 9
- // digit2 gt 0 digit2 lt 9
- // digit3 gt 0 digit3 lt 9
56CombinationLock implementation
- // last, secondToLast, thirdToLast are the last
three - // digits entered, with last the most recent.
- // a value of -1 indicates digit has not been
entered. - private int last
- private int secondToLast
- private int thirdToLast
- // invariant
- // -1 lt last lt 9
- // -1 lt secondToLast lt 9
- // -1 lt thirdToLast lt 9
57- Combination is 223, and digits 2-2 have been
entered to a closed lock
58Implementing constructor
- public CombinationLock (int combination)
- digit3 combination 10
- combination combination / 10
- digit2 combination 10
- digit1 combination / 10
- isOpen true
- last -1
- secondToLast -1
- thirdToLast -1
59Implementing methods
- Query isOpen is the same as before.
public boolean isOpen () return isOpen
- Command close must resets lock.
public void close () open false last
-1 secondToLast -1 thirdToLast -1
60Implementing method enter
- public void enter (int digit)
- thirdToLast secondToLast
- secondToLast last
- last digit
- if (thirdToLast digit1
- secondToLast digit2 last digit3)
- isOpen true
61Relational operators
- lt less than or equal
- gt greater than
- gt greater than or equal
- equal (A single denotes assignment.)
- ! not equal
- A relational expression consists of two
expressions joined with a relational operator.
62Relational expressions
- Let i110, i2-20, i330.
- i1 lt 12 ? true
- i1 lt 10 ? true
- i3 i1 ? false
- i1 ! 2 ? true
- i1 lt 10 ? false
- i2 gt 0 ? false
- 2i1 i240 ? true
- i2(-1) ! i1i1 ? false
63Relational expressions
- An expression like altbltc is illegal.
- int values are converted to double, in mixed type
comparisons - 10 gt 2.5 ? 10.0 gt 2.5 ? false
64Relational expressions
- floating point values are approximations for real
numbers, avoid using equality or inequality
operators with them. - (1.0/6.0 1.0/6.0 1.0/6.0
- 1.0/6.0 1.0/6.0 1.0/6.0) 1.0 ? false
65Reference equality and object equality
- Operators and ! can be used to compare values
of any type. - Comparing reference values must be of same type.
Counter counter1 Counter counter2 Explorer
myHero counter1 counter2 // legal counter1
myHero // compilation error
66Reference equality and object equality
- Two reference values are equal if they refer to
same object. - How to check if two different objects are equal?
- if string1, string2, and string3 are String
variables,
string1 "c" string2 "ab" string1 string3
"a" "bc"
- string2 and string3 will reference two distinct
objects.
string2 string3 ? false
- use String method equals,
string2.equals(string3) ? true
67Boolean operators
! booleanExpression booleanExpression
booleanExpression booleanExpression
booleanExpression
- A boolean expression evaluates to true or false
68The ! (not) operator
- Not reverses boolean values.
- !true ? false
- !false ? true
- Given i110
- !( i1 gt 9) ? !(true) ? false
- Beware Not has high precedence.
- ! i1 gt 9 ? (!i1) gt 9 ? illegal
69, (and then, or else) operators
- Given i110
- (i1gt10)(i110) ? false true ? true
- (i1gt10)(i1lt0) ? false false ? false
- (i1gt0)(i1lt5) ? true false ? false
- (i1gt0)(i1lt20) ? true true ? true
70, (and then, or else) operators
- and have lower precedence than the
relational operators. - Parentheses are still useful as they enhance
readability. - i1 lt i2 i1 lt i3 means
- (i1 lt i2) (i1 lt i3)
- Using the and then operator, can express the
condition that value of i1 is between 0 and 20 - (0 lt i1) (i1 lt 20)
71The and are lazy operators
- They evaluate only the left operand only when
that suffices. - Given i110
- (i1 lt 10) (i1 gt 0) ? false (i1 gt 0)? false
- (i1 lt 11) (i1 gt 100)? true (i1 gt 100)?
true - Right operands, (i1 gt 0) and (i1 gt 100), are not
evaluated. - Useful when considering expressions like
- (x 0) (y/x lt 10)
- If left operand is true, x is 0, evaluating right
operand will result in an attempt to divide by 0
and a run-time error.
72Operator precedence
- High
- unary , unary -, !
- , /,
- , -
- lt, lt, gt, gt
- , !
-
-
- Low
73DeMorgans Laws
- Useful for simplifying expressions.
- !(b1 b2) ? !b1 !b2
- !(b1 b2) ? !b1 !b2
- !(i1gt5 i1lt8) ? !(i1gt5) !(i1lt8)
74Summary
- Introduced boolean expressions and conditional
statements. -
- Conditional statements allow us to specify
alternative computations and the circumstances
under which each is to be performed. - The particular action to be done is determined by
the processor at execution time, depending on the
current data values.
75Summary
- The two forms of conditional statement weve seen
are if-then and if-then-else.
if (condition) statement
- With an if-then-else, we specify two possible
actions, one of which will be done
if (condition) statement1 else statement2
76Summary
- Syntax of the Java language permits only a single
statement as a conditional alternative. - Need a way to package a number of statements into
one. - Compound statement put braces around a sequence
of statements
statement1 statement2 statementn
77Summary
- Boolean expression an expression that evaluates
to a boolean value, true or false. - Several kinds of operators useful for
constructing boolean expressions - relational operators lt, lt, gt, and gt,
- equality operators and !,
- boolean operators , , and !.
78Summary
- introduced preconditions, postconditions, and
invariants. - Important in the specification and correctness
verification of our designs. - Not part of the language per se, we include them
in comments.
79Summary
- Client of a method responsible for making sure
that all method preconditions are satisfied
before invoking method. - Method will work correctly only if preconditions
are satisfied. - Preconditions are documented in a require clause
of method specification.
80Summary
- Method implementor is responsible for making sure
that all postconditions are satisfied when method
completes. - Postconditions documented in an ensure clause
of method specification.
81Summary
- Invariants are conditions that always hold.
- Class invariants are conditions that are always
true of all instances of a class. - A class instance is a consistent and coherent
model of whatever entity the class represents if
class invariants hold.