Hierarchia klas: Wielomian i inne pojęcia alebraiczne
======================================================
Klasa Polynomial
^^^^^^^^^^^^^^^^^
Stwórz klasę ``Polynomial``, która będzie reprezentować funkcję :math:`W(x) = \sum_{i=0}^N c_i x^i` gdzie :math:`N` jest stopniem wielomianu a :math:`x` dowolną liczbą rzeczywistą. Współczynniki :math:`c_i` powinny być prywatnymi danymi klasy
Konstruktor klasy
Klasa powinna mieć konstruktor, umożliwiający łatwe tworzenie wielomianów. Zadbaj o wygodę użytkowników swojej klasy! Twój konstruktor powinien zatem być przeciążony (patrz :term:`przeciążenie`). Utwórz warianty umożliwiające następujące sposoby konstruowania wielomianów:
.. code-block:: python
w1 = Polynomial(1, 0, 5) # Tworzy x^2 + 5
w2 = Polynomial([1, 0, 5]) # Tworzy x^2 + 5
w3 = Polynomial(w2) # Konstruktor kopiujący
Dane prywatne
Zastanów się nad najwygodniejszą reprezentacją danych prywatnych klasy
Wypisywanie na ekran
Napisz metodę ``__str__()``, która odpowiednio wydrukuje wielomian na ekranie
.. code-block:: python
print(w1) # Drukuje na ekran: x^2 + 1
Metody publiczne
Klasa ``Polynomial`` powinna mieć następujące metody: ``add(w)``, ``sub(w)`` i ``mul(w)``, które będą odpowiednio dodawać, odejmować oraz wymnażać wielomian ``w``, modyfikując bieżący obiekt (``self``). Napisz także metody ``differentiate()`` i ``integrate()``, które policzą pierwszą pochodną oraz całkę z wielomianu. Oczywiście klasa ``Polynomial`` powinna też mieć metodę ``eval()`` obliczającą wartość wielomianu w zadanym punkcie.
Na tym etapie Twoja klasa powinna umożliwić **poprawne** działanie następującego programu:
.. code-block:: python
w1 = Polynomial(2, 0, 1)
print(w1) # Drukuje na ekran: x^2 + 1
w2 = Polynomial([3, 2, 1])
w3 = Polynomial(w2)
w2.add(w1)
print(w2.mul(w1))
Lepsza klasa Polynomial
---------------------------------------------
Przeciążenie operatorów
Wykorzystaj :ref:`magic_functions` do zdefiniowania operatorów ``+= -= *=`` , które zastąpią odpowiednio metody klasy: ``add(w)``, ``sub(w)`` i ``mul(w)``. W tym celu wystarczy odpowiednio zmienić nazwy metod, np ``add()`` na ``__iadd__()``. Pamiętaj, aby metody te zwracały ``self``. Zdefiniuj też operatory ``+ - *`` a także operator wywołania (ang. *call operator*) jako metodę ``__call__()``, który zastąpi metodę ``eval()``
Zabezpieczanie danych prywatnych
Utwóż listę ``__slots__`` w klasie ``Polynomial`` (:ref:`slots`), aby nikt nie dodał nowych składowych do Twojej klasy
Dostęp do składowych
Utwóż :term:`getter` ``coefficients`` udostępniający współczynniki wielomianu; dla zachowania integralności klasy metoda ta powinna zwracać głęboką kopię współczynników, ustawionych w kolejności wg. rosnących potęg.
Na tym etapie Twoja klasa powinna umożliwić **poprawne** działanie następującego programu:
.. code-block:: python
w1 = Polynomial(2, 1)
print(w1) # Drukuje na ekran: x^2 + 1
w2 = Polynomial([3, 2, 1])
w3 = Polynomial(w2)
w2 += w1
w4 = w3 + w2
w5 = w3 - w2
w = w4 * w5
print(w2.coefficients)
Test jednostkowy dla klasy Polynomial
---------------------------------------------
Jedną z głównych zalet obiektowego podejścia do programowania jest zamknięcie fragmentu kodu w obiekcie jako w autonomicznej całości (patrz :term:`enkapsulacja`). Każdy obiekt należy jednak dokładnie przetestować. Przedstawiony poniżej plik ``TestPolynomial.py`` sprawdza działanie publicznych metod, które powinieneś zaimplementować w klasie Polynomial:
.. raw:: html
A unit test for Polynomial class
.. literalinclude:: TestPolynomial.py
:language: python
:linenos:
.. raw:: html
W szczególności test ten sprawdza integralność klasy. Na przykład metoda ``test_init(self)`` tworzy wielomian dla podanej listy współczynników, a następnie modyfikuje tą listę i sprawdza, czy wielomian nie uległ zmianie.
Wielomany Czebyszewa
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Wieloman Czebyszewa *k*-tego rzędu :math:`T_k(x)` zdefiniowany jest rekurencyjnie jak nastepuje:
:math:`\begin{matrix}
T_0(x) & = & 1\\
T_1(x) & = & x\\
T_k(x) & = & 2x T_{k-1}(x) - T_{k-2}(x)\\
\end{matrix}`
Wydrukuj na ekranie wielomian :math:`T_{128}(x)`. W tym celu:
funkcja ``chebyshev(k)``
Napisz funkcję ``chebyshev(k)``, która zwraca listę współczynników wielomanu Czebyszewa *k*-tego rzędu.
Klasa ``Chebyshev``
Zawrzyj funkcję ``chebyshev(k)`` w klasie ``Chebyshev`` jako jej statyczną składową. Klasa powinna dziedziczyć po klasie ``Polynomial``. Ponieważ konstruktor klasy ``Polynomial`` wymaga podania współczynników tworzonego wielomianu, wykorzystaj tu napisaną uprzednio statyczną metodę.
Poniżej podaję test jednostkowy dla klasy Chebyshev:
.. raw:: html
(rozwiń kod testu jednostkowego dla klasy Chebyshev)
.. literalinclude:: TestChebyshev.py
:language: python
:linenos:
.. raw:: html
Klasa Fractional
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Stwórz klasę ``Fractional``, która będzie reprezentować iloraz wyrażeń.
Konstruktor klasy
Klasa powinna mieć następujący konstruktor:
.. code-block:: python
f = Fractional(1,5) # Tworzy ulamek 1/5
Dane prywatne
Iloraz powinien przechowywać licznik oraz mianownik jako prywatne pola.
Publiczne pola
Zdefiniuj getter dla licznika i mianownika, nazwij je ``num`` i ``den``
Wypisywanie na ekran
Napisz metodę ``__str__()``, która odpowiednio wydrukuje ułamek na ekranie. Wykorzystaj w tym celu funkcję ``str()`` dla licznika i mianownika
Operatory
Klasa ``Fractional`` powinna udostępniać następujące operatory: ``+``, ``-`` oraz ``*``. Przy sprowadzaniu wyrażeń
do wspólnego mianownika również korzystaj z operacji ``+`` oraz ``*``, operujących odpowiednio na liczniku i mianowniku.
Na tym etapie Twoja klasa powinna umożliwić **poprawne** działanie następującego programu:
.. code-block:: python
f1 = Fractional(2, 5)
f2 = Fractional(1,3)
print(f3) # Drukuje na ekran: 2/15
f3 = f1 * f2
f3 += f1
f4 = f3 - f2
Funkcje wymierne
^^^^^^^^^^^^^^^^^
Funkcja wymierna to nic więcej jak ułamek (``Fractional``) w którym zarówno licznik i mianownik to wielomiany
(obiekty klasy ``Polynomial``). Poniższy kod powinien działać poprawnie:
.. code-block:: python
w1 = Polynomial(1, 2, 5)
w2 = Polynomial(1,3)
f1 = Fractional(w1, w2)
f2 = Fractional(w2, w1)
print(f1 + f2)