"""
A module of recursive functions on Strings.

Author: Walker M. White (wmw2)
Date:   October 10, 2017 (Python 3 Version)
"""
import string # constants to help with string
import sys

# Allow us to go really deep
sys.setrecursionlimit(999999999)

def length(s):
    """
    Returns: number of characters in s
    
    Parameter: s the string to measure
    Precondition s is a string
    """
    assert type(s) == str, repr(s) + ' is not a string' # get in the habit
    
    # Work on small data  (BASE CASE)
    if s == '':
        return 0
    
    # Break up the data   (RECUSIVE CASE)
    left  = 1               # Length of s[0]
    right = length(s[1:])   # Length of s[1:]
    
    # Combine the results
    return left+right


def num_e(s):
    """
    Returns: number of 'e's in s
    
    Parameter: s the string to count
    Precondition s is a string
    """
    assert type(s) == str, repr(s) + ' is not a string' # get in the habit
    
    # Work on small data  (BASE CASE)
    if s == '':
        return 0
    
    # Break up the data   (RECUSIVE CASE)
    if s[0] == 'e':
        left = 1
    else:
        left = 0
    right = num_e(s[1:])
    
    # Combine the results
    return left+right


def deblank(s):
    """
    Returns: s but with blanks removed
    
    Parameter: s the string to edit
    Precondition s is a string
    """
    assert type(s) == str, repr(s) + ' is not a string' # get in the habit

    # Work on small data  (BASE CASE)
    if s == '':
        return s
    
    # Break up the data   (RECUSIVE CASE)
    left = s[0]
    if s[0] in string.whitespace:
        left = ''
    right = deblank(s[1:])
    
    # Combine the results
    return left+right


def depunct(s):
    """
    Returns: s but with everything that is not a letter removed 
    
    Parameter: s the string to edit
    Precondition s is a string
    """
    assert type(s) == str, repr(s) + ' is not a string' # get in the habit
    
    # Work on small data  (BASE CASE)
    if s == '':
        return s
    
    # Break up the data   (RECUSIVE CASE)
    left = s[0]
    if not s[0].isalpha():
        left = ''
    right = depunct(s[1:])

    # Combine the results
    return left+right


def reverse(s):
    """
    Returns: s with its characters in reverse order
    
    Parameter: s the string to reverse
    Precondition s is a string
    """
    assert type(s) == str, repr(s) + ' is not a string' # get in the habit

    # Work on small data  (BASE CASE)
    if s == '':
        return s
    
    # Break up the data   (RECUSIVE CASE)
    left  = s[0]  # Reverse of one letter is itself
    right = reverse(s[1:]) 
    
    # Combine the results
    return right+left