Fabryka klas: znaczniki na wykresie ========================================= W poprzednim ćwiczeniu powstała klasa ``Plot``. Umożliwia ona rysowanie wykresu punktowego dzięki metodzie ``Plot.scatter()`` Celem tego ćwiczenia jest umożliwienie dynamicznego tworzenia graficznych symboli, odpowiadającym punktom na wykresie. W tym celu wykorzystasz wzorzec projektowy **fabryka klas**. Zadanie ------- Napisz moduł ``markers_factory.py`` zawierający fabrykę klas produkującą znaczniki do wykresu punktowego i wykorzystaj go w klasie ``Plot``. Poprawne rozwiązanie powinno umożliwiać rysowanie wykresu punktowego z dowolnymi znacznikami zdefiniowanymi przez użytkownika; bez konieczności edytowania klasy ``Plot``. Klasy - znaczniki --------------------- Napisz ``AbstractMarker`` oraz dziedziczące po niej znaczniki: ``CircleMarker`` (koło) oraz ``SquareMarker`` (kwadrat). Klasy - producenci ------------------- Instancje tych klas produkowane będą w fabryce ``MarkerFactory``, która zwróci marker dla zadanego symbolu, np ``CircleMaker`` dla symbolu ```o```. Aby umożliwić zautomatyzowaną produkcję znaczników, kompletna implementacja fabryki wymaga również stworzenia klas-procucentów (*makers*), czyli ``CircleMakerMaker``, ``SquareMakerMaker``, itd. Producenci powinni dziedziczyć po wspólnej abstrakcyjnej klasie bazowej. Program testowy --------------- Końcowa implementacja musi poprawnie działać napisaną wcześniej klasą ``Plot``. Zauważ, że poniższy program testowy wymaga napisania własnego znacznika, odpowiedniego producenta (*maker*) i zarejestrowania tego ostatniego w fabryce. Na przykład, ``MyMaker`` może być rombem (``DiamondMarker``) .. code-block:: python import math from plot import Axes, Plot from svg_shapes import Style from markers_factory import AbstractMarker, AbstractMaker class MyMakerMaker(AbstractMaker): # Tu zaimplementuj swój znacznik pass class MyMaker(AbstractMarker): # Tu zaimplementuj maker do znacznika pass axes = ( Axes("ax1", 80, 40, 580, 260) .bottom(0.0, 360) .left(-1.1, 1.1) .top(0.0, 360) .right(-1.1, 1.1) .with_xticks(6) .with_yticks(4) .with_grid(True) .with_stroke("black") .with_stroke_width(1.5) ) x = [i for i in range(0, 370, 10)] ys2 = [math.sin(v*3.14159/180.0)**2 for v in x] pl = Plot(axes) pl.define_new_marker('M', MyMakerMaker()) sin2_style = Style(fill="#a6cee3", stroke_width=1.5, stroke="#1f78b4") pl.scatter(x, ys2, marker="M", style=sin2_style) pl.save_fig("plot_with_marker.svg") Wynik powinien przypominać wykres z poprzedniego ćwiczenia.