Projekt Matplotlib

Ta strona zawiera szczegółowe informacje na temat projektu dotyczącego pisania technicznego zaakceptowanego do udziału w sezonie Dokumentów Google.

Podsumowanie projektu

Organizacja open source:
Matplotlib
Pisarz techniczny:
Brunobeltran
Nazwa projektu:
Poprawa wykrywalności cech przez standaryzację dokumentacji typów niejawnych
Długość projektu:
Długotrwałe (5 miesięcy)

Opis projektu

Motywacja

W przeszłości interfejs API matplotlib w dużej mierze opierał się na „typach niejawnych” typu „string-as-enum”. Ciągi parametrów nie tylko naśladują interfejs API matlab, lecz także umożliwiają użytkownikowi przekazywanie wartości o dużej zawartości semantycznej w postaci argumentów do funkcji matplotlib bez konieczności importowania lub szczegółowego poprzedzania rzeczywistej wartości wyliczeniowej w celu przekazywania podstawowych opcji wykresu (np.plt.plot(x, y, linestyle='solid') jest łatwiejszy do wpisania i mniej nadmiarowy niż np. plt.plot(x, y, linestyle=mpl.LineStyle.solid)).

Od tego czasu wiele z tych rodzajów niejawnych wyrażeń typu „string as-enum” rozwinęło się w bardziej zaawansowanych funkcjach. Na przykład linestyle może być teraz ciągiem znaków lub 2 tupką sekwencji, a element znaczników może być ciągiem tekstowym lub matplotlib.path.Path. Chociaż tak się dzieje w przypadku wielu niejawnych typów, MarksStyle jest (o czym znam) jako jedyny, który ma stan uaktualnienia do odpowiedniej klasy Pythona.

Ponieważ te typy niejawne nie są klasami własnymi, firma Matplotlib musiała do tej pory wdrażać własne rozwiązania do scentralizowanej dokumentacji i sprawdzania tych typów niejawnych (np. wzorca interpolacji ciągu tekstowego docstring.interpd.update i odpowiednio wzorca walidatora cbook._check_in_list), zamiast korzystać ze standardowych łańcuchów narzędzi dostarczanych przez klasy języka Python (np.__init__

Te rozwiązania się sprawdziły w naszym przypadku, ale brak wyraźnego miejsca pozwalającego udokumentować każdy niejawny typ oznacza, że często trudno jest znaleźć odpowiednią dokumentację. W dokumentacji powtarzają się duże tabele dozwolonych wartości, a w dokumentacji często brakuje wyraźnego określenia zakresu typu niejawnego. Weźmy na przykład dokumenty plt.plot: w sekcji „Notatki” opis metody stylizacji ciągu znaków w formacie matlab przypomina o opcjach linestyle, color i markers. Istnieje znacznie więcej sposobów przekazywania tych 3 wartości, ale dla wielu użytkowników jest to jedyne źródło wiedzy o wartościach dostępnych w przypadku tych opcji, dopóki nie natrafią na jeden z odpowiednich samouczków. Zawarta jest w nim tabela atrybutów Line2D, której celem jest przedstawienie czytelnikowi dostępnych opcji kontrolowania wykresu. Mimo że wpis linestyle dobrze sprawdza się jako łącznik z elementem Line2D.set_linestyle (wymagane są 2 kliknięcia), gdy opisane są możliwe dane wejściowe, wpisy color i markers nie. color po prostu łączy się z usługą Line2D.set_color, która nie instruuje, jakie rodzaje danych wejściowych są w ogóle dozwolone.

Można argumentować, że taki problem można rozwiązać, usuwając po prostu pojedyncze ciągi dokumentów, które powodują problemy. Niestety, problem ten jest niepotrzebnie bardziej systemowy. Brak jednego miejsca na dokumentację prowadziłoby do tego, że wszędzie powtarzano coraz więcej kopii coraz bardziej szczegółowej dokumentacji wszędzie tam, gdzie używane są poszczególne typy niejawne, co utrudnia początkującym użytkownikom po prostu znalezienie potrzebnego parametru. Jednak obecny system, który zmusza użytkowników do stopniowego łączenia modeli mentalnych każdego z nich na podstawie informacji w naszej dokumentacji lub fragmentów pochodzących ze StackOverflow, również nie jest zrównoważony.

Cel końcowy

Najlepiej, gdy wzmianka o typie niejawnym powinna odsyłać do jednej strony, która zawiera wszystkie możliwe wartości, jakie może przyjąć dany typ, uporządkowaną od najprostszych i najpowszechniejszych do najbardziej zaawansowanych lub ezoterycznych. Zamiast wykorzystywać cenną przestrzeń wizualną w najwyższej dokumentacji interfejsu API do szczegółowego wyliczenia wszystkich możliwych typów danych wejściowych dla określonego parametru, możemy użyć tej samej przestrzeni, aby podać jasny opis tego, jaką abstrakcję nanoszenia ma kontrolować dany parametr.

Wróćmy do przykładu z tabelą linestyle. Dokumenty LineCollection powinny zawierać po prostu:

  1. Link do dokumentacji dotyczącej dozwolonych danych wejściowych (kombinacji danych w Line2D.set_linestyle i samouczku stylu linii).
  2. Prosty opis tego, do czego służy dany parametr. W przypadku zaawansowanych użytkowników matplotlib jest to jasne w nazwie parametru, ale w przypadku nowych użytkowników nie musi tak być.

W rzeczywistych dokumentach LineCollection wygląda to tak: python """""" linestyles: `LineStyle` or list thereof, default: :rc:`lines.linestyle` ('-') A description of whether the stroke used to draw each line in the collection is dashed, dotted or solid, or some combination thereof. """""", gdzie Sphinx zajmie odniesienie do typu LineStyle, by wskazać pojedynczy, wiarygodny i kompletny zestaw dokumentacji dotyczącej sposobu, w jaki Matplotlib traktuje style linii.

Zalety

Ważnymi zaletami tego podejścia są m.in.

  1. Trzeba w pełni ujednolicić funkcje każdej z funkcji w postaci zwykłego tekstu (bez kliknięć).
  2. Pokazywanie opcji domyślnej (bez kliknięć). Widać często, że jest to opcja domyślna, aby wykorzystać pamięć powracających użytkowników.
  3. Stwórz pełny opis „najczęstszych” i „najprostszych” opcji parametru, które są łatwo dostępne podczas przeglądania stron internetowych za pomocą jednego kliknięcia.
  4. Odkrywanie bardziej zaawansowanych funkcji i metod wprowadzania powinno być jak najłatwiejsze, jak np. „przewiń w dół”, aby zobaczyć bardziej zaawansowane opcje (wystarczy jedno kliknięcie).
  5. Udostępnij scentralizowaną strategię łączenia dokumentów „API” najwyższego poziomu z odpowiednimi „samouczkami”.
  6. Unikaj eksplozji w postaci dokumentów z użyciem interfejsu API, ponieważ skanowanie wielu możliwych opcji każdego parametru sprawia, że poszczególne ciągi dokumentów bywają nieporęczne.

Inne zalety tego podejścia w porównaniu z obecnymi dokumentami:

  1. Dokumenty rzadziej stają się nieaktualne ze względu na centralizację.
  2. Konwertowanie kanoniczne wielu „ukrytych standardów” (takich jak „granice” i „zakresy”) matplotliba, których należy się obecnie opanować poprzez odczytanie kodu.
  3. Proces wyróżnia problemy ze spójnością interfejsów API w sposób, który można łatwiej śledzić za pomocą narzędzia do śledzenia błędów na GitHubie, co ułatwia ulepszanie naszego interfejsu API.
  4. Szybsze tworzenie dokumentów ze względu na znaczne zmniejszenie ilości tekstu wymagającego analizy.

Implementacja

Opisane wyżej ulepszenia będą wymagały 2 dużych nakładów, a własny twórca techniczny będzie nieoceniony. Pierwsza to 1 scentralizowana strona „tutorial” dla każdego typu niejawnego. Wymaga to współpracy z głównym zespołem programistów w celu opracowania konkretnej listy typów niejawnych, których dokumentacja będzie przydatna dla użytkowników (zwykle dlatego, że zawierają one zaawansowane, ukryte funkcje naszej biblioteki, której dokumentacja jest obecnie dostępna tylko w przypadkach, w których trudno znaleźć samouczki). W przypadku każdego typu niejawnego łączę różne odpowiednie samouczki, dokumenty API i przykładowe strony w jedno wiarygodne źródło dokumentacji, które można połączyć ze wszystkimi elementami, w których pojawia się dany typ treści.

Po utworzeniu scentralizowanej dokumentacji danego typu niejawnego rozpocznie się drugi główny etap: zastąpienie dotychczasowej dokumentacji interfejsu API linkami do nowej dokumentacji w taki sposób, aby korzystanie z nowej dokumentacji było jak najłatwiejsze zarówno dla osób korzystających z wbudowanego narzędzia help() Pythona, jak i dla osób przeglądających naszą dokumentację online.

Chociaż proponowany tu format dokumentacji może się zmieniać w miarę rozwoju projektu, podczas cotygodniowych „rozmów z deweloperami” Matplotlib współpracowałem z zespołem głównym Matplotlib, aby uzgodnić, że zaproponowana tu strategia jest najbardziej efektywnym, przydatnym i technicznie łatwym do znalezienia podejściem do rozpoczęcia dokumentowania tych „typów działań” (uwagi na temat tych połączeń są dostępne). dostępne są uwagi Wykorzystam istniejącą infrastrukturę „samouczki” do początkowych etapów tworzenia scentralizowanej dokumentacji dla każdego typu niejawnego, co pozwoli mi łatwo odwoływać się do tych stron w następujący sposób, bez konieczności tworzenia nowych klas publicznych (ponownie, używając jako przykład dokumentacji LineCollection):

""""""
linestyles: LineStyle or list thereof, default: :rc:`lines.linestyle` ('-')
    A description of whether the stroke used to draw each line in the collection
    is dashed, dotted or solid, or some combination thereof. For a full
    description of possible LineStyle's, see :doc:`tutorials/types/linestyle`.
""""""

W przyszłości moglibyśmy łatwo zmienić pisownię tych odniesień, gdy główny zespół programistów ustali najlepszą długoterminową strategię włączania naszej nowej dokumentacji „typów” do rzetelnych klas Pythona, np. zgodnie z propozycją ulepszenia Matplotlib 30.

Na koniec wstępna lista rodzajów niejawnych typów dokumentów, które proponuję dokumentować w tym sezonie Dokumentów Google:

  1. capstyle
  2. joinstyle
  3. bounds
  4. extents
  5. linestyle
  6. colors/lists of colors
  7. colornorm/colormap
  8. tick formatters

Obecną wersję tego dokumentu znajdziesz na naszej stronie.