Week 8

String indexing and loop design

Author:Christopher Haynes
Email:chaynes@indiana.edu
Affiliation:Indiana University
Course:BL CSCI A201
Date:2008-02-28
Copyright © 2008, Christopher Haynes—all rights reserved.

Not covered yet

Syntax trees

Demo: string indexing, slicing, and inclusion

>>> s = 'abcd'
>>> s[1]
'b'
>>> s[1.0]
Traceback (most recent call last):
  File "", line 1, in ?
TypeError: string indices must be integers
>>> s[1:3]
'bc'
>>> len(s)
4
>>> s[1:len(s)]
'bcd'
>>> s[1:]
'bcd'
>>> s[:3]
'abc'
>>> s[:]
'abcd'
>>> 'c' in 'ab' + 'cd'
True
>>> 'ham' in 'they served ham and eggs'
True
>>> 'ham' in 'they served spam and eggs'
False
>>> 'ham' not in 'they served spam and eggs'
True

Indexing

Indexing diagram

indexing.png

Slicing

The in and not in operators

Indexed loops

Exercise: remove_char

def remove_char(s, c):
    """
    Return string s with all instances of character c removed.

    >>> remove_char('eggs', 'g')
    'es'
    >>>
    """
    # Hint: use an accumulating indexed loop
    #.
    #.
    #.
    #.
    #.
    #.
    #.

Solution: remove_char

def remove_char(s, c):
    """
    Return string s with all instances of character c removed.

    >>> remove_char('eggs', 'g')
    'es'
    >>>
    """
    # Hint: use an accumulating indexed loop
    index = 0
    result = ''
    while index < len(s):
        if s[index] != c:
            result = result + s[index]
        index = index + 1
    return result

Demo: order of strings

>>> 'a' < 'b'
True
>>> 'A' < 'a'
True
>>> 'a' < 'B'
False
>>> 'egg' < 'eggs'
True
>>> '0' < '1'
True
>>> '9' < '10'
False
>>> 'ab' < 'ac'
True
>>>

Rules for ordering of string

clicker If the value of s is the string 'Wowzer!', what is s[7] ?

  1. '!'
  2. 'r'
  3. none of the above, but no error
  4. syntax error
  5. runtime error

Answer: E

clicker If the value of s is the string 'Wowzer!', what is s[1:3] + s[6] ?

  1. 'Wow!'
  2. 'ow!'
  3. 'Wow'
  4. none of the above, but no error
  5. syntax error
  6. runtime error

Answer: B

clicker The type of an index must be

  1. int
  2. float
  3. string
  4. A or B
  5. any of the above

Answer: A

clicker What's it print?

s = 'Monty'
s[0] = 'm'
print s
  1. monty
  2. Monty
  3. m
  4. none of the above, there is an error

Answer: D

Demo: characters as numbers

>>> ord('a')
97
>>> chr(97)
'a'
>>> ord('A')
65
>>> ord('A') < ord('a')
True
>>> ord('.')
46
>>> chr(0)
'\x00'
>>> chr(255)
'\xff'
>>> chr(256)
Traceback (most recent call last):
  File "", line 1, in ?
ValueError: chr() arg not in range(256)
>>> ord('8') - ord('5')
3

Midterm grades and drop deadline

The ord and chr functions

Exercise: char_table

def char_table():
    """
    Print a table with the numbers 0 through 255 in the first column and
    the corresponding character in the second column. (Separate the columns with
    a space.)
    """
    # FYI: All printing keyboard characters and more appear in the list.
    # Non-printing characters are automatically represented by escape sequences
    # of the form `\xHH`, where `HH` is two "hexadecimal" (base 16) digits

    # Hint: use ord in a counted loop
    #.
    #.
    #.
    #.

Solution: char_table

def char_table():
    """
    Print a table with the numbers 0 through 255 in the first column and
    the corresponding character in the second column. (Separate the columns with
    a space.)
    """
    # FYI: All printing keyboard characters and more appear in the list.
    # Non-printing characters are automatically represented by escape sequences
    # of the form `\xHH`, where `HH` is two "hexadecimal" (base 16) digits

    # Hint: use ord in a counted loop
    i = 0
    while i < 256:
        print i, chr(i)
        i = i + 1

Exercise: leap_year

def leap_year(year):
    """
    Return a boolean indicating if int year is a leap year.  A year is a
    leap year if it is evenly divisible by 4 (that is, there is no
    remainder when divided by 4), and it is not evenly divisible by 100, with
    the exception that years evenly evenly divisible by 400 are leap years.
    >>> leap_year(2006)
    False
    >>> leap_year(2004)
    True
    >>> leap_year(1900)
    False
    >>> leap_year(2000)
    True
    >>>
    """
    #...

Solution: leap_year

def leap_year(year):
    """
    Return a boolean indicating if int year is a leap year.  A year is a
    leap year if it is evenly divisible by 4 (that is, there is no
    remainder when divided by 4), and it is not evenly divisible by 100, with
    the exception that years evenly evenly divisible by 400 are leap years.
    >>> leap_year(2006)
    False
    >>> leap_year(2004)
    True
    >>> leap_year(1900)
    False
    >>> leap_year(2000)
    True
    >>>
    """
    return year % 4 == 0 and not (year % 100 == 0) or year % 400 == 0

Practice and review problems

Rotation ciphers

Example: lower_rot13

def lower_rot13(s):
    """
    Return the result of encoding the string s by applying the 'rot-13'
    cipher to the lowercase characters in s and leaving the the others
    unchanged.

    >>> lower_rot13('abc')
    'nop'
    >>> lower_rot13('nop')
    'abc'
    >>> lower_rot13('This is an encoded message.')
    'Tuvf vf na rapbqrq zrffntr.'
    >>>
    """
    index = 0
    answer = ''
    while index < len(s):
        char = s[index]
        if 'a' <= char and char <= 'z':
            # position of s[index] in alphabet (0-based)
            n = ord(char) - ord('a')
            n = (n + 13) % 26 # rotate 13 positions
            answer = answer + chr(n + ord('a'))
        else: # don't change the character unless it is lowercase
            answer = answer + s[index]
        index = index + 1
    return answer