Chapter 6 Exercise Set 3: mytools

mytools module

Assuming you have configured your development environment as described in Configuring Debian for Python Web Development, create a Python module named seqtools.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)

  1. 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)

  1. 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)

  1. 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)

  1. 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)

  1. 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)

  1. 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)

  1. 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)

  1. 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)

  1. 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'
        """