Markdown – czyli o dodawaniu lukru do notebooków

Jak to w życiu bywa, nie wystarczy czegoś dokonać, żeby trafiło to do większej liczby osób. Nie chodzi mi tutaj o robienie czegoś na pokaz i promowanie nic nieznaczących wyników. Chodzi mi bardziej o to, że (moja hipoteza) na świecie cały czas powstają publikacje, książki, artykuły, grafiki i nagrania, które trafiają do szuflady, bo ich „esencja” jest zbyt głęboko ukryta. Wynika to może z tego, że coraz bardziej skłaniamy się (obywatele „pierwszego świata”) ku łatwej, przystępnej i co najważniejszej szybkiej formie przyswajania informacji. A taką formę najłatwiej osiągnąć, jeśli treść jest krótka. Nie bez powodu Twitter na stałe zakorzenił się we współczesnej komunikacji, a wyrażenie tl;dr stało się niemalże hasłem słownikowym. Ma być krótko, żebym w ogóle się zainteresował. Ale jeśli nie da się czegoś zrobić krótko, to może da się zrobić przystępniej?

Pamiętam jak na przełomie liceum/studiów miałem okazję wakacyjnie pracować przy sprzedaży podręczników szkolnych. Poprzeglądałem je sobie i na początku odłożyłem z odrazą. Tyle kolorów, tyle różnych stylów, obrazków, wykresów? Gdzie podziały się jednolite bloki tekstu niepodzielone na sekcje. Czy ktoś to w ogóle może przeczytać? Jak tak można. Później jednak przeglądałem sobie te podręczniki „z nudów” i im dłużej to robiłem, tym bardziej zmieniałem moje nastawienie. Oczywiste było, że na pierwszy rzut oka, „esencjonalnej” treści było mniej. Ale wszystkie te dodatkowe informacje, nieformalne wyjaśnienia, podobne przykłady dodawały masę sensu. No i dziś (od jakiegoś czasu już), moje nastawienie się zmieniło tak bardzo, jak to możliwe. Esencja materiału esencją, ale co Ci po niej, jak nikt nie jest w stanie się do niej wgryźć. Trzeba dodać trochę lukru.

W pracy z danymi prawie zawsze chcemy rozwiązać jakiś problem. Jeśli robimy to dla siebie, to nie ma trudności, możemy zupełnie pominąć lukier i zajmować się tylko konkretami. Jeśli jednak chcemy pokazać komuś wyniki albo kogoś nauczyć czegoś nowego to powinniśmy się zastanowić, czy nie jesteśmy za bardzo „patrzcie, jaki jestem mądry”, a za mało „patrzcie, jakie to proste”. To pierwsze podejście szczególnie dało mi się we znaki w środowisku akademickim. Nietaktowne było tam napisanie publikacji, którą wszyscy są w stanie zrozumieć. Przyjęło się, że jeśli publikacja jest pisana prostym językiem i jest zbyt „łatwa” to mogą pojawić się zarzuty, że każdy byłby w stanie to zrobić i że może zostać cofnięte fundowanie badań. Natomiast jeśli używało się trudnych słów i długich zdań pisanych bezosobowo w czasie przeszłym, to publikacje brzmiały niczym prawda objawiona. A jak jeszcze miała dużo stron i skomplikowanych wykresów to już w ogóle szykowała się prawdziwa gratka. Ja akurat robiłem sobie MOOC Writing in the Sciences (gorąco polecam) i bardzo chciałem (o naiwności), żeby każdy mógł wziąć moją publikację, zaczepić mnie w tramwaju i pogadać. Nie dało się tak jednak (z wyżej wspomnianych „politycznych” powodów). Postanowiłem sobie wtedy, że jak tylko będę miał wolną rękę, to wszystko, co będę chciał przekazać, zawsze będę starał się upraszczać. I lukrować, tak żeby tylko omawiany problem był problemem, a nie moje podejście do niego. I nie mówię tutaj o usuwaniu trudnej informacji, żeby było ładnie, tylko o dodawaniu i rozbudowywaniu kontekstu. Żeby było łatwiej. Tak, uważam, że informacja nie musi być trudna, żeby była przydatna.

Wracając do głównego wątku, jak być może zauważyłeś, przykłady, które publikuję na blogu, zawsze bazują na notebookach Jupyter. Od kiedy trafiłem na to IDE, prawie cały czas spędzam, korzystając z niego. Fakt, tworzenie np. produkcyjnych platform do obsługi back-endu usług jest praktycznie niewykonalne z poziomu tego IDE (jest możliwe, ale byłby to kosztowny błąd). Natomiast przygotowywanie publikacji, objaśnianie jakiejś koncepcji, szybkie prototypownie rozwiązania problemu data science albo pisanie książki – to są aktywności, w których Jupyter Notebook błyszczy. Jednym z elementów składowych tego narzędzia które to umożliwiają jest wspieranie języka znaczników Markdown.

