.. _Cwiczenie: Biblioteka kształtów – programowanie funkcyjne ================================================================== W tym ćwiczeniu przepiszesz bibliotekę kształtów SVG zgodnie z paradygmatem programowania funkcyjnego. W przeciwieństwie do poprzedniego zadania: - **nie używamy klas** - **kształty są reprezentowane jako dane (słowniki)** - **renderowanie odbywa się przez funkcje** Efektem końcowym ma być poprawne wygenerowanie wykresu funkcji sinus i cosinus za pomocą dostarczonego programu ``plot.py``. Reprezentacja kształtu ---------------------- Każdy element SVG jest reprezentowany jako słownik zawierający m.in.: - ``tag`` – typ elementu (np. ``circle``, ``line``) - ``id`` – identyfikator - inne atrybuty (np. ``cx``, ``cy``) - opcjonalnie ``style`` Dla przykładu poniżej podano implementację funkcji tworzącej element ````: .. literalinclude:: svg_shapes_func.py :language: python :linenos: :lines: 9-17 Renderowanie elementów ---------------------- Każdy typ elementu ma odpowiadającą funkcję renderującą. Dla przykładu element ```` narysujemy: .. literalinclude:: svg_shapes_func.py :language: python :linenos: :lines: 85-86 Zwróć uwagę, że funkcja: - przyjmuje słownik (dane) - zwraca tekst SVG - **nie modyfikuje stanu** Funkcja ``render_circle()`` pobiera styl elementu, zapisany w słowniku pod kluczem ``"style"`` i wywołuje dla niego ``render_style()``. Funkcja główna renderująca -------------------------- Funkcja ``render_element()`` wybiera odpowiednią funkcję renderującą na podstawie pola ``tag``, korzystając z dyspozytora: .. literalinclude:: svg_shapes_func.py :language: python :linenos: :lines: 116-120 Zadanie ------- Uzupełnij plik ``svg_shapes_func.py`` tak, aby program ``plot.py`` działał poprawnie. W szczególności: 1. Zdefiniuj brakujące funkcje konstruktorów kształtów: - ``Line()`` - ``Rect()`` - ``Group()`` - ``Square()`` Każda z nich powinna zwracać **słownik opisujący element SVG**. 2. Zaimplementuj ``Style``, która przyjmuje wymagane argumenty: ``fill``, ``stroke`` oraz ``stroke_width`` a zwraca odpowiedni słownik. Dodatkowo, napisz ``render_style()``. 2. Zaimplementuj brakujące funkcje renderujące: - ``_render_line()`` - ``_render_rect()`` - ``_render_group()`` 3. Uzupełnij słownik dyspozytora: - ``_RENDERERS = { ... }`` który mapuje ``tag`` → funkcja renderująca Dodatkowe elementy funkcyjne ---------------------------- Zwróć uwagę na elementy programowania funkcyjnego użyte w zadaniu: - funkcje jako argumenty (``make_points(..., math.sin, ...)``) - brak mutowalnego stanu - transformacje danych (``with_style()``) - list comprehensions zamiast pętli z ``.add()`` Funkcja ``with_style()`` (już zaimplementowana): .. literalinclude:: svg_shapes_func.py :language: python :linenos: :lines: 65-66 Ostatecznie, obraz tworzony jest funkcją svg_drawing: .. literalinclude:: svg_shapes_func.py :language: python :linenos: :lines: 123-138 Efekt końcowy / ocena ćwiczenia --------------------------------------- Poniżej znajduje się kompletny program ``plot.py``, który korzysta z Twojej biblioteki. Twoim celem jest uzyskanie poprawnego obrazu SVG. .. literalinclude:: sin_cos_plot_fn.py :language: python :linenos: Po poprawnej implementacji uruchomienie ``plot.py`` powinno wygenerować poprawny wykres funkcji sinus i cosinus w formacie SVG.