Tańczące roboty: gra edukacyjna dla dzieci. Słowo o kontroli wersji i licencjach.

Zagrajmy w grę z dziećmi. Czas na trochę informatyki bez komputerów. ...

5 years ago, comments: 3, votes: 82, reward: $4.87

Zagrajmy w grę z dziećmi. Czas na trochę informatyki bez komputerów.

A picture of a dancing robot
Źródło: Pixabay

English version here

Zazwyczaj spędzamy lato z moją rodziną w Polsce. Potrzeba sporo wysiłku, aby siedmioro dzieci w wieku 4-10 lat bawiło się razem i bez tabletów. W zeszłym roku przygotowałem tę grę i nazwałem ją "Tańczące roboty".

Celem gry jest wykorzystanie szeregu umiejętności, aby przygotować taniec, a potem go zatańczyć. Dzieci zaczynają od ułożenia bloków z instrukcjami w zapis choreografii.

Przykładowa choreografia

Już kiedyś opublikowałem tę grę po polsku na koncie Breadcentric. Tym razem jednak przetłumaczyłem ją również na język angielski i dodałem kilka klocków. Ponadto umieściłem ją pod kontrolą wersji i nadałem jej licencję Creative Commons (CC BY-SA 4.0) aby wszyscy mogli z niej korzystać i wprowadzać do niej zmiany. Zarówno kontrola wersji jak i temat Creative Commons został wyjaśniony nieco poniżej.

Gra jest dostępna tu: https://github.com/kurykodowe/dancing-robots - wystarczy że pobierzesz plik pdf z grą i wydrukujesz. Miłej zabawy!

Wszystkie instrukcje są dostępne w pliku README.md: https://github.com/kurykodowe/dancing-robots/blob/master/README.md#pl-tańczące-roboty

Skorzystaj z podanych instrukcji i baw się dobrze! U nas dzieci bawiły się wspólnie około 30 minut zanim się znudziły.

Jeśli chcesz mieć swój udział w projekcie, serdecznie zapraszam. Szczególnie jeśli znasz inne języki. Jeśli chcesz dodać coś od siebie, przeczytaj instrukcje na ten temat w pliku README. Ponadto poniżej jest wyjaśnienie, czym jest kontrola wersji, mam nadzieję, że się przyda. W razie czego serdecznie zapraszam do zadawania pytań w komentarzach. Zdaję sobie sprawę z tego, że to ta cała techniczna strona może być przerażająca. Jeśli chcesz dodać do projektu coś od siebie, napisz o tym w komentarzu, z przyjemnością pomogę. Przy okazji będziemy mogli przygotować wspólnie wpis o pomocy projektom otwartym.

Czym jest kontrola wersji?

W czasie pracy nad projektem, a także podczas jego utrzymywania i dalszego rozwoju, wiele ulega zmianie. W przpadku programów zazwyczaj zmieniane są pliki tekstowe z kodem, konfiguracją i danymi. Każda modyfikacja zachowania wymaga zmiany w plikach, często w wielu jednocześnie. Kiedy zespoły pracują nad danym projektem, ich członkowie mogą dodawać nowe rzeczy w wielu obszarach. Miło byłoby mieć własną prywatną przestrzeń do pracy bez wchodzenia sobie w drogę. Kiedy cała modyfikacja jest gotowa, przydałby się sposób, aby ją połączyć z projektem. A gdy już wszystko zostanie przygotowane, warto byłoby mieć jak oznaczyć ten stan w kodzie, aby móc do niego wrócić w przyszłości, na przykład aby poprawić zgłoszony problem i zidentyfikować te wersje projektu, które także wymagają naprawy.

To właśnie daje nam kontrola wersji. Jest wiele dbających narzędzi. Jedne są darmowe (w tym też open source), inne płatne, jedne zcentralizowane, inne rozproszone.

  • open source (oprogramowanie otwarte) - projekt jest dystrybuowany jako narzędzie, z którego można korzystać, a także jako kod, z którego to narzędzie zbudowaneo. Zazwyczaj projektu nie można od tak zamknąć i jeśli ktoś inny z niego korzysta, musi o tym informować. Często liderzy takich projektów akceptują i zachęcają do zgłaszania własnego wkładu ze strony osób nie pracujących na co dzień nad nimi. Niektóre narzędzia kontroli wersji udostępniają narzędzia, aby względnie łatwo dodać taką zmianę do projektu
  • system scentralizowany - rodzaj systemu, w którym jest jakiś centralny byt (węzeł), odpowiedzialny za trzymanie prawdy jedynej i najprawdziwszej. W przypadku kontroli wersji musi on istnieć, aby dało się zapisać fakt wystąpienia zmiany
  • system rozproszony - rodzaj systemu, w którym każdy węzeł jest w jakiś sposób niezależny od pozostałych i zapewnia pewien poziom fukcjonalności. Może występować również węzeł centralny, używany do wymiany informacji i do przechowywania współdzielonego stanu, ale takich centralnych bytów może być więcej, a także pojedyncze węzły mogą razem wypracowywać wspólny stan bez takiego centralnego

