.. py:module:: polinomis Polinomi ======== L'objectiu d'aquest exercici és dissenyar la classe :py:class:`~polinomis.Polinomi` que representa un polinomi d'una sola variable amb coeficients reals. .. _polinomis_especificacio: Especificació ------------- La classe :py:class:`~polinomis.Polinomi` té l'especificació següent: .. py:class:: Polinomi Retorna el polinomi zero. .. rubric:: Mètodes .. py:method:: 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: .. literalinclude:: tests-polinomis-1.txt :language: python3 .. _polinomis_representacio: 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. .. _polinomis_implementacio: Implementació ------------- Deseu la implementació de la classe :py:class:`~polinomis.Polinomi` al fitxer :file:`polinomis.py` (mòdul :py:mod:`polinomis`). De les tres representacions mencionades a l'apartat :ref:`polinomis_representacio`, 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 :ref:`polinomis_especificacio`. Cal que tingueu en compte les següents observacions: #. Per representar els coeficients diferents de zero del polinomi caldrà un atribut addicional *privat*, per exemple: .. py:attribute:: 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: .. math:: p(x) = -0.4x^9 + 1.2x^5 - 0.04x^3 + 9.4x^2 #. Quan es crea una instància a la classe :py:class:`~polinomis.Polinomi`, aquesta representa un polinomi amb tots els coeficients iguals a zero. Per exemple: .. code:: python >>> from polinomis import Polinomi >>> p = Polinomi() >>> p[3] 0 >>> p[300] 0 #. El mètode ``__init__`` haurà d'inicialitzar el diccionari :py:attr:`~polinomis.Polinomi.__vals` tenint en compte el que s'ha explicat en els punts anteriors, és a dir, haurà d'estar buit. #. 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 :math:`g \ge 0`. #. Quan s'assigna un coeficient `c` al grau `g` del polinomi `p`, ``p[g] = c``, cal tenir en compte que en el diccionari :py:attr:`~polinomis.Polinomi.__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 :py:attr:`~polinomis.Polinomi.__vals`. #. El mètode :py:meth:`~polinomis.Polinomi.grau` retorna el grau més gran dels coeficients diferents de zero del polinomi, és a dir la màxima clau del diccionari :py:attr:`~polinomis.Polinomi.__vals`. Per exemple: .. code:: python >>> p = Polinomi() >>> p[2] = 23 >>> p.grau() 2 >>> p[9] = -5 >>> p.grau() 9 Disposeu de jocs de proves al fitxer :download:`tests-polinomis-1.txt`. Suport per la funció :py:class:`str` ------------------------------------ L'objectiu ara és mostrar el polinomi a l'usuari d'una manera entenedora quan es converteix a *string* cridant a la funció :py:class:`str` o quan s'escriu cridant a la funció :py:func:`print`. Per exemple: .. literalinclude:: tests-polinomis-4.txt :language: python3 :lines: 3-10 Cal que reescriviu el mètode ``__str__`` a la classe :py:class:`~polinomis.Polinomi`. Disposeu de jocs de proves als fitxer :download:`tests-polinomis-4.txt`. Operadors suma i producte ------------------------- Afegiu a la classe :py:class:`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: .. literalinclude:: tests-polinomis-3.txt :language: python3 :start-after: --ini-enunciat :end-before: --fi-enunciat Recordeu que caldrà implementar els mètodes ``__add__`` i ``__mul__``. Disposeu de jocs de proves als fitxers :download:`tests-polinomis-2.txt` i :download:`tests-polinomis-3.txt`. Disposeu d'una solució al fitxer :download:`polinomis.py `. .. _polinomis_suma_producte: .. py:module:: opera_polinomis Suma d'un iterable de polinomis ------------------------------- Tot seguit, fent servir aquesta classe, implementeu al fitxer :file:`opera_polinomis.py` una funció que donat un iterable d'una seqüència de polinomis, en calculi el polinomi suma. .. py:function:: suma_polinomis(iterpolinomis) :param iterpol: un iterable d'una seqüència d'instàncies de la classe :py:class:`~polinomis.Polinomi` :return: el polinomi suma Per exemple: .. literalinclude:: tests-opera_polinomis_1.txt :language: python3 :start-after: --ini-enunciat :end-before: --fi-enunciat Disposeu de jocs de proves als fitxer :download:`tests-opera_polinomis_1.txt`. Iterador de graus ----------------- En el mateix mòdul :file:`opera_polinomis.py` implementeu la funció següent que retorna un iterador dels graus d'una seqüència d'instàncies de la classe :py:class:`Polinomi`. .. function:: iter_graumaxim(iterpol) :param iterpol: un iterable d'una seqüència d'instàncies de la classe :py:class:`Polinomi`) :return: un iterador de la seqüència dels graus dels polinomis de l'iterable Per exemple: .. literalinclude:: tests-opera_polinomis_2.txt :language: python3 :start-after: --ini-enunciat :end-before: --fi-enunciat Disposeu de jocs de proves als fitxer :download:`tests-opera_polinomis_2.txt` i d'una solució a :download:`opera_polinomi.py `.