← Back to the Introduction to Computer Science outline The Course Maker
← Introduction to Computer Science outline
Week 4 · Lecture

Lecture: Booleans & Conditionals

Introduction to Computer Science Free sample edition

Lecture script · about 15–20 minutes spoken · Week 4

Opening

Picture a thermostat set to 18 degrees. It reads the room at 17, and the heat clicks on. Nobody told it to do that at that moment. It asked itself one question, "is the room colder than 18?", got the answer yes, and picked the path that goes with yes.

That kind of question runs through a lot of work you might do. A pharmacy technician checks that a dose sits inside a safe range. A store clerk's register decides whether a purchase earns free shipping. Your phone decides whether to show a low-battery warning. Each one is a yes-or-no test, and the order of the tests decides what happens next.

In Week 1, you learned to predict, then run, and to read an error from its last line. In Week 2, you met the bool type and its two values, True and False, and I warned you that the single equals sign and the double equals sign are different. In Week 3, you read input as a string and built output with f-strings.

In this lecture, your programs start making choices. We ask questions with comparisons, join them with and, or, and not, and work out a mixed question in Python's order. Then we let the answers choose which lines run, meet the two classic bugs, and check a chatbot's claim with a run. Next, in Week 5, Loops I: The while Loop, a question decides whether a block runs again.

1. Ask a yes-or-no question: comparison operators

Think about a clerk checking the age on an ID card. The clerk isn't doing arithmetic. The clerk asks one question, "is this at least 18?", and the only answers are yes and no.

A Boolean expression is an expression that Python works out to one of the two bool values, True or False, such as pages_read greater than or equal to goal. You build most of them with a comparison operator, one of the six operators that compare two values and give True or False. In words, they ask: is equal to, is not equal to, is less than, is greater than, is less than or equal to, and is greater than or equal to.

One of them gets its own name. The equality operator is the double equals sign, which asks whether two values are equal and gives True or False, unlike the single equals sign, which gives a name a value. I'd like you to say them differently out loud. The single equals sign is "gets." The double equals sign is "is equal to."

Let's ask the reading log some questions. The goal is 300 pages, and you've read 45. First question: is pages_read greater than or equal to goal? Is 45 at least 300? No, so Python prints False. Second question: is pages_read equal to 45? Yes, so it prints True. Third question: is pages_read not equal to 45? That's False. Notice that none of those questions changed a value. A comparison only answers.

Python compares values, not the way they look. The whole number 3 and the decimal number 3.0 hold the same value, so asking whether they're equal gives True. But the character 3 inside quotation marks is text, and text is never equal to a number. That comparison gives False. Run the pinned line that asks both questions, and it prints True, then False.

Pause and try this. The thermostat program stores a temperature of 17. Does the question "is temperature less than 18" come out True or False, and did the question change the temperature?

Say the comparison in words before you decide.

Here's the answer. It comes out True, because 17 is less than 18. The temperature is still 17, since a comparison asks about a value and never changes it.

So the single equals sign gets a value, and the double one asks a question.

2. Combine questions: and, or, not, and truth tables

Real decisions often join two questions. A bike-share app unlocks a bike only if you have a pass and the dock has a free bike. Python has three words for joining questions like that.

A logical operator is one of the three words and, or, and not, which combine or flip Boolean values to build a bigger condition. And is the logical operator that gives True only when the conditions on both of its sides are True. Or is the logical operator that gives True when at least one of its sides is True, and False only when both sides are False. Not is the logical operator that flips one Boolean value, so not True is False and not False is True.

Here's the bike-share story. You have a pass, so has_pass is True. But the dock shows 0 free bikes, so the question "are bikes free greater than 0?" is False. Join them with and, and you get False: one false side is enough to sink an and, so no bike unlocks. Join the same two with or, and you get True, because one true side is enough for an or. And not has_pass flips True to False.

You can list every possible case in a grid. A truth table is a table that lists every combination of True and False for its inputs, one row each, beside the value an expression gives on that row. This course always lists the rows in one order: True True, then True False, then False True, then False False.

