"""
polystuff.py (Python 3.x)

For a curriculum segment when we're not yet wanting to build
user-defined classes.

showpoly -- return an evaluable string with x the variable
evalpoly -- return a numeric result given an evaluable string and x's value
multipoly -- return the product of two polynomials as a tuple of tuples
"""

from operator import itemgetter

def showpoly(A):
    """
    Return a close-to-classic polynomial as an evaluable Python string
literal,
    given a sequence of tuples for input (see multipoly below). Some
prettifying.

    >>> p1 = ((4,2),(-4,1),(-7,0))
    >>> showpoly(p1)
    '4 * x**2 - 4 * x**1 - 7'
    """

    terms = []
    for coeff, exp in sorted(A, key=itemgetter(1), reverse=True):
        terms.append( "{sign} {coeff}{var}".format(
                            sign = "+" if coeff > 0 else "-",
                            coeff = abs(coeff),
                            var = ' * x**{}'.format(exp) if exp>0 else ""
                            ))

    ans = " ".join(terms)
    if ans[0] == "+":  # prettify
        ans = ans[1:].strip()
    return ans


def evalpoly(strpoly, x):
    """
    Evaluates a polynomial string literal for a given x value

    >>> p1 = ((4,2),(-4,1),(-7,0))
    >>> thestring = showpoly(p1)
    >>> thestring
    '4 * x**2 - 4 * x**1 - 7'
    >>> evalpoly(thestring, 10)
    353
    """
    return eval(strpoly, {"x":x})


def multipoly(A, B):
    """
    Multiply two polynomials, represented as sequences of tuples
    e.g.:  3*x**3 + 2*x**2 - x - 1 would be
    ((3,3),(2,2),(-1,1),(-1,0))
    with internal pairs in any order (term order is arbitrary)

    >>> p1 = ((1,1),(-1,0))
    >>> p2 = ((1,1),(1,0))
    >>> multipoly(p1,p2)
    [(-1, 0), (1, 2)]
    >>> p1 = ((4,2),(-4,1),(-7,0))
    >>> p2 = ((1,1),(3,0))
    >>> multipoly(p1,p2)
    [(-21, 0), (-19, 1), (8, 2), (4, 3)]
    """
    results = []
    termsAB = []

    # Cartesian product of terms in poly A and poly B
    # multiply coefficients, add exponents
    for termA in A:
        for termB in B:
            termsAB.append((
                    termA[0] * termB[0], # coefficients
                    termA[1] + termB[1]  # exponents
                            ))

    # find maximum exponent
    degree = max([term[1] for term in termsAB])

    # collect like terms (same exponent)
    for exp in range(degree+1):  # from 0 to degree inclusive
        newterm = ( sum([term[0] for term in termsAB if term[1] == exp]),
exp)
        if newterm[0] != 0:
            results.append(newterm)

    return results

def _test( ):
    import doctest
    doctest.testmod()

if __name__ == '__main__':
    _test()
_______________________________________________
Edu-sig mailing list
Edu-sig@python.org
http://mail.python.org/mailman/listinfo/edu-sig

Reply via email to