6 Chapter 6: Selection
SELECTION
Topics Covered:
- Decision making in Python
- Comparison operators
- Boolean expressions
- Else and elif statements
- Nested if-else blocks
Decision Making in Python
In order to allow a computer to handle different data values in different ways, programming languages need to provide some type of decision‑making capabilities. In Python, the simplest form of decision‑making capability is provided by the if statement, which has the following format:
if Condition:
Action
In this prototype, Condition stands for any expression that can be evaluated to either True or False. Most often, the Condition is a simple comparison. In Python, you can use the following comparison operators:
Operator Meaning Example
== is equal to A == B
< is less than A < B
> is greater than A > B
!= is not equal to A != B
<= is less than or equal to A <= B
>= is greater than or equal to A >= B
These operators should be self‑explanatory. You need to be careful, though, when comparing fractional values, since equality rarely holds between two fractional variables or expressions. This is because fractional values are approximated in the computer. When a series of arithmetic operations is performed using approximated values, it is almost inevitable that these values will undergo a significant amount of round-off in the final decimal places. Here are a couple of examples of conditions, or Boolean expressions, evaluated in the Python Interactive window:
The Action component of the if statement is the instruction, or series of instructions, to be carried out if the condition is True. If more than one instruction is to be carried out, the whole series of instructions should be indented at the same level. This tells the computer to treat the entire group of instructions, commonly referred to as a block, as a single unit. Python’s Idle environment assists you by automatically indenting when you type a colon at the end of a line.
To illustrate, the following are examples of legal if statements in Python:
if hoursWorked <= 40:
grossPay = rate * hours
if prevID != currID:
idCount = idCount + 1
prevID = currID
In the first example, the variable hoursWorked is compared to 40; if it is less than or equal to 40, the value of grossPay is computed by multiplying rate by hours.
In the second example, the variables currID and prevID are compared. It’s assumed that these are both numeric variables. If the values don’t match exactly, then two actions are carried out. First, 1 is added to the variable idCount; presumably, the program is going to count how many distinct identification numbers are processed. Second, the value of the variable currID is being copied into the variable prevID.
It is worth emphasizing here just how important the indentation of blocks is with Python. Most languages use either keywords, such as begin/end, or curly brackets { }, to indicate blocks of code. The white space (space, tab, new line) in these languages is ignored. For a block to work in Python, the indenting for each instruction has to be created using the same keystrokes. For example, you cannot use the TAB key on the first line of the block and then consecutive spaces on the second line, even if they appear to visually align vertically.
The standard comparison operators (<, <=, >, >=, ==, and !=) can be used to compare strings, as well as for comparing numeric values. You should be aware, though, that string comparison is case sensitive. The ASCII values of characters are used when comparisons are made between two strings. Here are some examples:
In the first example, “fish” is less than “turkey” because the ASCII value of “f” (102) is less than that of “t” (116). A “d” has a value (100) greater than that of “c” (99), so “dog” is not less than “cat”. When strings begin with the same character, the comparison moves on to succeeding characters until characters in the two strings differ. The string “twinkie” is less than “twister” since the fourth character “n” had an ASCII value (110) less than that of “s” (115). Finally, upper case letters have smaller ASCII values than lower case letters. The string “cat” is not less than “Cat” because the “c” has a value of 99 and the “C” has a value of 67. Since 99 is not less than 67, the expression “cat”<“Cat” returns False.
The bool Data Type
In some cases, it’s handy to be able to remember if something has, or hasn’t, occurred. One way to do this is to set a special “marker” value in some variable. For example, the variable flag, of type int, might be initially set to 0, but then changed to 1 if some special event takes place. The test:
if flag == 1:
could then be used to see if the event has taken place. Of course, it’s important for the programmer to remember if the value 1 stands for “yes” or “no” within the program, which may not be easy. A better way is to use a more descriptive variable name, and give that variable the type bool, which stands for True or False. Typically, the bool variable might be set to False to indicate that an awaited event hasn’t yet taken place, and then subsequently changed to True after the event does occur. For example, the variable buttonPressed might be used to indicate that a mouse button has been pressed. When the button is pressed, buttonPressed could be set to True, while a release of the button would cause the value to be changed to False.
To test the variable, it is sufficient to say:
if buttonPressed:
instead of:
if buttonPressed == true:
While this may seem like a minor difference, it does improve the overall readability of the program.
The if – else Statement
Often, a programmer has to choose between two alternate actions, depending on the result of a comparison. For example, the task of figuring an hourly employee’s gross pay, when overtime is paid for hours in excess of 40, might be programmed as:
if hoursWorked <= 40:
grossPay = hoursWorked * hourlyRate
if hoursWorked > 40:
grossPay = hourlyRate*40 + 1.5*hourlyRate*(hoursWorked–40)
Can you guess what would happen if the programmer accidentally wrote the first comparison as hoursWorked < 40? If you think about it, you’ll realize that this could be a serious error ‑ grossPay won’t be computed for workers with exactly 40 hours. Sadly, this type of problem arises far more frequently than you might imagine. In some circumstances, Python is able to tell you that you have a potential problem. If the variable grossPay in the above example hadn’t been given an initial value before the if statements are encountered, the Python interpreter will trigger an error since the variable wasn’t initialized. But if the value of grossPay had already been computed for a previous employee, then this employee would end up receiving the same gross pay!
In addition to this being a nasty error condition waiting to happen, the redundant comparison of hoursWorked to 40 is also at least a little troubling; it just doesn’t seem necessary. To simplify this type of situation, most programming languages allow another form of the if statement, usually called the if ‑ else. Using Python’s version of this instruction, the above sequence could be written as:
if hoursWorked <= 40:
grossPay = hoursWorked * hourlyRate
else:
grossPay = hourlyRate*40 + 1.5*hourlyRate*(hoursWorked–40)
Whenever the keyword else is encountered, it is automatically associated with the most recent if. Perhaps the simplest way to understand its use is to think of it like this:
If some condition is true,
here’s what I want you to do.
But if that condition is false,
I want you to do this, instead.
As with the simple if statement, multiple actions are specified by indenting those instructions to the same level. For example, if a company’s payroll required regular and overtime pay to be calculated separately, it might be done like this:
if hoursWorked <= 40:
regularPay = hoursWorked * hourlyRate
overtimePay = 0
else:
regularPay = 40 * hourlyRate
overtimePay = 1.5 * hourlyRate * (hoursWorked – 40)
As you model the decision-making process using a flowchart, whenever a condition occurs, you should include that condition inside of a diamond. Two arrows will exit the diamond, one designating the path if the condition is True; the other path when the condition is False. Below are flowcharts modeling an if statement and an if-else statement.
General Programming Constructs
No matter which programming language you are using to solve a problem, there are three general computer programming constructs that are required:
- Sequence – the computer will execute one instruction after the next.
- Selection – this is the decision-making process using if or if-else statements.
- Repetition – creating a loop. We will study this in chapter 7.
Suppose the local bagel shop asked you to write a simple program to compute the charge for each customer’s purchase. Bagels normally cost 75 cents each, but if you buy a half-dozen or more, then the charge is 60 cents per bagel. Of course, once we learn the quantity, a decision needs to be made. Our newly acquired if-else statement would be perfect here:
# Program to compute charge for bagel sale
# Written by XXX XXXXX
# CS101 – Introduction to Computer Programming
# Date: XX/XX/XXXX
quantity = int(input(“How many bagels do you want? “))
if quantity<6:
charge = .75 * quantity
else:
charge = .60 * quantity
print(“Total charge is”, charge)
Compound Conditional Expressions
In many cases, it’s necessary to consider multiple conditions to decide if some action should or should not be performed. In some cases, two or more conditions must be true; in other cases, at least one condition, from a list of possible conditions, must be satisfied. In these situations, you can combine individual comparisons in a single expression. For example, a salesperson might be due to receive a bonus if he or she has at least 20 customers, and accounts for at least $10,000 in sales. Or maybe a student will receive an F in a class if his or her test average is below 60, or if he or she has more than 10 unexcused absences.
The key words in these two examples are “and” and “or.” When two or more conditions are joined with the word “and,” it implies that ALL of the conditions must be satisfied in order for the entire expression to be considered true. In contrast, the word “or” implies that AT LEAST ONE of the specified conditions must be satisfied to obtain a result of true.
The salesperson example from above might be represented in Python like this:
if numCustomers >= 20 and totalSales >= 10000:
…
while the student example might instead be expressed like this:
if testAvg < 60 or absences >= 10:
…
While less common, it’s sometimes necessary to mix “and” and “or” conditions in a single expression. Python has default rules for interpreting these expressions, but it’s probably best to instead use parentheses to explicitly dictate the order in which the individual expressions should be combined.
Although not required, you can add parentheses, which many people find to be more readable:
if (testAvg < 60) or (absences >= 10) :
or even:
if ((testAvg < 60) or (absences >= 10)) :
Finally, in some contexts, it’s desirable to perform some action if some condition or conditions are NOT met. Typically, the word not is placed outside of a parenthesized expression. For example, you could check to see if a salesperson is not eligible for a bonus like this:
if not (numCustomers >= 20 and totalSales >= 10000):
…
An easier way to ask this same question, though, might be to ask:
if numCustomers < 20 or totalSales < 10000:
…
Nested if Statements
Whenever one or both of the actions associated with an if – else instruction contains another if statement, the resulting form is referred to as a nested if. The nested form arises naturally in contexts where a choice must be made between several different options. To illustrate, consider the following scenario.
To receive a grade of A, a student’s average must be at least 90. A B will be assigned if the average is at least 80, but less than 90, while a C is assigned for a grade of at least 70, but less than 80. For an average of 60 or higher, but less than 70, the letter grade is D, while an average below 60 leads to a grade of F.
Using only if statements, this grade assignment problem could be programmed like this:
if average >= 90:
grade = ‘A’
if average >= 80 and average < 90:
grade = ‘B’
if average >= 70 and average < 80:
grade = ‘C’
if average >= 60 and average < 70:
grade = ‘D’
if average < 60:
grade = ‘F’
While this sequence will certainly do the trick, it requires several redundant comparisons, and also contains a number of potential trouble spots, where either numbers or comparison operators could easily be messed up.
An alternate form, which significantly reduces the number of comparisons required, is the following:
grade = ‘A’
if average < 90:
grade = ‘B’
if average < 80:
grade = ‘C’
if average < 70:
grade = ‘D’
if average < 60:
grade = ‘F’
While this form is clearly shorter, it’s far more difficult to understand, because it relies on a trick. Every student is initially assigned an A, and then their grades are reassigned as each new test shows their average to be lower. Often, programmers forget that other people need to be able to understand their programs, too, and will rely on tricks that, while the trick they came up with might be obvious to them, it might not be obvious to others.
The elif statement
When you have an if statement immediately following an else section, Python provides elif, which combines the two statements. A cleaner version of the grade checker, which takes advantage of the elif statement to assign a grade to each student exactly once, would be:
The comments on the right clarify why this form works. When an if statement follows an else, it can rely on the fact that the condition associated with the preceding if is already known to be False. This characteristic is shown in most well written nested if blocks – the secondary if statements are placed so they follow an else, thereby ensuring that the earlier if condition is already known to be False.
Whatever you do, don’t place the if within the if portion, as illustrated below:
While this form will, in fact, work properly, it’s a rare person who could figure it out on the first try!
INTERACTIVE – Can you debug it?
The program below asks the user to enter a number. It will then display whether the input number is positive, negative, or zero. The only problem, though, is that the code contains three errors. Can you fix it?
Let’s take a look at a complete program that will need selection to work. The program will process a savings-account withdrawal. It should ask the user for their current balance and the amount of the withdrawal. If the transaction was successful, it should display the customer’s new balance. If the balance wasn’t large enough to handle the withdrawal, the program should output “Transaction denied”. If the new balance is less than $100, then “Balance below $100” should be printed.
Before we tackle the code, we can model the solution to this problem using the following flowchart:
As you observe from the flowchart, there are two triangles, or decisions, involved. The first is an if-else statement that checks to see if the customer has sufficient funds for the withdrawal. The second decision is an if-statement checking to see if the customer’s balance if below $100. The Python solution looks like this:
Chapter Review Exercises:
6.1. Given the following Python instructions:
a = 12
b = 12
c = 8
What is the value of the following condition (True or False)?
a != b
6.2. Given the following Python instructions:
a = 12
b = 12
c = 8
What is the value of the following condition (True or False)?
a < b and b > c
6.3. Given the following Python instructions:
a = 12
b = 12
c = 8
What is the value of the following condition (True or False)?
a < b and b > c
6.4. Show the output if the following Python instructions were executed:
a = 4
b = 5
c = 13
if a+b < 10:
print(c)
else:
print(a)
6.5. Show the output if the following Python instructions were executed:
miles = 10
if miles<20:
price = 5 + .30*miles
else:
price = 2 + (20-miles)*.10
print(price)
Programming Projects:
6.1. Write a program that will ask for the name and age of two people. The program should then display a message saying either “X is older than Y”, “X is younger Y”, or “X is the same age as Y” (assuming the first person has name X and the second person has name Y).
6.2. Leo’s Print Shoppe charges 8 cents per copy for the first 50 copies and 5 cents per copy for the copies beyond the first 50. Write a Python program that asks for the customer’s name and how many copies they need. Your program should output the customer’s name and the total cost (using a dollar sign and 2 decimal places).
- Write an algorithm to solve the problem. Save it as a Word document.
- Write a flowchart to model the solution to the problem. Save it as a PDF document.
- Implement the solution to your problem as a Python program. Add at least 4 lines of comments at the top.