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)