Rather than fill that table from memory, the course lets Python print it. Here is what the pinned program printed, row by row, reading a, then b, then a and b, then a or b. Row one: True, True, True, True. Row two: True, False, False, True. Row three: False, True, False, True. Row four: False, False, False, False.

Read down the and column, and it's True on the first row only. Read down the or column, and it's False on the last row only.

Pause and try this. On row one, both inputs are True. Many people expect or to give False there, because in conversation "soup or salad" means one or the other. What does Python's or give on row one?

Check the table, not your ear.

Here's the answer. It gives True. Python's or is False only when both sides are False, so two true sides still make it True.

So and needs both, or needs either, and not flips one.

3. Work out a mixed condition in Python's order

Here's a recipe line that leaves you guessing: "add salt or pepper and lemon." Is the lemon always in, or only with the pepper? English doesn't say. Python never leaves that open. It has a fixed order for its logical operators, the same way it has a fixed order for arithmetic.

The order is not, then and, then or. All three come after the comparisons, which come after the arithmetic. So in "has_pass and bikes free greater than 0," the comparison is worked out first, and the and comes after it.

Let's try the pinned one-liner: print True or False and False. Read it left to right, the way you'd read a sentence, and you'd say True or False is True, and True and False is False. But Python does the and first. False and False is False. That leaves True or False, which is True. Run it, and it prints True.

The same priority explains a second pinned program. It prints not a or b across the four rows, and the last column reads True, False, True, True. That's exactly what you get when not grabs only the a right next to it, then the or comes after. If not had flipped the whole of a or b, the very first row would have come out False, and it doesn't.

Parentheses change the order, the same way they do in arithmetic. Take not, followed by 3 greater than 2 in parentheses. Work inside out. 3 greater than 2 is True, so not of that is False.

When you're unsure, add parentheses that say what you mean, and run both versions.

Pause and try this. A chatbot reads True or False and False from left to right. Which operator does it work out first, and which one should it have worked out first?

Remember the order: not, then and, then or.

Here's the answer. The chatbot did the or first, but Python does the and first. That's why the chatbot lands on False while the run prints True.

So circle the and first, then the or.

4. Choose which code runs: if, elif, and else

Think about a pedestrian crossing. The light asks its questions in order. Is the button pressed? Then stop the cars. Otherwise, has the green run long enough? Then change. Otherwise, stay green. It never does two of those at once, and it always asks the first question first.

Python's tool for this is the if statement, a statement that runs its indented block only when its condition is True, and may carry elif and else branches below it. A condition is the Boolean expression after if or elif that Python tests to decide whether that branch's block runs. A branch is one of the alternative blocks of code in an if statement; Python runs at most one branch each time the statement runs.

Two more words finish the picture. Elif is a further test in an if statement, short for else if, that Python checks only when every test above it was False. Else is the last branch of an if statement, with no condition of its own, which runs only when every test above it was False. And a block is the lines indented four spaces under an if, elif, or else line, which run together as that branch's code. The indentation isn't decoration. It's how Python knows which lines belong to which branch.

Here's the reading log's Week 4 stage, in words. The goal is 300, and pages_read is 45. The if asks: is pages_read at least the goal? Is 45 at least 300? No, so skip that block. The elif asks: is pages_read at least goal floor-divided by 2? Floor division turns the goal into 150, so the test is 45 at least 150. No again, so skip that block too. Every test above the else was False, so the else runs and prints Keep going.

Now change one number. With pages_read set to 150, the if is still False, but the elif is True, because 150 is at least 150. It prints Halfway or better. With pages_read set to 300, the if is True, because 300 is at least 300. It prints Goal met, and Python never even looks at the elif, though 300 is also at least 150. That's the heart of this week. Once a branch runs, the rest of the chain is skipped.

Pause and try this. The pinned chain sets x to 7. Its if asks whether x is greater than 10, its elif asks whether x is greater than 5, and its else prints small. Which single word prints?

Trace from the top and stop at the first True.

