0

I'm making a Polynomial python class and as part of that, I need to print a polynomial nicely. The class is given a list that represents the coefficients of the polynomial and their exponents are given by the position the coefficients are in the list. For example [2,-3,0,5] would give 2x^3-3x^2+5 .

I have tried to take in to account errors such that instead of having 1x it just prints x and if there is a negative, the function just returns a - and not a +-

This is my code so far

class Polynomial:

    def __init__(self, coefficients):
        self.coeffs=coefficients

    def __str__(self):
        out = ''
        for i in range(1,len(self.coeffs)):
            if self.coeffs[i] != 0:
                out += ' + %g*x^%d' % (self.coeffs[i],i)
        # Fixing
        out = out.replace('+ -', '- ')
        out = out.replace('x^0', '1')
        out = out.replace(' 1*', ' ')
        out = out.replace('x^1 ', 'x ')
        if out[0:3] == ' + ':  # remove initial +
            out = out[3:]
        if out[0:3] == ' - ':  # fix spaces for initial -
            out = '-' + out[3:]
        return out

When trying to print p1 = Polynomial([2,3,4]) I get p1 = 3x+4x^2 . The order of the exponents seems to be backwards and the code just ignores the coefficient at the end.

timgeb
  • 76,762
  • 20
  • 123
  • 145
Sharl
  • 175
  • 5
  • 15
  • Are you writing the class for fun or as an exercise? If not: `print(numpy.poly1d([1,2,3]))`. – timgeb Jan 17 '16 at 20:54
  • `for i in range(1,len(self.coeffs)):` replace to `for i in range(1,len(self.coeffs)+1):` so `range(start,stop,end) 'end' not equal to your need!` – dsgdfg Jul 25 '21 at 14:30

4 Answers4

2

Python has really powerful iteration that will help you out here.

For starters, don't pass the len of something to range. Iterate over the something directly.

for x in self.coeffs:

This won't completely help you, though, since the index of the iteration is needed for the power. enumerate can be used for that.

for i, x in enumerate(self.coeffs):

This presents another problem, however. The powers are backwards. For this, you want reversed.

for i, x in enumerate(reversed(self.coeffs)):

From here you just need to handle your output:

items = []
for i, x in enumerate(reversed(self.coeffs)):
    if not x:
        continue
    items.append('{}x^{}'.format(x if x != 1 else '', i))
result = ' + '.join(items)
result = result.replace('x^0', '')
result = result.replace('^1 ', ' ')
result = result.replace('+ -', '- ')
dirn
  • 19,454
  • 5
  • 69
  • 74
1

Here's very simple approach of iterating over coeffs, building string chunk by chunk and joining it afterwards.

class Polynomial:
    def __init__(self, coefficients):
        self.coeffs = coefficients

    def __str__(self):
        chunks = []
        for coeff, power in zip(self.coeffs, range(len(self.coeffs) - 1, -1, -1)):
            if coeff == 0:
                continue
            chunks.append(self.format_coeff(coeff))
            chunks.append(self.format_power(power))
        chunks[0] = chunks[0].lstrip("+")
        return ''.join(chunks)

    @staticmethod
    def format_coeff(coeff):
        return str(coeff) if coeff < 0 else "+{0}".format(coeff)

    @staticmethod
    def format_power(power):
        return 'x^{0}'.format(power) if power != 0 else ''


assert str(Polynomial([2, -3, 0, 5])) == "2x^3-3x^2+5"
Łukasz Rogalski
  • 22,092
  • 8
  • 59
  • 93
0

There are several issues:

  • you should start your range at 0 and not 1;
  • the power should be len(self.coeffs)-1-i;
  • try also to handle particular cases as numerical comparisons rather than strings substitutions (it is more efficient to work with numerical values rather than converting them to string and then detect things on strings).

I would personnaly handle [2,3,4] as 2+3x+4x^2 since it would be easier to handle more complicated computations later, but you may have good reasons to want the contrary.

Thomas Baruchel
  • 7,236
  • 2
  • 27
  • 46
0

This should print: 2*x^2 + 3*x + 4*1 for p1

class Polynomial:

def __init__(self, coefficients):
    self.coeffs=coefficients

def __str__(self):
    out = ''
    size = len(self.coeffs)    
    for i in range(size):      #To Solve the ignored coefficient
        if self.coeffs[i] != 0:
            out += ' + %g*x^%d' % (self.coeffs[i],size-i-1)   #To solve Backwards order
    # Fixing
    out = out.replace('+ -', '- ')
    out = out.replace('x^0', '1')
    out = out.replace(' 1*', ' ')
    out = out.replace('x^1 ', 'x ')
    if out[0:3] == ' + ':  # remove initial +
        out = out[3:]
    if out[0:3] == ' - ':  # fix spaces for initial -
        out = '-' + out[3:]
    return out




a = Polynomial([2,3,4])


print(a)
gallium
  • 301
  • 6
  • 12
  • Using the replace method works fine (by adding: out = out.replace('*1','') / out = out.replace('1x','x') / out = out.replace('-1x', '-x') ), but I suppose there is a more proper way to get the result as explained by @Rogalski with 'format_power' and 'format_coeffs' methods. – gallium Jan 18 '16 at 16:30