Ja zazwyczaj korzystam z gita. Git to rozproszony, otwarty system kontroli wersji. Został stworzony przez Linusa Torvaldsa, gościa znanego między innymi z utworzenia systemu operacyjnego Linux.

Z gitem jest stosunkowo łatwo zacząć (jak już jest zainstalowany). Powiedzmy, że chcę utworzyć repozytorium pod kontrolą wersji i umieścić w nim program, który będzie mówił "Hello". Powiedzmy też że napiszę ten program w języku programowania Python. Kod wygląda tak:

print("Hello!")

Bardzo skomplikowane, wiem. nie będę wchodził nadmiernie w szczegóły jeśli chodzi o to, co ten bardzo złożony zbiór poleceń. Python pozwala mi uruchomić to polecenie w interpreterze (takim narzędziu, które bierze to co napisałem i uruchamia):

Interaktywna konsola interpretera Pythona

Super! Utwórzmy zatem repozytorium. Będę potrzebował folderu na moim komputerze:

Tworzenie folderu

Pewnie zauważyliście, że preferuję pracę w trybie tekstowym, a nie z okienkami i myszkami. Większość zadań, które wykonuję, jest dostatecznie prostych aby je tak wykonywać błyskawicznie, dodanie do tego klikania byłoby bardziej czasochłonne. Z czasem łatwo zapamiętać polecenia. Czasem wolę narzędzia z interfejsem użytkownika, jeśli dodaje on wygody użytkowania.
Utworzyliśmy folder hello (polecenie mkdir), weszliśmy do niego (polecenie cd) i wyświetliliśmy zawartość (polecenie ls -la) - czyli nic, w końcu dopiero co go utworzyliśmy. Element . reprezentuje bieżący folder hello, a .. reprezentuje katalog nadrzędny dev, z którego tu przyszliśmy. To nie ma większego znaczenia w tym momencie. Większe znaczenie ma to, że chcemy mieć repozytorium:

Tworzenie repozytorium

Teraz mamy folder .git wewnątrz hello. Kropka na początku nazwy pliku/katalogu w Linuksie (z którego tak się składa że korzystam) czyni go ukrytym. Jeśli pominę opcje w poleceniu ls, zobaczymy to:

Wyświetlenie zawartości katalogu bez ukrytych plików

Widzicie to? Nic.
Kontynuujmy. Nasze repozytorium jest puste i przydałby nam się tu nasz program. Utwórzmy dla niego plik. Użyję edytora tekstu zwanego vim aby umieścić w pliku treść. Plik nazwiemy hello.py. Komenda cat wyświetli zawartość pliku:

Tworzenie hello.py

Super. Czy plik jest już pod kontrolą wersji? Nie. Przyczyna jest prosta: musimy powiedzieć, że plik ma być trzymany w historii repozytorium. git status pokazuje status projektu w porównaniu z ostatnim zapisanym stanem:

Sprawdzanie statusu repozytorium

Git czasem pokazuje przydatne rady, tak jak w tym przypadku: musimy użyć git add:

Dodanie hello.py pod kontrolę wersji

Teraz musimy zapisać obecną zmianę (czyli dodanie nowego pliku) do gita. Użyjemy do tego polecenia git commit z opisem "Added hello.py":

Zapisanie pierwszych zmian

git status już nie pokazuje naszego pliku jako nowego - mówi że jesteśmy na gałęzi master (powiedzmy tylko że to jest jakby główna linia zmian w kodzie), a git log wyświetla nasz pierwszy commit (czyli zapisany zbiór zmian). A, zapomnieliśmy uruchomić program. Zobaczmy jak działa:

Hello.py uruchomiony po raz pierwszy

