Polinomi

L’objectiu d’aquest exercici és dissenyar la classe Polinomi que representa un polinomi d’una sola variable amb coeficients reals.

Especificació

La classe Polinomi té l’especificació següent:

class polinomis.Polinomi

Retorna el polinomi zero.

Mètodes

grau()

Retorna el grau del polinomi. Si el polinomi és nul (amb tots els coeficients iguals a zero), retorna 0.

Aquesta classe ha de suportar les operacions següents:

Operació

Resultat

p[g]

retorna el coeficient de grau g del polinomi p.

p[g] = coef

assigna coef al coeficient de grau g del polinomi p.

El grau d’un coeficient (g) ha de ser més gran o igual que zero.

Per exemple:

>>> from polinomis import Polinomi

>>> p = Polinomi()
>>> p.grau()
0
>>> p[5]
0
>>> p[3] = 2
>>> p[3]
2
>>> p[2] = 7
>>> p[2]
7
>>> p.grau()
3
>>> p[3] = 0
>>> p[3]
0
>>> p.grau()
2

Representació

Hi ha diverses maneres d’implementar aquesta classe, depenent de com es guardin els coeficients:

  • En una llista de longitud prefixada. La longitud d’aquesta llista determinarà el grau màxim dels polinomis.

  • En una llista de longitud variable. En aquest cas, els polinomis podran ser de grau arbitrari.

  • En un diccionari les claus del qual siguin els graus i els valors els coeficients. En aquest cas, el grau també serà arbitrari. Per tal de minimitzar l’espai de memòria usat, convé que el diccionari contingui només els coeficients no nuls.

Implementació

Deseu la implementació de la classe Polinomi al fitxer polinomis.py (mòdul polinomis).

De les tres representacions mencionades a l’apartat Representació, la implementació que exposarem a continuació correspon a la representació basada en un diccionari.

Per implementar aquesta classe, haureu de dissenyar els mètodes que donen suport a les operacions i funcions esmentades a l’apartat Especificació. Cal que tingueu en compte les següents observacions:

  1. Per representar els coeficients diferents de zero del polinomi caldrà un atribut addicional privat, per exemple:

    polinomis.Polinomi.__vals

    Diccionari que conté únicament els graus amb els coeficients no nuls del polinomi. En aquest diccionari, la clau serà un grau del polinomi, un nombre natural g, tal que el seu coeficient sigui no nul, i el valor associat serà el coeficient no nul de grau g, un nombre real. Per exemple, el diccionari {2: 9.4, 9: -0.4, 3: -0.04, 5: 1.2} representa el polinomi de grau 9 amb quatre coeficients no nuls següent:

    \[p(x) = -0.4x^9 + 1.2x^5 - 0.04x^3 + 9.4x^2\]
  2. Quan es crea una instància a la classe Polinomi, aquesta representa un polinomi amb tots els coeficients iguals a zero. Per exemple:

    >>> from polinomis import Polinomi
    >>> p  = Polinomi()
    >>> p[3]
    0
    >>> p[300]
    0
    
  3. El mètode __init__ haurà d’inicialitzar el diccionari __vals tenint en compte el que s’ha explicat en els punts anteriors, és a dir, haurà d’estar buit.

  4. La consulta (p[g]) i l’assignació (p[g] = c) al grau g del polinomi p, són vàlides sempre que el grau compleixi \(g \ge 0\).

  5. Quan s’assigna un coeficient c al grau g del polinomi p, p[g] = c, cal tenir en compte que en el diccionari __vals hi ha només els coeficients no nuls del polinomi. És a dir, si el coeficient c és nul, cal esborrar el grau g del diccionari __vals.

  6. El mètode grau() retorna el grau més gran dels coeficients diferents de zero del polinomi, és a dir la màxima clau del diccionari __vals. Per exemple:

    >>> p  = Polinomi()
    >>> p[2] = 23
    >>> p.grau()
    2
    >>> p[9] = -5
    >>> p.grau()
    9
    

Disposeu de jocs de proves al fitxer tests-polinomis-1.txt.

Suport per la funció str

L’objectiu ara és mostrar el polinomi a l’usuari d’una manera entenedora quan es converteix a string cridant a la funció str o quan s’escriu cridant a la funció print(). Per exemple:

>>> p = Polinomi()
>>> p[3], p[1], p[0] = 2, -1, 4
>>> print(p)
2x^3-x+4

>>> p[4] = 6
>>> print(p)
6x^4+2x^3-x+4

Cal que reescriviu el mètode __str__ a la classe Polinomi.

Disposeu de jocs de proves als fitxer tests-polinomis-4.txt.

Operadors suma i producte

Afegiu a la classe Polinomi els operadors suma i producte:

Operació

Resultat

p + q

retorna el polinomi suma dels polinomis p i q.

p * q

retorna el polinomi producte dels polinomis p i q.

Per exemple:

>>> p = Polinomi()
>>> p[3], p[1], p[0] = 2, -1, 4
>>> q = Polinomi()
>>> q[2], q[1] = -5, 7
>>> str(p+q)
'2x^3-5x^2+6x+4'
>>> str(p*q)
'-10x^5+14x^4+5x^3-27x^2+28x'

Recordeu que caldrà implementar els mètodes __add__ i __mul__.

Disposeu de jocs de proves als fitxers tests-polinomis-2.txt i tests-polinomis-3.txt. Disposeu d’una solució al fitxer polinomis.py.

Suma d’un iterable de polinomis

Tot seguit, fent servir aquesta classe, implementeu al fitxer opera_polinomis.py una funció que donat un iterable d’una seqüència de polinomis, en calculi el polinomi suma.

opera_polinomis.suma_polinomis(iterpolinomis)
Paràmetres:

iterpol – un iterable d’una seqüència d’instàncies de la classe Polinomi

Retorna:

el polinomi suma

Per exemple:

>>> p = Polinomi()
>>> p[3], p[1], p[0] = 2, -1, 4
>>> q = Polinomi()
>>> q[5], q[2], q[1] = 9, -5, 7
>>> r = Polinomi()
>>> r[5], r[3], r[2], r[1], r[0] = 7, 9, -5, 7, 13
>>> str(suma_polinomis([p, q, r]))
'16x^5+11x^3-10x^2+13x+17'

Disposeu de jocs de proves als fitxer tests-opera_polinomis_1.txt.

Iterador de graus

En el mateix mòdul opera_polinomis.py implementeu la funció següent que retorna un iterador dels graus d’una seqüència d’instàncies de la classe Polinomi.

opera_polinomis.iter_graumaxim(iterpol)
Paràmetres:

iterpol – un iterable d’una seqüència d’instàncies de la classe Polinomi)

Retorna:

un iterador de la seqüència dels graus dels polinomis de l’iterable

Per exemple:


>>> p = Polinomi()
>>> p[3], p[1], p[0] = 2, -1, 4
>>> q = Polinomi()
>>> q[5], q[2], q[1] = 9, -5, 7
>>> r = Polinomi()
>>> r[7], r[3], r[2], r[1], r[0] = 7, 9, -5, 7, 13
>>> it = iter_graumaxim([p, q, r])
>>> next(it), next(it), next(it)
(3, 5, 7)

Disposeu de jocs de proves als fitxer tests-opera_polinomis_2.txt i d’una solució a opera_polinomi.py.