Monday

for loops

The general syntax of a for loop is this:

for variable in sequence:
   do this
   and this
   and as many lines as are indented

Here’s an example from last time:

>>> for ch in "abcdefg":
...   print(ch*5)
...
aaaaa
bbbbb
ccccc
ddddd
eeeee
fffff
ggggg

In the above example, the loop variable is ch, and the sequence is a string ("abcdefg"). The only line in the loop code block is a print() statement.

sample quiz questions

Q1: what will this code do?

for i in range(4):
   print(i)
   print("-"*5)

Q2: how about this one?

for i in range(4):
   print(i)
   print("-"*i)

Q3: write the python code to do this:

$ python3 q3.py
how many? 7
*******
*******
*******
*******
*******
*******
*******

Q4: write the python code to do this:

$ python3 q4.py
how many? 4
0000
1111
2222
3333

Q5: trick question…​what will this code do?

total = 0
for i in range(1,6):
   total = total + i
   print(total)

accumulator

The above Q5 is an example of an accumulator. The accumulator is a common pattern seen in programs. Suppose you are entering quiz grades for your students, and you want to calculate the average quiz grade for the class:

Number of grades: 8
grade 1: 90
grade 2: 93
grade 3: 87
grade 4: 74
grade 5: 91
grade 6: 100
grade 7: 76
grade 8: 77
Average grade = 86.0

One way to do that is with an accumulator using the pseudocode below:

total = 0.0
for loop over range(number of grades):
    # get grade using input
    # add it to total
# for loop is done here
# calculate and print average grade

The accumulator can also be useful in counting how many of the items in a list have a certain property. We won’t do this until we understand branching, but here is the pseudocode:

count = 0
for loop over all items in a list:
    if item has a certain property:
        add 1 to count
# for loop is done here
print(count)

accumulator syntax

The above pseudocode shows the basic syntax: initialize the accumulator before the loop, add to the accumulator in the loop, then do something with the accumulator after the loop. Here’s the code to sum the quiz grades entered by the teacher:

num_grades = int(input("Number of grades: "))
total = 0
for n in range(num_grades):
    grade = float(input("grade",n+1,": "))
    total = total + grade
average_grade = total/float(num_grades)
print("Average grade = %.1f\n" % (average_grade))

The total = total + grade line is where each new grade is added to the running total. After the for loop is done, the sum of all the grades should be stored in the variable total.

your turn!

Write a program to ask the user for miles run each day of a week whose output might look like this:

Enter your weekly milage below...
Day 1: 5
Day 2: 2
Day 3: 0
Day 4: 0
Day 5: 6
Day 6: 0
Day 7: 10
Total miles: 23.000000
    Average: 3.285714 miles per day

Wednesday

practice files

I made a practice directory in your cs21 directory, so now you should have inclass, labs, and practice. Inside the practice directory are some for loop and accumulator files with practice problems in them. Please try them out if you are having trouble with for loops and/or accumulators.

review runninglog.py

Here’s my runninglog.py program from last time:

"""
running log: add up running miles for the week

J. Knerr
Fall 2019
"""

def main():
  days = 7
  miles = 0
  for day in range(days):
     amt = float(input("day" + str(day+1) + ": "))
     miles = miles + amt
  print("You ran",miles,"miles this week!")

main()

Fahrenheit to Celcius table

What do you think is the algorithm behind this program?

$ python3 F2C.py

Give me a temperature in degrees F and an increment,
and I'll make a nice F->C table for you!

Start Temperature (F): 32.5
       Temp increment: 1.5
32.5 0.2777777777777778
34.0 1.1111111111111112
35.5 1.9444444444444444
37.0 2.7777777777777777
38.5 3.611111111111111
40.0 4.444444444444445
41.5 5.277777777777778
43.0 6.111111111111111
44.5 6.944444444444445
46.0 7.777777777777778