Ojej! Nie umiem pisać. Naprawmy to:

Hello.py naprawiony i uruchomiony po raz wtóry

Już lepiej. Zapiszmy zmiany w gicie:

Commit poprawki

Teraz mamy już dwie zmiany w historii.
Jak widzicie, nasz program jest bardzo użyteczny. Powinienem nim podzielić się ze światem. W tym celu potrzebuję publicznie dostępnego repozytorium. Jest kilka usług, które na to pozwalają. Ja skorzystam z https://github.com. Będziemy musieli utworzyć tam repozytorium. Zalogowałem się, poszedłem na https://github.com/new i wypełniłem formularz:

Tworzenie repozytorium w GitHub

Następnie otrzmujemy listę podręcznych poleceń, z których możemy skorzystać:

GitHub new repository instructions

Podsumujmy szybko co mamy: jest repozytorium git lokalnie na moim komputerze i jakieś repozytorium git gdzieś tam. Nie wiedzą nic o sobie. Podane polecenia pasują do kilku scenariuszy, takich jak użycie zdalnego repozytorium, aby rozpocząć pracę lokalnie, czy wskazanie zdalnego repozytorium jako adresu do wysyłania lokalnych zmian. My chcemy to drugie.
Wykonałem polecenia i proszę bardzo:

Wypchnięcie zmian do zdalnego repozytorium

git push to polecenie służące do wysłania zmian do zdalnego repozytorium.
Pójdźmy do https://github.com/kurykodowe/hello i spójrzmy jak to wygląda:

Ujęcie z repozytorium github

Github to więcej niż tylko zdalne repozytorium, z którego inni mogą sobie pobrać kod. Inni mogą też wprowadzać zmiany do projektu i mają do tego narzędzia. Aby im trochę pomóc, możemy dodać trochę informacji o projekcie. Zazwyczaj robi się to w pliku README.md. md oznacza Markdown - jest to format plików tekstowych, który dodaje trochę stylu wyświetlanym treściom (FUN FACT: Ten tekst został również napisany z użyciem Markdown). Na obrazku powyżej widać, że mogę dodać ten plik przez stronę. Skorzystam z tego i dodam treść:

# hello
This project is an extremely useful utility printing "Hello".

Feel free to contribute.

Oto co otrzymujemy:

Widok repozytorium na github z plikiem readme

Już prawie skończyliśmy, jest tylko jeden problem - nie spełniamy pierwotnego wymagania: mieliśmy wypisywać "Hello", a wypisujemy "Hello!". Jak wspomniałem, Github pozwala nam zrobić wiele rzeczy. Zgłośmy zatem błąd, korzystając z sekcji "Issues" na stronie repozytorium:

Widok zgłoszonego błędu

Opis błędu dostępny jest pod adresem: https://github.com/kurykodowe/hello/issues/1 (opis pod tym adresem nie będzie wyglądał tak jak powyżej, zdradzę Wam tajemnicę: naprawimy to).
Jako autor bardzo użytecznego narzędzia nie mogę pozwolić na to, żeby zawierało ono błąd. Naprawmy to.

Oczywiście w tym przypadku mamy bardzo malutki projekt i moglibyśmy go naprawić tak jak powyżej, ale zróbmy to tak, jak to się robi przy nieco większych projektach, gdzie wiele osób może jednocześnie wprowadzać zmiany. Zrobimy to:

  • pobierzemy najnowszą wersję kodu
  • założymy nową gałąź kodu
  • naprawimy na niej błąd
  • utworzymy pull request (zaraz o tym trochę powiem)
  • połączymy gałąź z główną linią

Musimy pobrać kod ponieważ wykonaliśmy w nim zmiany dodając readme. Popatrz:

Pobranie kodu

Przed git pull mieliśmy jeden plik, teraz mamy dwa. Historia również uległa zmianie:

Git log ze zmianą dodającą readme

Teraz utworzymy gałąź fix-wrong-printout poleceniem git checkout -b fix-wrong-printout i naprawimy kod:

Naprawa

Pozostaje nam wysłać poprawkę do oceny i dodania do głównej linii kodu:

Wypchnięcie kodu na github

Jeśli popatrzymy na GitHub, znajdziemy dwie gałęzie:

Widok gałęxi

Możemy również utworzyć pull request. Jest to sposób na powiedzenie: cześć, to jest gałąź, zrobiłem na niej poprawki, czy ktoś mógłby to sprawdzić i włączyć do głównego kodu na gałęzi master? Jedni mają możliwość zapisywania zmian w repozytorium, inni nie. Jeśli nie ma się takich uprawnień, pull request jest sposobem na poproszenie, aby przyjąć przygotowane zmiany do projektu.
Zaraz pewnie zapytasz: Chwila moment, jak można wprowadzić zmiany na gałęzi jeśli nie można zapisać niczego w repozytorium? Odpowiedź jest dość prosta: GitHub pozwala na tworzenie tzw. forków - rozwidleń kodu w osobistej przestrzeni użytkownika. W ten sposób staje się posiadaczem kopii repozytorium, do której można już zapisać zmiany. Każdy może wykonać forka, utworzyć gałąź, zapisać zmiany i utworzyć pull request do pierwotnego repozytorium. Ja tu tego nie zrobiłem bo jestem śmierdzącym leniem.
Utwórzmy request:

Widok Pull request

Możemy obejrzeć zmiany:

Widok zmian

W zgłoszonym błędzie widać, że pracujemy nad zmianami:

Widok błędu po utworzeniu pull request

GitHub wie, że robię coś związanego z tym błędem, ponieważ użyłem kodu #1, który jest sposobem na odwołanie się do błędu z numerem 1. Tak połączyłem commit i pull request z błędem. Na dole pull request mam przycisk do połączenia zmian z główną linią kodu:

Screenshot from 2019-04-07 21-00-07.png

Po połączeniu (merdżu) GitHub zaproponował, że usunie gałąź, więc z tego skorzystałem (została usunięta na GitHub, lokalnie wciąż jest dostępna). Akceptacja Pull request automatycznie zamknęła zgłoszenie błędu.
Pobierzmy zmiany do naszego lokalnego repozytorium. Przełączę się na gałąź master i pobiorę zmiany z użyciem opcji --rune, co usunie usunięte zdalnie gałęzie w repozytorium lokalnym:

Pobranie zmian i uruchomienie programu

To by było na tyle, jeśli chodzi o podstawową pracę z kontrolą wersji w git.
Wiem że nie jestem cudowny w tłumaczeniu. LaunchSchool to profesjonaliści, którzy udostepnili swoją książeczkę na temat gita i githuba (po angielsku). Polecam.
Możesz też nauczyć się więcej bezpośrednio ze strony projektu, gdzie znajdziesz książkę "Pro Git" do pobrania za darmo, dostępną pod licencją Creative Commons Attribution Non Commercial Share Alike 3.0 license. Książka też pokazuje, jak zainstalować gita.

Co to Creative Commons?

Ta część będzie krótka, obiecuję. Chodzi tu o sposób, w jaki dzielimy się treściami. Czasem autor chciałby, aby korzystano z jego utworów zgodnie z pewnym zbiorem reguł - tak można z grubsza określić, czym jest licencja. Jeśli utwór nie ma licencji, sytuacja nie jest zbyt klarowna, szczególnie jeśli autor chce, aby osoby powszechnie korzystały z niego. W takiej sytuacji reguły mogą być ustalone przez platformę, na której nastąpiła publikacja, ale czasem nie są.
W całym zbiorze dostępnych licencji jest taki ich zbiór, którego celem jest zachęcanie do dzielenia się. Tak jest na przykład z oprogramowaniem otwartym, ale też może to dotyczyć nieprogramistycznych utworów podlegających prawu autorskiemu - książkom, grom, muzyce etc.
Creative Commons to organizacja non-profit, która udostępnia zbiór licencji, których można użyć do pokazania, których praw chce się chronić, a z których się rezygnuje. Mniej więcej. Ja udostępniam grę na licencji Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) co oznacza że możesz przekazywać dalej grę pod warunkiem wskazania licencji i autora. Możesz też ją modyfikować, ale musisz o tym wspomnieć, a sama gra wciąż musi być dostępna na tej licencji.
Co ciekawe, nasz projekt hello nie ma licencji. Dodam ją teraz. GitHub udostępnia zbiór licencji, z których można wybrać odpowiednią. Ogólne założenie jest takie, że musi powstać plik o nazwie LICENSE. Ja wybrałem The Unilicense, co oznacza w zasadzie, że oddaję projekt do domeny publicznej.

Koniec

Dziękuję za uwagę. Jeśli masz uwagi lub pytania, pozostaw komentarz.