# CS134 Conditionals and Modules¶

In this lecture, we will continue our discussion of conditionals in Python.

Last lecture, we looked at some simple `if-else` conditional statements. Note that the `else` block is optional.

Today we will discuss the logical operators `and`, `or`, and `not` in Python to construct more complicated Boolean expressions, in addition to nested conditionals.

## Logical operators: `and`, `or`, `not`¶

The logical operators `and`, `or` and `not` in Python are used to combine Boolean values and write more complex Booleans expressions.

### `and`¶

boolExp1 and boolExp2 evaluates to `True` iff both boolExp1 and boolExp2 evaluate to `True`.

### `or`¶

boolExp1 or bool Exp2 evaluates to `True` iff at least one of boolExp1 and boolExp2 evaluate to `True`.

### `not`¶

not boolExp evaluates to True iff boolExp evaluates to False.

Let us try these out.

```20 < 13 and 6 == 6
```
```False
```
```20 < 13 or 6 == 6
```
```True
```
```result = (6 == 6)
```
```result
```
```True
```
```not 20 < 13
```
```True
```
```not 6 == 6
```
```False
```
```result = (6 == 6)
# result = True
# Note: no need to test for == True in expression
if (result):
print("true!")
```
```true!
```

Example 1. Check if a number is divisible by 5 and is odd.

```def oddMultipleFive(num):
"Returns true if num is divisible by 5 and odd"
return num % 5 == 0 and num % 2 == 1
```
```oddMultipleFive(55)
```
```True
```
```oddMultipleFive(80)
```
```False
```

Example 2. Ask the user to enter a lowercase letter. Check if it is a vowel or consonant.

```def isVowel(letter):
"""Takes lowercase letter as input and returns
True if it is a vowel, else returns False"""
# can do an if else or since we are
# returning the truth value of expression,
# can directly return

# this does not work because "e", "i", "o", and "u" are not boolean expressions
# return letter == "a" or "e" or "i" or "o" or "u"

return letter == 'a' or letter == 'e' or letter == 'i' or letter == 'o' or letter == 'u'
```
```isVowel('b')
```
```False
```
```isVowel('a')
```
```True
```
```isVowel('z')
```
```False
```

Some takeways.

• We can chain together a bunch of boolean expressions (not just two).

• It does not make sense, however, to write `letter == 'a' or 'e' or 'i' or 'o' 'u'`: logical operators take `bool` type operands, not strings.

Example 3. Write a function `divide` that takes two numbers `num1` and `num2` as input, and returns the result of `num1/num2` as long as `num2` is not zero. If `num2` is zero, print “Cannot divide by zero” and return None.

```def divide(num1, num2):
if not (num2 == 0):  # can also write num2 != 0
return num1/num2
else:
print("Cannot divide by Zero")
# do we need to say anything after this?
# if we get here we will implicitly return None
```
```divide(7, 3)
```
```2.3333333333333335
```
```divide(9, 0)
```
```Cannot divide by Zero
```

## Nested Conditionals¶

Sometimes, we may encounter a more complicated conditional structure. Consider the following example.

Write a function `weather` that takes as input a temperature `temp` value in Fahrenheit.

• If temp is above 80, print “It is a hot one out there.”

• If temp is between 60 and 80, print “Nice day out, enjoy!”

• If temp is below 60 and above 40, print “Chilly day, wear a sweater.”

• If temp is below 40, print “Its freezing out, bring a winter coat!”

Question. How can we organize this using if-else statements?

### Attempt 1: Nested If Else¶

Does the following work?

```def weather1(temp):
if temp > 80:
print("It is a hot one out there.")
else:
if temp >= 60:
print("Nice day out, enjoy!")
else:
if temp >= 40:
print("Chilly day, wear a sweater.")
else:
print("Its freezing out, bring a winter coat!")
```
```weather1(89)
```
```It is a hot one out there.
```
```weather1(72)
```
```Nice day out, enjoy!
```
```weather1(55)
```
```Chilly day, wear a sweater.
```
```weather1(33)
```
```Its freezing out, bring a winter coat!
```

### Attempt 2: Only Ifs¶

The above function is hard to read with so many indented blocks. What if we used only `if`s? What is the trade off?

```def weather2(temp):
if temp > 80:
print("It is a hot one out there.")
if temp >= 60 and temp <= 80:
print("Nice day out, enjoy!")
if temp <60 and temp >= 40:
print("Chilly day, wear a sweater")
if temp < 40:
print("Its freezing out, bring a winter coat!")
```
```weather2(89)
```
```It is a hot one out there.
```
```weather2(72)
```
```Nice day out, enjoy!
```
```weather2(55)
```
```Chilly day, wear a sweater
```
```weather2(33)
```
```Its freezing out, bring a winter coat!
```

### Class Discussion¶

• What is the difference between Attempt 1 and Attempt 2? Can we trace the control flow through each?

• What are the pros, cons of each attempt?

## Chained `if, elif, else` Conditionals¶

If we only need to execute one out of several conditional branches, we can use chained (or multi-branch) conditionals with `if`, `elif`, and `else` to execute exactly one of several branches.

### If Else Statement Syntax¶

`if` (boolean expression a):
statement 1
…
`elif` (boolean epression b):
statement 2
…
`else`:
statement 3
statement 4

• If bool expression a is True: only statement 1 and 4 are executed, regardless of the boolean exp b

• If bool expression a is False and b is True: only statement 2 and 4 are executed

• If bool expression a and b are both False: only statement 3 and 4 are executed

```def weather3(temp):
if temp > 80:
print("It is a hot one out there.")
elif temp >= 60:
print("Nice day out, enjoy!")
elif temp >= 40:
print("Chilly day, wear a sweater.")
else:
print("Its freezing out, bring a winter coat!")
```
```weather3(89)
```
```It is a hot one out there.
```
```weather3(72)
```
```Nice day out, enjoy!
```
```weather3(55)
```
```Chilly day, wear a sweater.
```
```weather3(33)
```
```Its freezing out, bring a winter coat!
```

### Takeway¶

• Chained conditionals can avoid having to nest conditionals, which improves readability

• Since only one of the branches in a chained `if, elif, else` conditional evaluates to `True`, using them avoids unnecessary checks incurred by chaining `if` statements one after the other.