# Defines Monomial and Polynomial classes.
# A polynomial is built from a string that represents a polynomial,
# that is, a sum or difference of monomials.
# - The leading monomial can be either an integer,
#   or an integer followed by x,
#   or an integer followed by x\^ followed by a nonnegative integer.
# - The other monomials can be either a nonnegative integer,
#   or an integer followed by x,
#   or an integer followed by x\^ followed by a nonnegative integer.
# Spaces can be inserted anywhere in the string.
#
# Written by Eric Martin for COMP9021


class Monomial:
    def __init__(self, coefficient = 0, degree = 0):
        self.coefficient = coefficient
        self.degree = degree
        self.next_monomial = None


class Polynomial:
    def __init__(self, input_polynomial):
        input_polynomial = input_polynomial.replace(' ', '')
        if not input_polynomial:
            return None
        if input_polynomial[0] == '+':
            print('Incorrect input')
            return
        if input_polynomial[0] == '-' and len(input_polynomial) > 1 and input_polynomial[1] == '0':
            print('Incorrect input')
            return            
        for i in range(1, len(input_polynomial)):
            if input_polynomial[i] in '+-' and not input_polynomial[i - 1].isdigit() and input_polynomial[i - 1] != 'x':
                print('Incorrect input')
                return
        input_polynomial = input_polynomial.replace('-', '+-').split('+')
        # For the case where the leading factor is negative.
        if not input_polynomial[0]:
            input_polynomial = input_polynomial[1: ]
        monomial = self._get_monomial(input_polynomial[0])
        if not monomial:
            print('Incorrect input')
            return
        self.head = monomial
        for input_monomial in input_polynomial[1: ]:
            monomial = self._get_monomial(input_monomial)
            if not monomial:
                print('Incorrect input')
                return
            if not monomial.coefficient:
                continue
            self._add_monomial(monomial)

    def _get_monomial(self, input_monomial):
        monomial_parts = input_monomial.split('x')
        if len(monomial_parts) > 2:
            return False
        if len(monomial_parts) == 1:
            try:
                coefficient = int(monomial_parts[0])
                return Monomial(coefficient, 0)
            except:
                return False
        # The case of 'x'.
        if not monomial_parts[0] and not monomial_parts[1]:
            return Monomial(1, 1)
        if not monomial_parts[0]:
            coefficient = 1
        elif monomial_parts[0] == '-':
            coefficient = -1
        else:
            try:
                coefficient = int(monomial_parts[0])
            except:
                return False
        # Needed for the leading monomial.
        if coefficient == 0:
            degree = 0
        else:
            if not monomial_parts[1]:
                degree = 1
            else:
                if monomial_parts[1][0] != '^':
                    return False
                try:
                    degree = int(monomial_parts[1][1: ])
                    if degree < 0:
                        return False
                except:
                    return False           
        return Monomial(coefficient, degree)

    def _add_monomial(self, monomial):
        if monomial.degree > self.head.degree:
            monomial.next_monomial = self.head
            self.head = monomial
            return
        if monomial.degree == self.head.degree:
            self._add_monomial_of_same_degree(None, self.head, monomial)
            return              
        node = self.head
        while node.next_monomial and monomial.degree < node.next_monomial.degree:
            node = node.next_monomial
        if not node.next_monomial:
            node.next_monomial = monomial
        elif monomial.degree == node.next_monomial.degree:
            self._add_monomial_of_same_degree(node, node.next_monomial, monomial)
        else:
            monomial.next_monomial = node.next_monomial
            node.next_monomial = monomial
        
    def _add_monomial_of_same_degree(self, parent, node, monomial):
        if node.coefficient + monomial.coefficient:
            node.coefficient += monomial.coefficient
        elif not parent:
            if not self.head.next_monomial:
                self.head = Monomial()
            else:
                self.head = self.head.next_monomial
        else:
            parent.next_monomial = parent.next_monomial.next_monomial
         
    def __str__(self):
        if not self.head:
            return ''
        if not self.head.degree:
            return str(self.head.coefficient)
        if self.head.coefficient == 1:
            output = ''
        elif self.head.coefficient == -1:
            output = '-'
        else:
            output = str(self.head.coefficient)
        output += 'x'
        if self.head.degree > 1:
            output += '^'
            output += str(self.head.degree)
        node = self.head
        while node.next_monomial:
            node = node.next_monomial
            if node.coefficient > 0:
                output += ' + '
            else:
                 output += ' - '
            if abs(node.coefficient) != 1 or node.degree == 0:
                output += str(abs(node.coefficient))
            if node.degree:
                output += 'x'
            if node.degree > 1:               
                output += '^'
                output += str(node.degree)
        return output
                   

if __name__ == '__main__':
   Polynomial('-0')
   Polynomial('+0')
   Polynomial('0x^-1')
   Polynomial('2x + +2')
   Polynomial('2x + -2')
   Polynomial('2x - +2')
   poly_0 = Polynomial('0')
   print(poly_0)
   poly_0 = Polynomial('0x')
   print(poly_0)
   poly_0 = Polynomial('0x^0')
   print(poly_0)
   poly_0 = Polynomial('0x^5')
   print(poly_0)
   poly_1 = Polynomial('x')
   print(poly_1)
   poly_1 = Polynomial('1x')
   print(poly_1)
   poly_1 = Polynomial('1x^1')
   print(poly_1)
   poly_2 = Polynomial('2')
   print(poly_2)
   poly_2 = Polynomial('2x^0')
   print(poly_2)
   poly_3 = Polynomial('1 + 2-3 +10')
   print(poly_3)
   poly_4 = Polynomial('x + x - 2x -3x^1 + 3x')
   print(poly_4)
   poly_5 = Polynomial('x + 2 + x - x -3x^1 + 3x + 5x^0')
   print(poly_5)
   poly_6 = Polynomial('-2x + 7x^3 +x   - 0  + 2 -x^3 + x^23 - 12x^8 + 45 x ^ 6 -x^47')
   print(poly_6)
   
    
        

Resource created Tuesday 06 October 2015, 10:26:50 AM.

file: question_2.py


Back to top

COMP9021 15s2 (Principles of Programming) is powered by WebCMS3
CRICOS Provider No. 00098G