Here's the answer. It prints medium. 7 isn't greater than 10, so the if is skipped, but 7 is greater than 5, so the elif runs and the chain ends there.

So test from the top; the first True wins, and the rest are skipped.

5. Find and fix the two classic conditional bugs

Think about two broken web forms. One won't submit because a box is blank, and at least it tells you. The other submits and quietly files your request under the wrong heading, and nothing warns you. Conditionals have one bug of each kind.

The first is the single equals sign where you meant the double one. A program sets x to 5, then writes "if x equals 5" with one equals sign. Python reads the whole program before running any of it, finds an instruction where a question belongs, and refuses. Nothing prints, not even from the first line. The last line of the error names SyntaxError, the same type you met in Week 1. The cure is one character: make it the double equals sign, and the program prints yes.

The second bug is quieter. A logic error is a mistake that lets the program run without any error message but makes it print the wrong thing, such as tests in the wrong order.

Here's the pinned example. A program turns a total of 95 into a letter. Its first test asks whether the total is at least 60, and if so it prints D or better. Its elif asks whether the total is at least 90, and if so it prints A. Run it with 95, and it prints D or better. Why? 95 passes the first test, that branch runs, and the chain ends. The at-least-90 test is never checked. The computer did exactly what was written, not what was meant. Put the at-least-90 test first, and the same 95 prints A.

A syntax error means nothing ran, so you read the error's last line. A logic error means the program ran, so you predict, run, and compare.

Pause and try this. In the out-of-order version, the program runs, no error appears, and it prints D or better for 95. Is that a syntax error or a logic error?

Ask yourself whether the program ran.

Here's the answer. It's a logic error. The program ran to the end and printed the wrong thing, and there was no error message to read.

So a syntax error stops the run, and a logic error runs and lies.

6. Check truthiness and a chatbot's claim with a run

Think about a sign-up form. It treats an empty box as "nothing entered" and any filled box as "something entered," whatever you typed. Python does something similar. Every value, not only True and False, counts as one or the other when it's used as a condition.

A value is truthy when bool turns it into True when it's used as a condition, such as any string with at least one character. A value is falsy when bool turns it into False when it's used as a condition, such as the empty string or the number 0.

The pinned line asks bool about two strings. The first is empty, two quotation marks with nothing between. The second holds one character, the digit zero. It prints False, then True. The empty string has no characters, so it's falsy. The string holding a zero has one character in it, so it's truthy. For a string, only emptiness counts as false; what's inside doesn't matter.

Now let's close the loop on that chatbot from earlier. You ask it what True or False and False prints. It answers False, and it explains its reasoning: left to right, True or False is True, then True and False is False. That sounds reasonable. Then you run it, and Python prints True. The chatbot's explanation contradicts what the code prints, because it skipped the priority not, then and, then or. The run caught it. The Python Tutorial's section 4.1, on the official documentation site, is where the if statement is written down if you'd like to read the rule for yourself.

Pause and try this. One string is empty. Another holds a single zero character. Which one is falsy, and why?

Count the characters in each string.

Here's the answer. The empty string is falsy, because it has no characters. The string holding a zero has one character, so it's truthy, even though zero itself sounds like nothing.

So the chatbot proposes, and the run decides.

Closing

Let's pull it together. A comparison asks a question and gives True or False, and the double equals sign asks while the single one gets. And needs both sides True, or needs either side, and not flips one, and a truth table lists the four rows in a fixed order. Python works out not, then and, then or, so circle the and before the or. An if, elif, and else chain runs only its first true branch, so the order of the tests is part of the program. A single equals sign in a condition is a SyntaxError, and tests in the wrong order are a logic error. And the empty string and 0 are falsy.

Next in this module come the slide deck, the Readings & Resources page, the lecture tutorial, the practice set, and the quiz, and after them the discussion, the assignment, and the Coding Lab. Next week, in Loops I: The while Loop, a condition like the ones in this lecture decides whether a block of code runs again.


Built with The Course Maker · samples.thecoursemaker.com