Chapter 6 exercise set 3: mytools

mytools module

Create a Python module named mytools.py in your $HOME/.local/lib/my_python directory. Put the following at the bottom of the module to run doctests:

if __name__ == '__main__':
    import doctest
    doctest.testmod()

Add each of the following functions to your module, making the doctests pass for each one.

reverse(seq)

Write a function that reverses its sequence argument, and satisfies these tests

def reverse(seq):
    """
      >>> reverse('happy')
      'yppah'
      >>> reverse('Python')
      'nohtyP'
      >>> reverse('')
      ''
      >>> reverse('a')
      'a'
      >>> reverse((4, 3, 2, 1))
      (1, 2, 3, 4)
    """

mirror(seq)

Write a function that mirrors its argument

def mirror(seq):
    """
      >>> mirror('good')
      'gooddoog'
      >>> mirror('Python')
      'PythonnohtyP'
      >>> mirror('')
      ''
      >>> mirror('a')
      'aa'
      >>> mirror((4, 3, 2, 1))
      (4, 3, 2, 1, 1, 2, 3, 4)
    """

remove_element(element, seq)

Write a function that removes all occurrences of a given element from a sequence.

def remove_element(element, seq):
    """
      >>> remove_element('a', 'apple')
      'pple'
      >>> remove_element('a', 'banana')
      'bnn'
      >>> remove_element('z', 'banana')
      'banana'
      >>> remove_element('i', 'Mississippi')
      'Msssspp'
      >>> remove_element('b', '')
      ''
      >>> remove_element(1, (1, 2, 1, 3, 1, 4, 1, 5))
      (2, 3, 4, 5)
    """

is_palindrome(seq)

Write a function that recognizes palindromes. We will extend the notion of palindrome from strings to sequences in general, calling any sequence that is the same forward and backward a “palindrome”.

def is_palindrome(seq):
    """
      >>> is_palindrome('abba')
      True
      >>> is_palindrome('abab')
      False
      >>> is_palindrome('tenet')
      True
      >>> is_palindrome('banana')
      False
      >>> is_palindrome('straw warts')
      True
      >>> is_palindrome('a')
      True
      >>> is_palindrome('')
      True
      >>> is_palindrome((1, 2, 2, 1))
      True
      >>> is_palindrome((1, 2, 3, 4))
      False
    """

Hint

Use your reverse function to make this easy!

count_sub(sub, seq)

Write a function that counts how many times a subseq occurs in a sequence.

def count_sub(sub, seq):
    """
      >>> count_sub('is', 'Mississippi')
      2
      >>> count_sub('an', 'banana')
      2
      >>> count_sub('ana', 'banana')
      2
      >>> count_sub('nana', 'banana')
      1
      >>> count_sub('nanan', 'banana')
      0
      >>> count_sub('aaa', 'aaaaaa')
      4
    """

find_sub(sub, seq)

Write a function that finds the index of the first occurrence of a substring inside another string. It should return -1 if the substring is not found.

def find_sub(sub, seq):
    """
      >>> find_sub('an', 'banana')
      1
      >>> find_sub('cyc', 'bicycle')
      2
      >>> find_sub('ud', 'apple strudel')
      9
      >>> find_sub('egg', 'bicycle')
      -1
    """

remove_sub(sub, seq)

Write a function that removes the first occurrence of a substring from another string.

def remove_sub(sub, s):
    """
      >>> remove_sub('an', 'banana')
      'bana'
      >>> remove_sub('cyc', 'bicycle')
      'bile'
      >>> remove_sub('iss', 'Mississippi')
      'Missippi'
      >>> remove_sub('egg', 'bicycle')
      'bicycle'
    """

Hint

One way to write this function would be to call find_sub to get the index of s where sub begins. Then use slicing (see Slices) to take the part before this substring and join it with the part after this substring.

remove_all_sub(sub, seq)

Write a function that removes all occurrences of a substring from another string.

def remove_all_sub(substr, s):
    """
      >>> remove_all_sub('an', 'banana')
      'ba'
      >>> remove_all_sub('cyc', 'bicycle')
      'bile'
      >>> remove_all_sub('iss', 'Mississippi')
      'Mippi'
      >>> remove_all_sub('eggs', 'bicycle')
      'bicycle'
    """

Hint

This problem can be solved in just a few lines and a simple while loop by calling remove_sub until no changes are made to the string.

remove_punct(s)

Write a function that removes all punctuation from a given string.

def remove_punct(s):
    """
      >>> remove_punct('This... is a "string"; it has, punctuation, yes?')
      'This is a string it has punctuation yes'
      >>> remove_punct('')
      ''
      >>> remove_punct('no punctuation here')
      'no punctuation here'
      >>> remove_punct('$#lots (of?^) punctuation!@# here!**')
      'lots of punctuation here'
    """