Markdown

Pierwsza specyfikacja języka Markdown została opublikowana w marcu 2014 roku. Najnowsza natomiast w grudniu 2014 roku. Jak widać, niektóre koncepcje „rodzą się” niemalże idealne. Czy tak było w tym przypadku? Niekoniecznie. Po prostu pierwotna wersja Markdown przestała być wtedy rozwijana, jest natomiast używana jako fundament wielu kolejnych projektów, które już dalej żyją swoim własnym życiem.

Czym więc jest ten Markdown? Jest to język znaczników. W przeciwieństwie do języków programowania, język ten nie umożliwia transformacji danych (np. wyznaczenia wyniku operacji 2 + 2), a pozwala kontrolować sposób, w jaki te dane są wyświetlane (np. 2 + 2). Jeżeli czytasz ten tekst, to znaczy, że gdzieś pomiędzy Tobą a mną zadział się proces interpretacji języka znaczników HTML. Bo oprócz naciskania odpowiednich klawiszy na klawiaturze, przekazałem jeszcze WordPressowi, jak niektóre literki mają wyglądać. A WordPress oprócz zapisania literek, które nacisnąłem (dane), zapisał sobie także informację, które mają być większe, mniejsze, pochyłe (znaczniki). Fajne nie?

Wspomniałem tutaj o języku znaczników HTML. Szacuje się, że HTML jest najpopularniejszym językiem znaczników. Po co nam więc Markdown? Cóż, miałeś może drogi czytelniku okazję używać czystego HTML do pracy z tekstem? Jeśli robiłeś strony internetowe na przełomie milenium, to pewnie tak. Szacuję na ~95%, że już tego nie robisz. Oczywiście, jeśli budujesz front-end to jest to twój chleb powszedni (ale i tak proces klepania tych znaczników różni się znacząco od „otwórz notatnik i jazda”). Jednym z powodów, dla którego nie piszemy w HTML, jest to, że jest on dość toporny. Znaczniki są dość spore (całe słowa), trzeba pilnować zagnieżdżenia, a sam teks źródłowy, jest dość nieczytelny.

I z tych powodów mniej więcej powstał Markdown. Miało być szybko (symbole jako znaczniki), łatwo (zagnieżdżanie przez wcięcia) i czytelnie (źródłowy Markdown wygląda jak zwykły tekst). I całkiem nieźle się to udało.

Co najważniejsze, Markdown jest możliwy do ogarnięcia w około 60 sekund, korzystając np. z Wikipedii albo samouczka. A kto wie, może sam już z niego korzystasz?

Markdown a Jupyter

Okej, skoro wiemy już, że Markdown jest spoko, to jak możemy go użyć wewnątrz notebooka Jupyter? Sprawa jest prosta. Tworzymy sobie nową komórkę, w której będziemy umieszczać nasz tekst. Podświetlamy ją (obojętnie czy tylko zaznaczymy, czy będziemy ją edytować) i z odpowiedniego menu zmieniamy jej typ:

Komórka Markdown
Komórka Markdown

Wtedy znika nam licznik w tej komórce i możemy śmiało pisać i używać znaczników Markdown. Jeśli jesteśmy w trybie edycji, to wciąż mamy zwykły tekst i okazjonalne podpowiedzi jak będzie on wyglądał. Jeśli wykonamy komórkę (Shift + Enter) to nasz tekst i Markdown zostaną zinterpretowane i odpowiednio wyświetlone. Przykład znajduje się tutaj.

Alternatywy

Oczywiście, jak to zwykle bywa w świecie open source, mamy całą masę alternatyw, które pozwalają osiągnąć podobne efekty. Poniżej lista tych, które wydawały mi się warte odnotowania:

  • reStructuredText – język znaczników dość podobny do Markdown. Używany jako standard w dokumentowaniu kodu Pythona. Widzimy więc tutaj pewien konflikt – jak działasz w notebooku, to lukruj w Markdown, a jak piszesz produkcyjny kod, to lukruj w reStructuredText. Cóż, w życiu trzeba czasem wybrać jakiś standard.
  • LaTeX – duży kaliber. System składu tekstu wraz z systemem znaczników. Bardzo popularny w środowiskach akademickich m.in. dlatego, że pozwala bardzo wygodnie pracować z formułami matematycznymi oraz „kompilować” gotowe dokumenty, które mogą być np. publikacjami, plakatami na konferencje oraz prezentacjami. Problem jest jednak taki, że wraz z wielką mocą dostaliśmy też tutaj wielkie skomplikowanie. Może więc być odstraszający dla początkujących.
  • GitHub Flavored Markdown – rozszerzenie Markdown proponowane przez serwis GitHub. Używane np. w plikach README umieszczanych w publicznych repozytoriach na GitHub. Czy jest to pełna alternatywa – raczej nie. Ale pomyślałem, że warto tutaj ją umieścić.
  • MediaWiki markup – jeżeli zdarzyło Ci się kiedyś edytować Wikipedię, to zauważyłeś pewnie, że jest tam obecny osobny system znaczników. Tak, Wikipedia ma też swój język znaczników. Nie widziałem go co prawda poza systemami Wiki, ale jeśli planujesz podzielić się swoją pracą poprzez artykuły na Wikipedii, to również warto się zapoznać z tym językiem.
  • HTML – bo dlaczego nie? Jeśli chcesz przedstawić coś z w pełni kontrolowaną interakcją, to HTML + CSS + JS dają całkiem niezłe pole do popisu. Nie jest to co prawda sprawa łatwa i szybka, ale powyższe rozwiązania mogą niekoniecznie być wystarczające we wszystkich sytuacjach.
  • The Jupyter Notebook Format – w tej chwili zataczamy niejako koło, bo notebooki Jupyter są plikami JSON z konkretnym systemem znaczników. Mamy wiec język znaczników, wewnątrz języka znaczników. Faktem jest, że ręczne edytowanie plików ipynb (pliki notebooków) jest zadaniem karkołomnym, ale możemy je np. poprawiać za pomocą skryptów z wyrażeniami regularnymi. Więc kto wie, może sam będziesz korzystał z tej możliwości.