It displays a table of 10 results, so that’s probably a for loop (on range(10). How do we start at the given temperature and increment that each time through the loop?

string accumulator

You can accumulate strings as well as numbers. The following code starts with a 1-character string, and then adds to it each time through the for loop.

name = input("Name? ")
output = "*"
for ch in name:
    output = output + ch + "*"
print(output)

If the user types in jeff, the output is j*e*f*f.

len() and indexing

A string is a sequence of characters between single or double quotes. A list is a sequence of items, where each item could be anything (an integer, a float, a string, etc).

Both strings and lists have lengths: a string’s length is the number of characters in the string; a list’s length is the number of items in the list.

>>> S = "hello"
>>> L = ["a","b","zebra"]
>>> len(S)
5
>>> len(L)
3

Each character in a string as well as each item in a list has a position, also called an index. In python, positions start at 0, so the "h" in the above string is at position 0, and the "o" is at position 4 (note: one less than the length of the string). In the list above, "zebra" is at position 2.

You can access individual characters in a string, or items in a list, using square-bracket indexing:

>>> print(L[2])
zebra
>>> print(S[2])
l
>>> print(S[3])
l
>>> print(S[4])
o

Any sequence in python can be used in a for loop. For strings, we can either loop over characters in the string or indices (0 to len(S)-1). For lists, we can either loop over items in the list or indices. Here are a few examples:

>>> S = "hello"
>>> for ch in S:
...   print(ch)
...
h
e
l
l
o
>>> for i in range(len(S)):
...   print(i,S[i])
...
0 h
1 e
2 l
3 l
4 o
>>>
>>> L = ["a","b","zebra"]
>>> for i in range(len(L)):
...   print(L[i])
...
a
b
zebra

your turn!

How would you write this program?

$ python3 stringsplit.py
string: we love computer science!!!
we love compu
---------------------------
             ter science!!!
$ python3 stringsplit.py
string: abcdefg
abc
-------
   defg

Friday

split string using accumulator

Here’s one way to do the program (splitstring.py) from last time:

  • get string from the user

  • find length of string

  • calculate half the length

  • accumulate first half of the string into a new string, print it

  • print length dashes

  • accumulate second half of the string into a new string

  • print half spaces, then second half of the string

Here’s the code for getting the first half of the string:

  s = input("string: ")
  length = len(s)
  half = int(length/2)
  first = ""
  for i in range(half):
      first = first + s[i]
  print(first)

slicing

Slicing is a very useful shorthand notation for grabbing characters from a string or items from a list. The syntax is similar to range() where you can have a start, a stop, and a step (or you can use the default values). Here are some examples:

>>> S = "ABCDEFGHIJKLMNOP"
>>> L = ["jeff","kevin","lauri","andy"]
>>> S[2:5]
'CDE'
>>> S[:6]
'ABCDEF'
>>> S[6:]
'GHIJKLMNOP'
>>> L[2:len(L)]
['lauri', 'andy']

The first example above (S[2:5]) grabs characters from positions 2, 3, and 4 (i.e., the start is 2, the stop is 5, so don’t include the stop).

The next two examples use the defaults: S[:6] is the same as S[0:6], and S[6:] is the same as S[6:len(S)] (grab from position 6 to the end).

The last example just shows slicing on a list (grab items instead of characters).

So the splitstring.py example above could have been written like this, using slicing:

  s = input("string: ")
  length = len(s)
  half = int(length/2)
  print(s[:half])

mutable (lists) vs immutable (strings)

Strings are immutable, which means you cannot change individual characters in a string. For example, this doesn’t work:

>>> name = "jeff"
>>> name[0] = "J"
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'str' object does not support item assignment

However, you can create new strings from parts of existing strings. Slicing (using [:] to pick out part of the original string) and concatenation (using the + operator) are useful for doing this:

>>> name = "jeff"
>>> name = "J" + name[1:]
>>> name
'Jeff'
>>> print(name)
Jeff

Unlike strings, lists are mutable, which means that their contents can be modified, without having to create a new list.

>>> L = ["a","b","zebra"]
>>> L[2] = "c"       # assign to position 2 in the list
>>> print(L)
["a","b","c"]

your turn!

Given a strand of RNA, grab/print 3-character groups from the strand. For example, given this:

strand = "ACUAUGACAUGCCAACGCUAGCGUCCU"

Can you print out this (i.e., the first three characters, then the next three, etc)?

0 ACU
3 AUG
6 ACA
9 UGC
12 CAA
15 CGC
18 UAG
21 CGU
24 CCU

2-letter transpositions

Get a string from the user and show all 2-letter transpositions (i.e., swap the first two letters, then the second two, then the third two, etc):

$ python3 transpositions.py
Input word: zebar
0 : ezbar
1 : zbear
2 : zeabr
3 : zebra