Overview
In this activity, we will practice with the Boolean data type, which allows us to reason about statements as true or false, and we will explore how to effectively use the if statement. An if statement is called conditionals because the actions taken are “conditional” on the value of the boolean expression in it. The conditional asks a question, or a series of questions, and it performs the set of actions associate with the first question that is true. The if statement syntax is more complex than the for loop:
Note: Complex statements in Python, like these, always have a first line that starts with the keyword that defines the statement (if) and the first line always ends with a colon (:).
A key distinction to remember: if statements select indented code to be executed one time, they do not loop.
Boolean data type
The boolean data type is a special one in most programming languages. A boolean value is either True or False:
these are constants in Python. Try typing them into the Python shell, without any quotation marks. Capitalization counts!
We use booleans to ask questions about data in a program, and to write programs that can choose among alternative actions.
Boolean expressions
We can ask questions using functions that return true/false answers, or with a set of boolean comparison operators. These form boolean expressions that evaluate to True or False. The most common boolean operators are shown in the table below.
A == B |
Is equal to takes two expressions, A and B, and evaluates to True if the value of A is equal to the value of B |
A != B |
Is not equal to takes two expressions, A and B, and evaluates to True if the value of A is not equal to the value of B |
A <= B |
Is less than or equal to takes two expressions, A and B, and evaluates to True if the value of A is less than or equal to the value of B |
A < B |
Is less than takes two expressions, A and B, and evaluates to True if the value of A is strictly less than the value of B |
A >= B |
Is greater than or equal to takes two expressions, A and B, and evaluates to True if the value of A is greater than or equal to the value of B |
A > B |
Is greater than takes two expressions, A and B, and evaluates to True if the value of A is greater than the value of B |
A in B |
Is in or Is an element of takes two expressions, A and B, and evaluates to True if the value of A occurs in the value of B * For strings this asks if A is a substring of B * For lists, this asks if A is an element of B |
A is B |
Is takes two expressions, A and B, and evaluates to
|
For each boolean expression, below, examine it and see if you can describe what question is being asked, and what the answer should be. Type each of the statements or expressions below in the Python console, or make a script file, where you print the value of each expression. Where you are wrong about the outcome, discuss with a neighbor, and ask for help!
# first we’ll assign three variables to values
x = 25
y = 30
s = 'boolean'
nums = [15, 20, 25, 30]
# now we’ll ask questions about them
print("x <=y is", x <= y)
print("y - 10 > nums[1] is", y - 10 > nums[1])
print("x % 2 == 0 is", x % 2 == 0, "(is x even)")
print("s > 'bodwaddle' is", s > 'bodwaddle')
print("len(s) == 7 is", len(s) == 7)
print("'e' in s is", 'e' in s)
print("'c' in s is", 'c' in s)
print("'boo' in s is", 'boo' in s)x <=y is True
y - 10 > nums[1] is False
x % 2 == 0 is False (is x even)
s > 'bodwaddle' is True
len(s) == 7 is True
'e' in s is True
'c' in s is False
'boo' in s is True
Try this to hand in: Copy the script above into a Python file, and add to it with this part. Write the following boolean expressions, using print to output the result (along with explanatory text):
- Ask if the difference between x and y is less than 10
- Ask if
"apple"is less than the variables - Ask if the variable
xis in the list[35, 20, -15, -25, 30] - Ask if the variable
yis less than 0 - Ask if the variable
yis greater than 100
Boolean logical operators
We can also put boolean expressions like the ones above together using the boolean logical operators: and, or, and not. The table below describes how these operators work.
A and B |
Evaluates to True if both the value of A and the value of B are True, otherwise it evaluates to False |
A or B |
Evaluates to True if at least one of A or B evaluates to True, otherwise it evaluates to False |
not A |
Evaluates to True if the value of A is False, and to False if the value of A is True |
Add the lines below to the script you started for the previous section. These depend on the variables defined earlier. Which of the following are True, and which False? Can you explain why each one produces the value it does? Discuss with a teammate, and ask if you are unsure.
Recall that the percent sign means to take the remainder of the first operand divided by the second operand. Also recall that the square bracket notation extracts single characters from a string based on position, where the first character is at position zero.
print("Are x and y multiples of 5? ", (x % 5 == 0) and (y % 5 == 0))
print("Does s start with b, or is it more than 10 long? ", (s[0] == 'b') or (len(s) >= 10))
print("Does s not contain the character i? ", 'i' not in s)
print("Is the 2nd character in s not an a? ", not (s[1] == 'a'))
print("Is x in nums, and y not? ", (x in nums) and not (y in nums))
print("Is x between 15 and 50, inclusive ", (x >= 15) and (x <= 50))Are x and y multiples of 5? True
Does s start with b, or is it more than 10 long? True
Does s not contain the character i? True
Is the 2nd character in s not an a? True
Is x in nums, and y not? False
Is x between 15 and 50, inclusive True
Try this to hand in: Save your answer for this activity into a new Python file. Practice with boolean expressions that have boolean operators here:
- Check if
xis less than 0 or greater than 100 - Check if either
'a'or'e'are ins - Check if both
xandyare less than 50 - Check if
numshas a length greater than 1, and (if so) if its zero-index element is less than its one-index element
Conditional statements
We often use boolean expressions in conditional statements, if statements, to cause the computer to choose one or another in a set of actions. The general form of an if statement is shown below. An if must have at least the first part, and has elif parts and an else optionally. Note that all the indented code options must be indented exactly the same amount.
Python evaluates each boolean expression in an if statement in order, stopping when it finds an expression that evaluates to True. It then performs the code associated with the true test, and then skips the rest of the conditional statement.
Look at the example below. Before typing it into an editor, try to figure out what it might print, given different values for x and y. Then put it in your Python file, and run it. Choose different values for x and y to cause different parts of the if statement to run. Explain your choices.
Conditionals and images
To practice with the conditional form, we are going to apply it to several tasks involving images, both displaying images and drawing on them.
User selecting images to show
Try this to hand in: By now you have probably had a typo in the name or path for an image you wanted to read in and display. OpenCV does not generate an error when it fails to read in an image, though it does print a warning, and the imread function returns the special Python value None. If a script has a hard-coded path to a file, we programmers can debug the program until we fix the path. But what if we want the user to select the image to read? Then we need to be more clever, and an if statement that checks what imread has returned is what we need. Do the following:
- Make a new script file, and at the top import
cv2 - Use the
inputfunction to ask the user to enter the name of a file inSampleImages(save their result to a variable) - Using string operations, add
SampleImages/to the front of the user’s string (be sure to save it to a variable) - Read in the image given by the string you have built, saving it to a variable
img - Use an
ifstatement to check whetherimgis an image or not:if img is None: - If this is true, in the indented section, print a message that the program couldn’t find the file, and then call the special
exit(0)function, which causes the program to end immediately - If the
iftest is false, then useimshowandwaitKeyto display the image the user entered.
Slideshow
Try this to hand in: If we combine an if statement and a for loop, we can write a program that displays a slideshow of all the images in a folder, in an efficient way. We will create a program that displays all the images in SampleImages, one by one. The user should type a key in the image window to move from one picture to the next.
We will use a function, listdir, from the os module to get a list of all the files and folders that are a part of the SampleImages folder. The function returns a list of strings. We will then loop over that list, and for each string, check if it has a filename extension of jpg or png. If so, we will read the image and display it, and it not, we will just go on to the next item in the list. Below are the steps to complete, in more detail.
Make a new Python file, and do the following:
- Start by importing
cv2and theosmodule - Use
os.listdir("SampleImages")to get a list of the files and folders inSampleImages. Save the returned value into a variable calledallFiles.- Before moving on, temporarily add a
printstatement, and print the value ofallFiles. Examine it, make sense of what the list contains, and make sure it is doing the right thing (ask for help if it isn’t)
- Before moving on, temporarily add a
- Next, write a
forloop that loops over the strings inallFiles: call the loop variablename.- Again, before moving on, temporarily add a print statement and print the loop variable. It should be a file or folder name from
SampleImages
- Again, before moving on, temporarily add a print statement and print the loop variable. It should be a file or folder name from
- Inside the loop, add an
ifstatement to check if the currentnameis an image file:- Use this string slicing to extract the last three characters:
name[-3:] - Use
orto perform two comparisons: Compare the sliced substring tojpg, and separately compare it topng
- Use this string slicing to extract the last three characters:
- If the test of the
ifisTrue, then:- Attach the folder name to the file name like this:
"SampleImages/" + name - Read in the image using the path string you created
- Display the image in the
"Slideshow"window - Wait for the user to type a key
- Attach the folder name to the file name like this:
Make sure that the if statement and all of its parts are indented inside the for loop.
Be sure to test your program all the way through to make sure it works for every image
Does the structure of this program make sense to you? If so, great! If not, ask for help!
User-control of shape on image
Try this to hand in: Next we will write a program that will allow the user to control the position of a shape on a background image. This will teach you how to use more information from the waitKey function, setting us up to work with video camera feeds very soon!
- Make a copy of your solution to the flying saucer program from the previous activity (if you didn’t finish that part, ask your teammates or work on it first).
- We are going to change the
xandyvariables so that they are accumulator variables:- Define
xto be 10 before theforloop - Define
yto be 10 before theforloop - Remove the two lines inside the
forloop that set the values ofxandyaccording to the value ofi - Change the
waitKeycall by removing the time input, and assign a variable to hold the value returned bywaitKey - Print the value of that new variable so that you can see what
waitKeyreturns
- Define
Every typical keyboard character, including control characters that are typically not printable, is represented inside the computer by a one-byte integer value as defined by the ASCII table (Python uses the much larger Unicode representation, but ASCII is a subset of that, and it’s all we will focus on). Open a copy of the ASCII table.. Focus on the Dec and Char columns in this table. The Dec column shows the decimal value from 0 to 127, and the Char column shows the character that corresponds to that integer value. The ones shown in all-caps are non-printable characters, like control characters. ASCII only uses half of the byte, a nibble, to represent typical characters, the values from 128 to 255 are special “extended” characters that we won’t need for now. Look for the values of alphabetic characters, upper and lower case, and the digits.
Once you have looked at the ASCII table, run the program you’ve created above, and try typing different keys: the value returned from waitKey is the integer that corresponds to the key you typed.
We can convert between a character and its integer counterpart using the ord and chr functions: ord takes a character and returns its integer value, chr takes an integer and returns its character value:
a1 = 67
a2 = 111
n3 = 'o'
n4 = 'L'
print(a1, chr(a1))
print(a2, chr(a2))
print(n3, ord(n3))
print(n4, ord(n4))67 C
111 o
o 111
L 76
- Add a line after the
waitKeyand assign a variablecto hold the result of callingchron the returned value fromwaitKey - Add an
ifstatement to respond to the key the user pressed. We will respond to w-a-s-d.- Create an
if-elifstatement with four separate tests: comparingcto'w', comparing it to'a', comparing it to's', and comparing it to'd' - In the
'w'case, we will want the saucer to move up on the screen - In the
's'case, we will want the saucer to move down on the screen - In the
'a'case, we will want the saucer to move left on the screen - In the
'd'case, we will want the saucer to move right on the screen - You can leave out the
elseclause, or include one and print a message that the program didn’t understand what the user typed - As a first step, just put a print statement in each indented block of the
ifstatement that prints which direction we want to move the saucer, given the key the user pressed
- Create an
- Finally, in each of the four cases of our
ifstatement, you will change either thexor theyvariable, updating it to complete the accumulator patterns- In the up case, subtract a fixed amount from
y - In the down case, add to
ythat fixed amount - In the left case, subtracts a fixed amount from
x - In the right case, add the fixed amount to
x
- In the up case, subtract a fixed amount from
Now your program should be complete.
Optional challenge: Bouncing-ball animation
For this optional challenge, you will create a program to draw a moving circle on the screen, and have it bounce off the edges of the screen. We do this by keeping accumulator variables for the x and y center position of the ball, and separately keeping accumulator variables, deltaX and deltaY, for the changes in position in x and y directions (how much the x value should change from one frame to the next, and similarly how much the y direction should change). When the ball reaches one of the edges of the background image, we will change deltaX or deltaY or both, so that the ball moves in a different direction.
Hint: For this to work, you will need to know the width and height of the background image. You can either look this up yourself by clicking on the image in PyCharm, and then hard-coding the values into your program. Or, you can access the size of the image (if it were in variable img) like this: (height, width, depth) = img.shape.
Start, as before with the flying saucer program from last time: * As in the previous program, initialize x and y to be 10 before the for loop, and remove the lines inside the loop that compute x and y in terms of i. * Add a definition of deltaX to be 5 and deltaY to be 3 before the for loop as well * Change what is drawn each time from an ellipse to a circle to simplify matters * Increase the number of iterations of the for loop so that the program will run longer * Make sure that the waitKey call is passed a number for the millisecond delay, we want this program to run without user input * On the lines below the call to waitKey, add two lines to update x and y by adding deltaX and deltaY to them, respectively * Below that, add four if statements (not an if-elif, but separate statements) * In the first if statement, check to see if x plus the circle’s radius is >= the image width * If it is, then set deltaX to be -5 * No else needed for this conditional * In the second if statement, check to see if x minus the circle’s radius is <= 0 * If it is, then set deltaX to be 5 (this can only happen if the circle is moving left in the x direction, so deltaX must currently be -5). * No else needed for this conditional * Implement the other two if statements similarly for the y variable, using -3 and 3 as the values for deltaY
A link to a video showing what this should look like will be available through Moodle.
What to hand in
You should have multiple Python files for this activity. At the very least, you must have:
- A file containing your boolean expression practice (two parts above)
- A file containing your script that asks the user what image to load and display
- A file containing your slideshow script
- A file containing your script where the user controls the movement of the shape on the image
- (Optional) a file containing the bouncing ball program
Use commit and push to copy your code to Github to submit this work.