Jeden, by wszystkimi rządzić

Okej, wiemy już, jak możemy lukrować nasz kod analizy przed pokazaniem go światu. Wiemy też, że mamy całą masę języków znaczników, które możemy użyć w swoim projekcie. A projekt firmowy, do którego dołączyliśmy właśnie, używa pewnie jeszcze czegoś innego. Jak w tym wszystkim się połapać i użyć na naszą korzyść? Najfajniej jest (sarkazm ;-)), jeśli mamy już jakiś tekst w jednym języku i musimy go na szybko przenieść do innego języka, nie tracąc całej „otoczki”. Spokojnie, nie jest wbrew pozorom aż tak źle. Skoro są to języki znaczników, to tekst przy wyświetlaniu jest wynikiem interpretacji tych znaczników. Możemy więc stworzyć konwerter, który będzie „tłumaczył” Markdown na HTML. I w drugą stronę również.

Efektem tego podejścia jest narzędzie zwane pandoc. Narzędzie pandoc to między innymi konwerter pomiędzy językami znaczników. Co ciekawe pozwala również na konwersję pomiędzy plikami OpenOffice i Microsoft Word. Oprócz konwersji w dwie strony pozwala również tworzyć m.in. pliki pdf i epub. Jest to więc szwajcarski scyzoryk, jeśli chodzi o konwersję pomiędzy formatami tekstu, co całkiem czytelnie pokazuje poniższy obrazek:

Diagram konwersji pandoc
Diagram konwersji pandoc

Podsumowanie

W celu jak najlepszego przekazania komuś wiedzy/informacji możemy i powinniśmy stosować „lukrowe” dodatki, które lepiej opisują tę wiedzę/informację. Kod, jaki jest, każdy widzi, prawie nigdy jednak nie widać co ten kod ma robić. Warto więc okrasić go w odpowiedni sposób. Jeśli piszemy czysty kod Python, to możemy używać np. języka reStructuredText. Jeśli śmigamy w Jupyter Notebookach, to Markdown będzie naszym przyjacielem. Jeśli jesteśmy fanami RStudio, to też nie powinniśmy poczuć się pokrzywdzeni, bo mamy tam R Markdown. Nie da się umieścić wzoru w prezentacji – LaTeX. Wciąż nam czegoś brakuje – HTML. Sądzę, że trudno jest w dzisiejszych czasach znaleźć dobrą wymówkę, dlaczego prezentujemy goły blok kodu, a kontekst uzupełniamy przez machanie rękami na żywo. Jeśli jeszcze więc nie myślałeś o sensownym opisywaniu kodu, to proponuję Ci zacząć od komórek Markdown w notebookach Jupyter – czasem te komórki mogą znaczyć więcej niż sam kod, który znajduje się w okolicy ;-).

O czym chciałbyś przeczytać na blogu?

Jestem w miejscu, w którym mam notatnik wypełniony pomysłami na artykuły co najmniej na najbliższe pół roku. Regularnie też staram się przechwytywać wasze czytelnicze potrzeby. Trochę się to jednak zaczyna komplikować z mojej strony. Pomyślałem więc, że przygotuję dla Ciebie stronę w serwisie tricider, na której będziesz mógł a) zaproponować temat, o którym z chęcią byś poczytał, b) przejrzysz listę takich propozycji od innych osób i będziesz mógł je podbić w celu zasygnalizowania mi, że temat jest gorący, oraz c) skomentować pomysł i być może dopisać, dlaczego jest on sensowny, bądź wskazać argumenty, dlaczego nie warto go poruszać. Głosować można tutaj.

Zachęcam do naprowadzenia mnie na Twoje potrzeby :-)!

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *