<,>,==,!=
and, or, not
if
statementsif/elif/else
statementsin
You've seen several instances of strings already this semester, and you've likely used string concatenation to build up a string. There are many other useful string operations. Here are some highlights:
len
command e.g. len("cs21") = 4
name="Punxsutawney"
, then name[1] = "u"
.+
operator. "hello" + "world" == "helloworld"
Open str_practice.py
to complete four tasks and a couple of extensions if you desire. Be sure to incrementally develop---complete one task, run your program to see if that tasks works, and then move onto the next. Tasks 4 and bonus will require for loops and accumulators.
$ python3 str_practice.py
Task 1:
Enter first name: Tina
Enter last name: Fey
Welcome Tina Fey
Task 2:
There are 7 characters in your name
Task 3:
Initials: T.F.
BONUS:
Last initials: a.y.
Task 4:
T
i
n
a
Topics for Quiz 1 stop here
Picking up from last week, we'll look at examples of using the accumulator pattern but with the string data type. Suppose we want to create the string zzzzzzz
with an arbitrary number n of z
's.
We can follow the traditional accumulator pattern
For strings, initialization is usually an empty string.
ans = ""
There is no space between two double quotation marks. Accumulation is done using the concatenation +
operator. Our solution is:
ans = ""
n=7
for i in range(n):
ans = ans+"z"
print(ans)
Our programs in the first week were entirely sequential. Each statement was processed immediately after the preceding line. In week two, we added the for
loop to allow us to repeat a task a fixed number of times. This week we will introduce a new type, the Boolean type and show how to use it with branching or decision structures to optionally run code based on various conditions. This will another computational tool we will use throughout the semester to design algorithms for problems.
The Boolean or bool
type can only have two possible values True
or False
. Note in python3
, both of these values begin with a upper case letter and the values do not have quotes around them. The value "True"
is a string, not a Boolean.
One way to generate a Boolean value is to use one of the relational operators listed below. For example, the operator <
compares two variables or expressions left < right
. If the value of left
is smaller than right
, the expression left < right
evaluates to True
, otherwise, the answer is False
.
Other relational operators:
Operator | Meaning |
---|---|
< | less than |
<= | less than or equal to |
> | greater than |
>= | greater than or equal to |
== | equal to |
!= | not equal to |
Note that to check if two expressions are equal, you must use the ==
, e.g., x == 7
. Using x = 7
in python3
has a different semantic meaning. It is used for variable assignment and would store the value of 7 in the container labeled x
.
What are the bool
values that result from the following expressions? Assume x = 10
. You can check your answers in the python3
shell by typing python3
in the terminal.
x < 10
x >= 10
x != 15
x + 15 <= 20
x % 2 == 1
The %
operator for number is the mod
or remainder operator. x%y
returns the remainder when x
is divided by y
using integer division. So if x//y=k
and x%y=m
then x=k*y+m
for some integer k
. What property does x
have if x%2 == 1
? What other values could x%2
possibly equal?
We will use branching, or conditional statements, to run different code based on the state of the program. The simplest form of branching is an if
statement:
if <condition>:
<body>
<condition>
will be some statement that evaluates to a Boolean value. The code inside the statement <body>
only runs if the condition is True
. Here is a program that warns you only if the temperature is below freezing:
def main():
temp = int(input("Enter temperature: "))
if temp < 32:
print("Freezing temperatures; be sure to wear a coat!")
print("Have a great day!")
main()
Notice the use of the :
as we saw at the end of for
loops, and also the indented <body>
to indicate that this code is part of the if
statement.
In addition to the basic if
statement, python
supports two additional variants: if/else
and if/elif/else
. The form of the if/else
is:
if <condition>:
<body>
else:
<else-body>
Again, if the <condition>
is true, python will execute the code in <body>
. However, if the condition is false, python executes the code in <else-body>
. Regardless of the value of <condition>
exactly one of <body>
or <else-body>
will run, but not both. It is possible to have an if
with no else
, but any else
must be paired with a matching if
statement.
We could modify our program above to print a different message if the temp is above freezing. Regardless of the temp, the program will always print Have a great day!
since this message is printed outside the body of either the if
or the else
as noted by indentation.
if temp < 32:
print("Freezing temperatures; be sure to wear a coat!")
else:
print("Spring is on its way!")
print("Have a great day!")
The final, most complex branching variant is the if/elif/else
:
if <cond-1>:
<body-1>
elif <cond-2>:
<body-2>
elif <cond-3>:
<body-3>
...
else:
<else-body>
All of these statements work together as one larger decision block. Python will first evaluate <cond-1>
and if it is true, it will execute <body-1>
then skip over the remaining bodies in the block. If <cond-1>
is false, python will next evaluate <cond-2>
. If it is true, it will execute <body-2>
and then skip over the remaining bodies in the block. We can continue to add more elif
conditions and bodies, but each condition will only be evaluated if all the other previous conditions were false. If all the conditions are false, we execute the <else-body>
, if it exists. You can have an if/elif/elif/...
with no final else
. In summary, a decision block has a mandatory if <condition>:
at the beginning, and optional else:
at the end, and zero or more elif <condition-k>:
statements in the middle.
Practice if/else
statements by writing a block of code that determines if a person's age makes them eligible to vote (18 or older on election day). A start of this program is available in cs21/inclasss/w03-boolean/voting.py
if you run update21
. Some potential output might look as follows:
$ python voting.py
Enter your age on election day: 20
You are eligible to vote
$ python voting.py
Enter your age on election day: 18
You are eligible to vote
$ python voting.py
Enter your age on election day: 2
You can't vote this year
You will need to wait 16 years
Code tracing is when you run through code in your head and try to determine the result. I have provided three blocks (the last purposefully being harder than the other two). Will these blocks give different results? Or are some of them equivalent in terms of what will be printed?
#Block 1
if temp >= 60:
print("No coat is needed")
if temp >= 40:
print("Spring jacket")
#Block 2
if temp >= 60:
print("No coat is needed")
elif temp >= 40:
print("Spring jacket")
#Block3
if temp >= 40:
if temp >= 60:
print("No coat is needed")
else:
print("Spring jacket")
Many times we want to ask compound questions, or have multiple conditions be true before executing some code. In these cases, we can join to questions together using a logical operator:
Operator | Meaning |
---|---|
and | both boolean expressions have to be true |
or | at least one of the two boolean expressions has to be true |
not | negates the boolean value |
Here is a truth table, where the x
and y
represent boolean values or expressions. For example, x
could be age >= 18
and y
could be status == "Yes"
. Each row should be read as follows: for the given boolean values of x
and y
, what is the result of x and y
,x or y
, and not x
:
x |
y |
x and y |
x or y |
not x |
---|---|---|---|---|
True | True | True | True | False |
True | False | False | True | False |
False | True | False | True | True |
False | False | False | False | True |
The precedence of operators is to evaluate in this order:
()
not
operatorsand
operatorsor
operators.For example, if b=5
and c=10
we'd evaluate:
not True or b < 10 and c != 5
by first evaluating b<10
to True
and c != 5
to True
:
not True or True and True
Next, we apply not True
to make it False
:
False or True and True
Next, apply the True and True
which is also True
:
False or True
Lastly, we evaluate the or
and the result is True
.
For this exercise, use the the program logicTests.py
to test your understanding of logical operators. You do not need to write any code for this exercise, just run the program and follow the prompts.
$ python3 logicTests.py
Write a program in phase.py
that given a temp in °C prints the phase of water at that temp assuming standard pressure.
$ python3 phase.py
Enter a temp in °C: 150
At 150C, water is a gas
$ python3 phase.py
Enter a temp in °C: 20
At 20C, water is a liquid
$ python3 phase.py
Enter a temp in °C: -10
At -10C, water is a solid
We can compare string values just as we can compare ints
. That is, we can use any relational operator on a pair of a strings.
"Aardvark" < "Baboon"
Strings are compared lexicographically (i.e., based on their sorted dictionary order). So, the above expression is True
because Aardvark
appears earlier in the dictionary.
Drilling down, Python actually compares the two strings character-by-character until it finds a difference. So, it will first compare A
to B
. It finds that they are different, and so it returns True
. If the expression is:
"Apple" < "Applied"
Python first compares the A
s, then each p
, then the l
s, and finally stops at the next position since e
and i
are different. Since e
comes first in the alphabet, it returns True
.
What if we had:
"apple" < "APPLE"
What does Python do? To drill down even further, everything in the computer is represented numerically in binary (0s and 1s). So, even text is really represented as a series of numbers (positive integers, specifically). The encoding, or conversion, is known as Unicode. We can find the conversion using the ord()
function:
$ python3
Python 3.5.2 (default, Nov 23 2017, 16:37:01)
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> ord('A')
65
>>> ord('B')
66
>>> ord('Z')
90
>>> ord('!')
33
So to answer our question above, we need to compare the Unicode value of a
to A
. A
is a small Unicode value, so the expression is False
.
We can also convert in the other direction - from a number to a character using the chr()
function:
>>> chr(58)
':'
>>> chr(100)
'd'
>>> chr(75)
'K'
A substring of a string is a portion of the string that appears contiguously. For example, blue
is a substring of blueberries
. Python has some commands for accessing substrings.
The most relevant for us right now is the in
operator. in
takes a substring called the pattern and another string commonly called the target, and returns True
if and only if the pattern appears as a substring in the target.
Sometimes, the pattern can be a single letter, but in general, the pattern can be any string.
>>> 'a' in "apples"
True
>>> 'b' in "apples"
False
>>> "vark" in "Aardvark"
True
>>> "bbrries" in "blueberries"
False
The print statement is nice for outputting, but it is difficult to format the output in a way we prefer. For example, every time we put out a dollar amount, we can't guarantee two digits after the decimal point for the cents and we also have to always leave a space between the dollar sign and the amount. String formatting allows us to define string templates:
%s
- string value%d
- int value%f
- float valueas well as optional width and precision values
%<number><type>
e.g., %10s
to give a string 10 spaces to fill in%.2f
to require 2 and only 2 significant digits.An example, if we print out the float variable pi
from the math
library:
>>> from math import pi
>>> print(pi)
3.14159265359
>>> print("Pi is %f|" % (pi))
Pi is 3.141593|
>>> print("Pi is %.2f|" % (pi))
Pi is 3.14|
>>> print("Pi is %20.2f|" % (pi))
Pi is 3.14|
>>> print("Pi is %-20.2f" % (pi))
Pi is 3.14 |
You can combine multiple templates in a single string format:
item = "dozen Pierogies"
qty = 4
price = 2.79
print("%d %s cost $%.2f" % (qty, item, qty*price) )