Class Notes Week 3


Week 3 Topics

Monday Wednesday Friday


String Accumulation

Picking up from last week, we’ll look at examples of using the accumulator pattern but with the string data type. An example is a solution to a problem from last week (str_practice.py) where given a string e.g., "David", we want to loop and print the following pattern:

D
Da
Dav
Davi
David

We follow the traditional accumulator pattern

  1. Initialize an accumulator variable
  2. Loop over some range * Update the accumulator in the loop
  3. Use accumulator

For strings, initialization is usually an empty string.

accum = ""

There is no space between two double quotation marks. Accumulation is done using the concatenation (+) operator. Our solution is:

name = "David"
accum = ""
for i in range(len(name)):
  accum += name[i]
  print(accum)

This will be a typical pattern for loops over strings. We usually want to look at every character, so our range is over the length of the string. To examine a particular character, we use indexing (name[i]).

Exercise: Double all letters in a string

Get started by moving to the in class directory and opening doubleLetters.py:

$ cd cs21/inclass/w03-boolean
$ atom doubleLetters.py

Write a string accumulator that doubles each character in the sequence. An example run is as follows (user in put in yellow):

$ python3 doubleLetters_soln.py
This program will double each letter in a word
Enter word: Swarthmore

SS
SSww
SSwwaa
SSwwaarr
SSwwaarrtt
SSwwaarrtthh
SSwwaarrtthhmm
SSwwaarrtthhmmoo
SSwwaarrtthhmmoorr
SSwwaarrtthhmmoorree

Range Operator

There are two more ways to use the range() operator if we need more control over the sequence:

Exercise: Skip letters

Return to doubleLetter.py. Write a new string accumulator that only accumulates every-other-letter in the sequence. An example run:

$ python3 doubleLetters_soln.py
This program will double each letter in a word
Enter word: Swarthmore

...


Now, print every-other character only
Satmr

String Formatting

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:

as well as optional width and precision values

An example, if we print out the float variable math.pi:

>>> import math
>>> print(math.pi)
3.14159265359
>>> print("Pi is %f|" % math.pi)
Pi is 3.141593|
>>> print("Pi is %.2f|" % math.pi)
Pi is 3.14|
>>> print("Pi is %20.2f|" % math.pi)
Pi is                 3.14|
>>> print("Pi is %-20.2f" % math.pi)
Pi is 3.14                |

Exercise: String formatting the tax calculator

I have copied last week’s calcTax.py example into formatting_tax.py. Modify the print() statement to print out the dollar amount with two values after the decimal regardless of the precision of the original result. Below, the first result is without print formatting; the second result is with print formatting:

$ python3 formatting_tax_soln.py
Enter the price of the item: 105.00
The tax is $ 6.3 for a total price of $ 111.3
The tax is $6.30 for a total price of $111.30

Boolean Logic

A key aspect of our daily lives is making decisions based on the environment around us. We rarely follow the same pattern, and that is because we must react to differing conditions. The same occurs with algorithms and our programs. Your phone apps would not be very interesting if they always did the exact same thing.

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 (bool type) i.e., True or False. 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:

temp = int(input("Enter temperature: "))
if temp < 32:
  print("Freezing temperatures; be sure to wear a coat!")

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.

There are many ways to compare values (we used less than < above to see if temp is less than 32). Other relational operators:

Operator Meaning
< less than
<= less than or equal to
> greater than
<= greater than or equal to
== equal to
!= not equal to

Exercise: practice relational operators

What are the bool values that result from the following expressions. Assume x = 10:

x < 10
x >= 10
x != 15
x + 15 <= 20
x % 2 == 1

Exercise: practice if statements

Practice if/else statements by writing a block of code that determines if a person’s age makes them eligible to vote.

Exercise: Grade calculator

Open grade.py:

$ cd cs21/inclass/w03-boolean/
$ atom grade.py

Write two different if-statements. First, write a simple if-statement that reports whether the user receives credit or no credit (below 60% is no credit).

Second, write a more complex program that calculates a specific grade with the following break down:

Score Letter
>= 90 A
<=80 and < 90 B
<=70 and < 80 C
<=60 and < 70 D
< 60 NC

Exercise: Code tracing

Code tracing is when you run through code in your head and try to determine the result. I have provided three loops (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")

Logical Operators

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:

  1. Evaluate anything inside of ()
  2. Evaluate all relational operators
  3. Apply any not operators
  4. Evaluate and operators
  5. Evaluate or operators.
  6. If tied, evaluate left to right.

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.

Exercise: Logic Tests

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

Comparing Strings

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 As, then each p, then the ls, 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 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 ASCII. 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 ASCII value of a to A. A is a small ASCII 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'

Boolean Flags

We’ve seen many boolean expression above. Just as we can save the result of a mathematical expression as a variable, we can save the result of boolean expressions as variables e.g.,

voter = age >= 18

The value of voter is either True or False depending on whether age is greater than or equal to 18. A common use of boolean variables is for boolean flags, which resemble the accumulator pattern.

Exercise: Contains an a

In contains_a.py, write a program that determines if a user-inputted word contains the letter a.