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)
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.