xyzxyzxyz
xyzxyzxyz

Reputation: 29

Python - Polynomials using Class

I'm at a very beginning in my adventure with Python. I have the following task to do and really I even don't know how to start:

Implement a Polinominal class that represents a polynomial.

Create instances by specifying consecutive coefficients of the polynomial. For example:

    Polynominal() -> 0  
    Polynominal(1, 2, 3) -> 1 + 2x + 3x^2  
    Polynominal(0, 0, 5) -> 5x^2  
    Polynominal(1, -1, 1, -1) -> 1 - x + x^2 - x^3

Instances can be converted to the type string, the format is given in the examples below:

    str(Polynominal()) == ''
    str(Polynominal(1, 2, 3)) == "1 + 2x + 2x^2"
    str(Polynominal(0, 0, 5)) == "5x^2"
    str(Polynominal(1, 1, 1, 1)) == "1 + x + x^2 + x^3"
    str(Polynominal(0, 2, 0)) == "2x"
    str(Polynominal(1, -1, 1, -1)) == "1 - x + x^2 - x^3"
    str(Polynominal(-1)) == "-1"

Instances can be called as a function, the argument of the call is the value of x for which we want to calculate the value of the polynomial:

    my_polynominal = Polynominal(1, 2)
    my_polynominal(1) == 3
    my_polynominal(2) == 5

The instances have a get_degree method to return the degree of the polynomial:

    Polynominal().get_degree() == 0
    Polynominal(1, 2, 3).get_degree() == 2

Instances can be compared to each other using the == operator:

    Polynominal() == Polynominal(0) -> True
    Polynominal(1, 2, 3) == Polynominal(1, 2, 3) -> True
    Polynominal(1, 1, 1) == Polynominal(2, 2, 2, 2) -> False

Instances can be stacked together to create a new object of class Polynominal:

    Polynominal(1, 1, 1) + Polynominal(2, 2, 2) == Polynominal(3, 3, 3)

These instances can be multiplied with each other, and a new object of the Polynominal class will be created as a result of multiplication

    Polynominal(1, 1) * Polynominal(2, 2) == Polynominal(2, 4, 2)

The Polynominal class has a from_iterable method for creating instances of objects using repeatable sets of coefficients.

    Polynominal.from_iterable([1, 2, 3]) == Polynominal(1, 2, 3)
    Polynominal.from_iterable((1, 1, 5)) == Polynominal(1, 1, 5)

The coefficients are integers.

I tried to define the class as follows:

class Polynominal():
    def __init__(*args):
        arg_printable = []
        for i, arg in enumerate(args):
            if i == 0:
                printable = str(arg)
            elif i == 1:
                printable = str(arg) + 'x'
            else:
                printable = str(arg) + 'x^' + str(i)
            arg_printable.append(printable)

            print(' '.join(arg_printable))

but as a result I received something like this:

    <__main__.Polynominal object at 0x7f3b123bbdf0> 1x
    <__main__.Polynominal object at 0x7f3b123bbdf0> 1x 2x^2
    <__main__.Polynominal object at 0x7f3b123bbdf0> 1x 2x^2 3x^3
    <__main__.Polynominal object at 0x7f3b123bbdf0>

How do not to print <main.Polynominal object at 0x7f3b123bbdf0>? What is more, I am wondering how to add signs (+/-) between consecutive coefficients. Could you please help me at least to properly initialize the Class? I would be very grateful, Thanks.

Upvotes: 0

Views: 875

Answers (2)

MK14
MK14

Reputation: 506

You can also overwrite the __repr__ function of a class like this:-

class Polynomial:
    def __init__(self, *coeff):
        if any(coeff):
            self._coeff = tuple(coeff)
        else:
            self._coeff = (0,)

    def __repr__(self):
        terms, res = self._coeff, ""

        if len(terms) == 1:
            res += f"{terms[0]}"
        else:
            for ind, coeff in enumerate(terms):
                if coeff == 0:
                    continue
                elif ind == 0:
                    res += f"{coeff}"
                elif ind == 1:
                    res += f"{coeff}x" if abs(coeff)!=1 else "x"
                else:
                    res += f"{coeff}x^{ind}" if abs(coeff)!=1 else f"x^{ind}"

                if ind != len(terms)-1:
                    res += " + " if coeff>0 else " - "
        return res

But one thing which you've to keep in mind is that, when overwriting any default functions, the suitable datatype must be returned otherwise it raises an error.

For example, here I've overwritten the repr function, and a repr function returns a string by default, so I've to return a string too.

You can also refer here

Upvotes: 0

Samwise
Samwise

Reputation: 71454

Store the terms in your constructor, and define a __str__ method to turn it into a string, rather than trying to turn it into a string (and print it) in the constructor itself.

Having the terms stored as integers is also necessary for implementing the other methods; you won't get far with implementing __mul__ if all you have available is the string representation! This will hopefully help get you started on the right foot:

class Polynomial:
    def __init__(self, *terms: int) -> None:
        self._terms = tuple(terms)

    def __str__(self) -> str:
        out = str(self._terms[0]) if self._terms and self._terms[0] else ""
        for p, term in enumerate(self._terms[1:], 1):
            if term == 0:
                continue
            if out:
                out += " + " if term > 0 else " - "
            if abs(term) != 1:
                out += str(abs(term))
            out += "x"
            if p > 1:
                out += f"^{p}"
        return out


print(Polynomial())
print(Polynomial(1, 2, 3))
print(Polynomial(0, 0, 5))
print(Polynomial(1, -1, 1, -1))
print(Polynomial(-1))

prints:


1 + 2x + 3x^2
5x^2
1 - x + x^2 - x^3
-1

Upvotes: 0

Related Questions