Boolean Expressions: Boolean • The Boolean data type was discussed earlier – It has only two values: True and false – But - as discussed at that time - almost any value of any other data type can represent true or false ∗ False is represented by the /empty/zero value of other data types: 0, 0.0, ”” (the empty string), [ ] (the empty list), etc. ∗ True is represented by the non-null/non-empty/non-zero values

1 Boolean Expressions: Boolean Operators • Return a Boolean value • Types: – Relational operators ∗ Operators: 1. == (equivalent to) 2. != (not equal) 3. < 4. > 5. <= 6. >= ∗ See earlier precedence/associativity table – Logical operators 1. and (logical and) 2. or (logical or) 3. not (logical not) ∗ Arguments must be boolean ∗ Values represented by truth tables: Graphical way of expressing value of boolean expression

A B A and B A or B not A true true true true false true false false true false false true false true true false false false false true

– Object comparison operators 1. is (same object) 2. is not (not same object) – See earlier precedence/associativity table

2 Boolean Expressions: Expressions

• Short-circuit (lazy) evaluation – Given a logical expression, Python will stop evaluation as soon as the result is known – For example: If A is false in A and B, B will not be evaluated – Similarly, for A or B, if A is true – This is convenient for situations like if ((x != 0) and (y / x > 10)) ...

– Of special note: and and or return the value of the last expression evaluated: >>>1 and 0 0 >>>0 and 1 0 >>>1 and 2 2

• DeMorgan’s Laws – not (A and B) ≡ not A or not B – not (A or B) ≡ not A and not B • Boolean variables – Often have names like is done, is zero, is valid

3 Boolean Expressions: Cautions • English does not translate directly to Boolean expressions – ”If the value is 4 or 5, ....” – Wrong: x == 4 or 5 ... – Right: (x == 4) or (x == 5) • Do not compare floats for equality – Consider 1.11 - 1.10 and 2.11 - 2.10 ∗ Algebraically they should both equal 0.01, but computationally? – Rather than comparing floats for equality, it is better to see if their differ- ence is within some small range – Wrong: x == 0.50000 – Right: math.abs(x − 0.50000) < 0.000001 • Consider the English statement ”x is between 10 and 20” – This could be written as (x > 10) and (x < 20) – Python allows this to be written more conveniently the same way as it would be algebraically: 10 < x < 20 • Knowing the precedence and associativity rules lets you write 0 <= x and y >= z knowing that the two relational expressions will be evaluated first, then the and – Many programmers prefer to use parens even in situations like this for clar- ity (0 <= x) and (y >= z)

4 Boolean Expressions: Equivalence v Same Objects • There is a subtle distinction between equivalence (==) and using Boolean operators is and is not • Consider

>>>5 == 5 True >>>5.3 == 5.3 True >>>5 + 2j == 5 + 2j True >>>"abc" == "abc" True >>>[1, 2, 3] == [1, 2, 3] True >>>(1, 2, 3) == (1, 2, 3) True

– Equivalence returns True if its arguments have the same value • But now consider

>>>5 is 5 True >>>5.3 is 5.3 True >>>5 + 2j is 5 + 2j True >>>"abc" is "abc" True >>>[1, 2, 3] is [1, 2, 3] False >>>(1, 2, 3) is (1, 2, 3) False

5 Boolean Expressions: Equivalence v Same Objects (2)

• The reason for the difference has to do with how the values are stored in memory – is returns True if its arguments point to the same location – In the case of the comparison of scalar values (and strings), all references are to the same location – In the case of the comparison of collections, each value is at a different location – But when one variable is assigned to another, they end up pointing to the same location

6 Boolean Expressions: Equivalence v Same Objects (3)

• Even more confusingly

>>>x = 5 >>>y = 5 >>>x is y True >>>x = 5.3 >>>y = 5.3 >>>x is y False

• When variables are assigned, – Unique int values are stored in the same location – Unique float values are not

7