Search code examples
pythonregexnon-alphanumeric

Pig Latin- keep non-letters python


I am currently writing a pig Latin code and it requires all the non-letters to be ignored ie left in the same place of the word. For instance, Tom's would be om'sTay. So I deleted all non-alphabetic characters using: word = re.sub('[^A-Za-z]', '', word) did the pig latin code and I want to bring the non-letters back. Not sure how to bring back the non-letters to the same place of the changed word.


Solution

  • In[2]: def pig_latinize(word):
      ...:     cluster_dex = 0
      ...:     vowels = set('AEIOUaeiou')
      ...:     for i, char in enumerate(word, start=1):
      ...:         if not char.isalpha() or char in vowels:
      ...:             break
      ...:         cluster_dex = i
      ...:     if cluster_dex == 0:
      ...:         suffix = 'hay'
      ...:     elif cluster_dex == len(word):
      ...:         cluster_dex = 1
      ...:         suffix = 'way'
      ...:     else:
      ...:         suffix = 'ay'
      ...:     return '{}{}{}'.format(word[cluster_dex:], word[:cluster_dex], suffix)
      ...: 
      ...: 
      ...: def pig_latin(words):
      ...:     return ' '.join(pig_latinize(word) for word in words.split())
      ...: 
    In[3]: pig_latin("Tom's") == "om'sTay"
    Out[3]: True
    In[4]: pig_latin('the ap!ple is green') == 'ethay ap!plehay ishay eengray'
    Out[4]: True
    In[5]: pig_latin("Kate's care") == "ate'sKay arecay"
    Out[5]: True
    In[6]: pig_latin('myth') == 'ythmway'
    Out[6]: True
    In[7]: pig_latin('cry') == 'rycway'
    Out[7]: True
    

    EDIT:

    This shows a possible way of turning these functions into the class from the description you gave

    >>> class PigLatin(object):
    ...     VOWELS = set('AEIOUaeiou')
    ...
    ...     def __init__(self, to_convert):
    ...         self.convert_words(to_convert)
    ...
    ...     def convert_words(self, to_convert):
    ...         if not isinstance(to_convert, list):
    ...             # if to_convert is a string, split into separate words
    ...             to_convert = to_convert.split()
    ...         self.pig_latin = ' '.join(
    ...             self.p_latin_converter(word) for word in to_convert)
    ...
    ...     def p_latin_converter(self, word):
    ...         cluster_dex = 0
    ...         for i, char in enumerate(word, start=1):
    ...             if not char.isalpha() or char in self.VOWELS:
    ...                 break
    ...             cluster_dex = i
    ...         if cluster_dex == 0:
    ...             suffix = 'hay'
    ...         elif cluster_dex == len(word):
    ...             cluster_dex = 1
    ...             suffix = 'way'
    ...         else:
    ...             suffix = 'ay'
    ...         return '{}{}{}'.format(word[cluster_dex:], word[:cluster_dex], suffix)
    ...
    
    # *** An object of this method initializes the string it wants to 
    # convert when it is created. ***
    >>> p = PigLatin("Tom's")  # initialize with a sting
    # pig_latin attribute is then set with the converted text
    >>> p.pig_latin == "om'sTay"
    True
    
    # *** Further, the class should have a method that allows the string to be
    # modified to perform another conversion. ***
    >>> p.convert_words('the ap!ple is green')  # modify the pig_latin attribute
    >>> p.pig_latin == 'ethay ap!plehay ishay eengray'
    True
    
    # *** build a pigLatin_class that works with strings and lists and has a
    # method to convert a string into pig latin. ***
    >>> p.convert_words(['myth', 'cry'])  # use a list of strings
    >>> p.pig_latin == 'ythmway rycway'
    True
    
    # *** The set of VOWELS can be defined as a static attribute of the class. ***
    >>> p.VOWELS
    {'E', 'e', 'A', 'O', 'a', 'i', 'u', 'I', 'U', 'o'}
    
    # *** The class pigLatin should be based on the basic object datatype. ***
    >>> isinstance(p, object)  # inherits from object "class PigLatin(object):"
    True
    
    # *** method pLatin_converter can be used. ***
    >>> p.pig_latin  # current pig_latin attribute
    'ythmway rycway'
    # returns a word without modifying the pig_latin attribute
    >>> p.p_latin_converter("Kate's care")
    "ate's careKay"
    # show that the pig_latin attribute wasn't modified after the above call
    >>> p.pig_latin
    'ythmway rycway'