[ create a new paste ] login | about

Link: http://codepad.org/G1ws5Bu3    [ raw code | fork ]

j_king - Python, pasted on Feb 3:
#!/usr/bin/env python

"""

rotate.py -- A simple function for comparing whether a given string is
a rotation of another.

(c) 2012, James King

"""

__author__ = 'James King'
__email__ = 'james@agentultra.com'


import doctest


def split_string(s, separator_p, include_separator=False):
    """
    Return a list of strings from 's' using the test function
    'separator_p' as the delimiter.

    'separater_p' is a function that takes a single character string
    as its argument and should return a Boolean.

    If include_separator is True, then include the delimiting
    character in the word.

    >>> split_string("the quick brown fox", lambda c: c.isspace())
    ['the', 'quick', 'brown', 'fox']
    >>> split_string("the1quick2brown2fox", lambda c: c.isdigit())
    ['the', 'quick', 'brown', 'fox']
    >>> split_string("the1quick2brown2fox", lambda c: c.isdigit(),
    ...              include_separator=True)
    ['the', '1quick', '2brown', '2fox']
    >>> split_string("ProgrammingPraxis", lambda c: c.isupper(),
    ...              include_separator=True)
    ['Programming', 'Praxis']
    """
    words = []
    pivot = 0
    for idx, char in enumerate(s):
        if separator_p(char):
            words.append(s[pivot:idx])
            pivot = idx if include_separator else idx + 1
    if pivot < len(s):
        words.append(s[pivot:])

    if include_separator:
        # filter the special case where the first word includes the
        # separator and we append an empty list to words. (ie:
        # 'CamelCase')
        return filter(lambda x: len(x), words)
    else:
        return words


def rotate(s1, s2, separator=lambda s: s.isupper(), include_sep=True):
    """
    Return True if s1 is a rotation of s2.

    'separator' is a function that takes one argument, a single
    character string, which determines the word delimiter.

    'include_sep' determines whether to include the delimiter
    character in the words to be compared.

    >>> rotate("ProgrammingPraxis", "PraxisProgramming")
    True
    >>> rotate("ProgrammingPraxis", "ProgrammingPrasix")
    False
    >>> rotate("AReallyInterestingExample", "ExampleInterestingReallyA")
    True
    >>> rotate("test1_test2", "test2_test1", separator=lambda c: c == '_',
    ...        include_sep=False)
    True

    But if you include the separator:

    >>> rotate("test1_test2", "test2_test1", separator=lambda c: c == '_')
    False

    Becase the word list will look like ['test1', '_test2'] and
    ['test2', '_test1'] for s1 and s2 respectively.  A general rule of
    thumb is to leave out the separator if it's not a part of the
    words you want to check (ie: 'test1_test2' is bad, but 'CamelCase'
    is good).

    >>> rotate("asdasd", "asdasd")
    True
    >>> rotate("asdasd", "erferf")
    False

    If no separator is found, the function will treat the word list as
    a single word and do what we expect it to.
    """
    s1_words = split_string(s1, separator, include_separator=include_sep)
    s2_words = split_string(s2, separator, include_separator=include_sep)
    s2_words.reverse()

    if s1_words == s2_words:
        return True
    else:
        return False


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


Output:
No errors or program output.


Create a new paste based on this one


Comments: