CIS 2020 · Python for Everyone · Module 5 · Study guide

Module 5 review: decisions, sections 3.1 to 3.4

Chapter 3 opens with the first statement that lets a program choose between paths: the if statement. This module covers its two parts, the relational operators that build its condition, the if/else form, chaining several alternatives together, and nesting one decision inside another.

Section 3.1

The if statement

A statement that runs one block of code only when a condition holds, and skips it otherwise.

A decision statement (also called a branch) is a statement that executes different code depending on whether a condition is true or false. In Python, the statement that implements a decision is the if statement.

An if statement has two parts: the condition, a boolean expression that evaluates to True or False, and the body (or block), the indented statement or statements that run only when the condition is True. If the condition is False, the body is skipped entirely and execution continues with whatever comes after it.

if y > 300 :
    x = y
print("done")

Syntax

The header line starts with if, followed by the condition, and must end with a colon. Every statement in the body must be indented by the same amount; Python uses that indentation, not braces or keywords, to mark where the body begins and ends.

Two syntax errors show up constantly with if: leaving off the trailing colon, and forgetting to indent the body (or indenting it inconsistently). Either one is caught before the program runs, as a SyntaxError or IndentationError.

cost = int(input("Enter the cost: "))
if cost > 100          # missing colon -- SyntaxError
    cost = cost - 10
print("Discounted cost:", cost)

Comparing values: relational operators

A condition is usually built with a relational operator (also called a comparison operator), which compares two values and produces True or False.

The six relational operators.
OperatorMeaning
==equal to
!=not equal to
<less than
>greater than
<=less than or equal to
>=greater than or equal to
print(5 == 5)   # True
print(5 != 5)   # False
print(3 <= 3)   # True -- <= is a relational operator
print(7 >= 4)   # True -- >= means greater than or equal to

Do not confuse == with =. A single = is the assignment operator; it stores a value and cannot appear inside a condition. Writing if count = max : is a SyntaxError for exactly this reason — the condition needs the two-character comparison == to ask whether count and max are equal.

Negating a condition

The opposite (or negation) of a condition is the one that is true in exactly the cases where the original is false. Each relational operator has a direct opposite:

Every relational operator paired with its opposite.
OperatorOpposite
==!=
<>=
><=

So the opposite of count > 10 is count <= 10, not count < 10 — the boundary value, 10 itself, has to land on one side or the other, and negating > flips it to <=, never to the strict <.

count = 10
print(count > 10)     # False
print(count <= 10)    # True -- the opposite condition

Section 3.2

The if/else statement

A second block that runs only when the condition is false, so the statement always takes exactly one of the two paths.

An if/else statement adds an else clause: a second body that executes when the condition is False. Exactly one of the two bodies runs on any given pass through the statement, never both and never neither.

The if block itself is never optional; the else block is. Every plain if statement in Section 3.1, with no else at all, is already valid on its own. Adding else is a choice you make when there is a second path worth handling, not a requirement.

y = int(input("Please enter a number: "))
if y > 300 :
    x = y
else :
    x = 0
print("x:", x)

Both the if body and the else body are examples of a compound statement (or block): a group of one or more statements, all indented to the same level, that are treated as a single unit and run together.

itemCount = 10
cost = 80
if itemCount > 5 :
    discount = 0.8
    totalCost = cost * discount
    print("Total discounted price is:", totalCost)
# itemCount > 5 is True, so all three lines in the block run:
# Total discounted price is: 64.0

Both branches need their own colon and their own consistent indentation. Writing the header lines correctly but leaving the bodies unindented is a common mistake:

if y > 300 :
x = y          # IndentationError -- not indented under the if
else :
x = 0
print("x:", x)

Tracing an if/else statement

To trace a decision statement, evaluate the condition first, then run only the body that matches. Nothing else in the statement executes.

y = int(input("Please enter a number: "))   # user enters 303
if y > 300 :          # 303 > 300 is True
    x = y             # x becomes 303
else :
    x = 0
print("x:", x)        # output: x: 303
cost = 100
if cost > 150 :
    discount = 0.8 * cost
else :
    discount = cost   # cost > 150 is False, so this line runs
print("Your cost is:", discount)   # output: Your cost is: 100
count = -1
x = 4
if count > 0 :        # -1 > 0 is False, body is skipped
    x = x + 1
print(x)               # output: 4, unchanged
numPizzas = 1
numPeople = 4
if numPeople == 5 :    # 4 == 5 is False, body is skipped
    numPizzas = 2
# numPizzas is still 1 after this code runs

If the condition is false and there is no else, nothing happens — the variables involved keep whatever value they already had. That is exactly what happens in the last two traces above: with no path taken, x and numPizzas are left exactly as they started.

Section 3.3

Multiple alternatives

Chaining conditions together to choose among more than two paths.

An elif clause (short for "else if") lets an if statement test a second condition when the first one is false, and a chain can hold as many elif clauses as needed, with an optional final else to catch everything else. Python checks the conditions in order and runs the body of the first one that is true; every condition after that is skipped, even if it would also have been true.

score = 82
if score >= 90 :
    grade = "A"
elif score >= 80 :
    grade = "B"
elif score >= 70 :
    grade = "C"
else :
    grade = "F"
print(grade)   # B -- the first true condition wins

Order matters. If the conditions above were written from lowest to highest (score >= 70 first), a score of 82 would match that first, looser condition and incorrectly come out as "C". Chained alternatives that overlap must be ordered from most specific to least specific.

Section 3.4

Nested branches

An if statement written entirely inside the body of another one.

A nested branch is an if (or if/else) statement placed inside the body of another if or else. The inner statement only runs at all if the outer condition let control reach that far, so its condition is really being asked relative to the outer one already having been true.

age = 20
hasLicense = True

if age >= 16 :
    if hasLicense :
        print("Can drive")
    else :
        print("Needs a license first")
else :
    print("Too young to drive")

This differs from chaining the same two checks with elif: an elif chain picks exactly one branch from a flat list of alternatives, while nesting expresses that the second question only makes sense once the first has already been answered a particular way.

Indentation depth tracks nesting depth. Each level of nesting adds one more level of indentation; a nested body that drifts back to the outer statement's indentation level is no longer considered part of the inner if.

Quick check

If you remember only these

  • A decision statement runs different code depending on a condition. In Python, that is the if statement.
  • An if statement has two parts: the condition and the body. The body runs only when the condition is True.
  • Every if, elif, and else header ends with a colon, and its body must be indented consistently. Missing either is a syntax or indentation error.
  • == tests equality inside a condition; = assigns a value and cannot be used there. if count = max : is a SyntaxError.
  • The relational operators are ==, !=, <, >, <=, and >=. >= means greater than or equal to; <= is itself a relational operator, not a special case of one.
  • The opposite of > is <= (not <), and the opposite of < is >= — the boundary value must land somewhere.
  • An if/else statement always takes exactly one branch. If the condition is false and there is no matching branch, variables simply keep their prior values.
  • A group of indented statements running together as one unit is a compound statement, or block.
  • elif chains are checked in order top to bottom; only the first true condition's body runs, so overlapping conditions must go from most specific to least specific.
  • Nesting one if inside another means the inner condition is only reached, and only means anything, once the outer condition has already been satisfied.