29 października 2013

Z pamiętnika Confitury 2013 - recenzja Review your code like a Googler Darka Łuksza

0 komentarzy
Pełne "wgryzienie się" w występ Darka Łuksza zajęło mi prawie tydzień. Każdego dnia przez ostatni tydzień udawało mi się wydzielić kawałek czasu, aby wsłuchać się w prezentację na temat "Review your code like a Googler", w którym +Dariusz Łuksza przedstawiał Gerrita i jego integrację z Eclipse IDE, a z nimi powody, dla których warto rozważyć wdrożenie codziennych przeglądów kodu w Twoim zespole.


Poniżej co ważniejsze kawałki z prezentacji. Jest ich całkiem sporo, co w zasadzie udowadnia bogactwo merytoryczne prezentacji. I taka faktycznie była! Chyba się z nią zżyłem po tym prawie tygodniu oglądania i styl prezentacji Darka zaprocentuje w przyszłości wdrożeniem gerrita u mnie w zespole. Citi pracuje na CollabNet TeamForge, a Darek właśnie integruje gerrita z TeamForge w CollabNet, więc pewnie już niedługo będę mógł powiedzieć coś więcej w temacie praktycznie.

Przed każdym cytatem (wybacz Darku, jeśli nie w pełni oddałem sens wypowiedzi lub zmieniłem tu i ówdzie) jest czas - w formacie minuta:sekunda - kiedy dany kawałek się pojawi. Przy niektórych pojawia się również mój komentarz.

Niektóre z cytatów można umieścić śmiało w sygnaturze maila (!) Zdecydowanie polecam tę prezentację. Dzięki Darku!

01:06 "Tak więc zakładam, że znacie gita. Wiecie, co to jest push, pull, fetch, merge, rebase, refspec." - Akurat w moim przypadku rebase i refspec nie są znane. Do nadrobienia.

01:20 "Prezentacja nie jest dla osób, które się wstydzą swojego kodu. Wasz kod nie jest Waszą żoną. Możecie się nim dzielić. I oto chodzi."

01:29 "Dzięki temu, że na kod patrzy więcej osób, wyłapywanych jest więcej błędów. Tak samo Wy się uczycie. Uczycie też innych."

02:09 "Dzisiaj, wyjątkowo, będę używał do współpracy z Gerritem i Gitem Eclipse z Egit'em oraz Mylyn Connector. Jeżeli interesuje Was użycie z 'command line', zapraszam na prezentację Mateusza Szczap dzisiaj w Marmoladzie. Tam będzie więcej na temat, jak można jeszcze bardziej zautomatyzować proces 'code review' korzystając z komand ssh, które udostępnia Gerrit."

03:00 Wzdychając..."Ok, to 'code review'. O 'code review' słyszałem kilka ładnych lat temu."...kładzie rękę na policzku, jakby cierpiał z bólu zęba, a to tylko 'code review' :-)

03:27 "Po co robimy 'code review'? Robimy 'code review' po to, żeby minimalizować liczbę błędów. Żeby te błędy wyłapywać wtedy, kiedy one są bardzo tanie i proste do poprawienia, czyli wtedy, kiedy kod jest tworzony, kiedy dany 'feature' jest tworzony, a nie kiedy aplikacja znajdzie się na produkcji i przyjdzie 100 niezadowolonych użytkowników (o których była mowa na poprzedniej prezentacji) i powie że coś nie działa. Wtedy naprawienie tego błędu jest bardzo kosztowne i też bardzo stresujące dla nas, developerów, że coś takiego przeoczyliśmy i zapomnieliśmy o czymś takim wspomnieć."

04:00 "'code review' robimy też po to, żeby dzielić się naszą wiedzą i żeby się uczyć."

04:09 "Są osoby w zespole, które poświęcają pewien czas, żeby się dokształcać. Po to też 'code review' się robi, żeby te osoby mogły swoją wiedzę dzielić wśród zespołu, żeby ta nasza aplikacja, to nasze dziecko, nasze dzieło, które robimy było lepsze."

04:25 "Pierwszy typ 'code review' - 'post-commit review', tzw. 'formal code review'."

04:38 "Tą słynną metodologię liczenia jakości kodu przez WTF/minute. Dzisiaj zrobimy coś więcej."

05:00 "Bardzo ważnym elementem na tym zdjęciu jest...kubek z kawą, a właściwie termos." Auć! Ja kawy nie piję! Czy to miałoby oznaczać, że nie dla mnie taki zespół?! :-)

05:22 "Co po tym będzie? Potem będzie dokumentacja. Potem będzie 'bug' w 'bug trackerze', a potem będzie 'backlog'. Z mojego doświadczenia wynika, że takie błędy nie są poprawiane, o ile to nie jest to błąd bardzo duży i kosztowny, który łamie jakieś założenia aplikacji, który jest w logice biznesowej."

05:46 "W tym momencie ten kod już jest w repozytorium. Ktoś inny bazuje na tym kodzie. Co więcej ta osoba może bazować na zachowaniach tego kodu, które są błędne."

06:22 "Kolejny typ ['code review'] 'review on request'."

07:48 "Na końcu to, co ja nazywam asynchronicznym 'code review'. To, co jest możliwe do osiągnięcia z gerritem i to, co moim zdaniem jest najlepsze z możliwości, które nam oferuje aktualnie rynek."

08:45 "Teraz 'post-commit code review' vs 'pre-commit code review'."

08:55 "Reprezentacja graficzna? Jeżeli robicie 'code review' po 'commicie', kończycie z wielką toną dokumentacji i rzeczy, które zrobimy kiedyś, czyli nigdy. Jeżeli macie 'code review' przez 'committem', to macie większe ciśnienie, żeby to 'code review' zrobić, bo 'feature' nie wejdzie do aplikacji, bo klient nie będzie zadowolony, bo szef nie będzie zadowolony, bo ja nie skończę mojego zadania, bo ktoś nie zrobił mi 'code review', bo ja nie zrobiłem komuś 'code review'. Chodzi o to, żeby w tym wypadku,  musimy się do tego ['code review'] jakoś zmusić."

09:27 "To podejście ['pre-commit code review' z gerrit] daje takie narzędzie, które po prostu zmusza. Jeżeli wy nie będziecie robić 'code review', to aplikacja będzie stała w miejscu."

09:40 "Przejdźmy do gerrita."

09:42 "Czym jest gerrit? I dlaczego taki tytuł prezentacji?"

09:46 "Gerrit powstał tylko i wyłącznie dla projektu Android po to, żeby przenieść 'feeling', który jest wewnątrz Google z ich 'code review' na społeczność 'open source', na projekt Android."

10:00 "Cytat, który był na samym początku, że "żadna zmiana nie wchodzi bez 'review' do repozytorium", to jest jedna z zasad, która obowiązuje w Google. Tam każdy kod przechodzi przez 'review'."

10:35 "Gerrit jest bardzo silnie spięty z gitem. Bazuje na gicie. Możecie używać gerrita, tak jakby to był serwer gita. Nie musicie używać 'code review' związanego z gerritem. Możecie w gerricie, tak go skonfigurować, że mając 30 repozytoriów, 3 z nich będą miały 'code review', a pozostałe będzie można 'pushować' do serwera gita normalnego. Co więcej, macie możliwość ustawienia 'access controls' per 'branch', per 'branch', gdzie 'branch name' może być wyrażeniem regularnym. To nie są takie proste ustawienia ACLe, jak np. odczyt i zapis. To jest 'pushowanie merdży', 'puszowanie tagów', zmiana autora 'commitu', czyli 'puszowanie' jak ktoś inny. Tych ustawień jest sporo i ta lista przyrasta."

11:30 "Jeśli nie potrzebujecie korzystać z 'code review', a potrzebujecie serwera gita, to polecam Wam właśnie gerrita" - cóż za rym! - "Aplikacja javowa, webowa, czyli mamy znaną nam architekturę - prostokąt, prostokąt, cylinder, tj. frontend, backend, na frontendzie jest GWT, na backendzie jest Guice plus PostgreSQL."

11:56 "Dość lekkie [gerrit], zwinne. Nie potrzebujecie żadnego kontenera. Odpalacie to normalną komendą java -jar i podajecie ścieżkę do jara gerrita. Koniec. Nawet do testów bardzo fajne."

12:46 "Podejrzewam, że ten projekt [gerrit] może przeżyć samego Androida, dlatego że jest wykorzystywany do większej ilości zadań niż tylko jako system bazowy."

13:00 "Pobawmy się trochę gerritem!"

13:50 "Fred i jego IDE - oczywiście Eclipse. I co Fred chce zrobić? Fred jako, że jest nowy chce zrobić pierwszą zmianę. Niech to będzie zmiana, która będzie coś psuła." - po prostu miodzio mieć takiego nowego w zespole, co?

14:03 "Oczywiście, jak to w git'cie, zakładamy nowego 'brancha' na samym początku."

14:16 "Popsujmy sobie 'builda'."

14:20 "Każdy z nas wie, jak się najprościej psuje 'builda' - psuje się testy jednostkowe, które oczywiście mamy w aplikacji."

15:00 "Bardzo ważna rzecz. Tutaj jest taki bardzo enigmatyczny ciąg znaków - Change-Id: i same zera. Tak to musi być na początku. To jest generowane po 'commit'cie', zostanie zastąpione pewnym specjalnym numerkiem, 'hashem'. Po tej linii, Gerrit rozpoznaje 'commity'. Dzięki tej linii, on jest w stanie spiąć kolejną wersję Waszego 'patcha' z całym 'code review'."

15:36 "Możecie zmienić cały 'commit message'. Możecie zmienić dowolnie 'content', który jest w środku, ale ważne, aby ta jedna linia [z Change-Id] została niezmieniona. Teraz tam są same zera, bo zostanie zaraz wygenerowana."

16:16 "'Pushujemy' 'Push to Gerrit'. Nie bezpośrednio, tylko po prostu wybieramy tę opcję z menu."

16:25 "'Pushujemy' do specjalnego 'brancha', który się nazywa refs/for/. W tym wypadku jest refs/for/ 'master'. Podajemy docelowy 'branch', do którego ta zmiana ma trafić po samym 'code review'. Jeśli ta zmiana ma trafić do 'brancha stable' podajemy refs/for/ 'stable' zamiast 'master'."

17:44 "To, co jest fajne z gerrittem to, to, że można go bardzo łatwo spiąć z Jenkinsem. W tym momencie, po każdym 'pushu for review' odpalany jest 'job' na Jenkinsie, ewentualnie Hudsonie. 'Job' jest wykonywany i możecie go dowolnie skonfigurować - w tym wypadku po prostu odpala testy. Jeżeli zmiana się nie skompiluje, albo 'sfailują' testy, Jenkins nam taką zmianę zablokuje. W tym wypadku głosuje 'Code Review' -1, bo się posypały testy. Już w tym momencie nie musicie patrzeć na testy, patrzeć w 'diffa', widzicie to aktualnie, że ta zmiana coś psuje - nie jest gotowa, więc pomijacie ją. Omijacie jeden element z Waszego dziennego planu zadań, czyli 'code review'."

18:16 Dlaczego nagranie przechodzi w tryb dwóch paneli, gdzie lewy jest pusty?! Bardzo utrudnia oglądanie nagrania.

18:40 "Poprawmy tę zmianę...Tak samo jak wcześniej 'scommituję' używając skrótu i w tym momencie zaznaczam 'amend'."

+Dariusz Łuksza - dlaczego amend a nie po prostu kolejny commit? W końcu to jest już w historii, chociażby Jenkinsa, że coś się sypnęło i stąd kolejna zmiana.

Niestety, w pewnym momencie prezentacja gerrita zamienia się w prezentację integracji Eclipse IDE z gerritem.

21:54 "Trzeba zrobić 'push comments'. W tym momencie macie również możliwość głosowania na zmianę. Ten gerrit, który mam lokalnie skonfigurowany w ten sposób, że na 'verify' głosuje tylko i wyłącznie Jenkins. Nikt inny. Odsiewam te zmiany, które się automatycznie nie zbudują, albo nie przejdą testy. Dla mnie ważny jest tylko 'code review', czyli to, co jest w kodzie."

22:20 "Zakres, jaki mamy możliwy do zrobienia tutaj, to jest od -2 do 2. To są flagi. One nie sumują się w żaden sposób. Flaga -2 to jest jedna flaga, która jest przyklejona. Oznacza, że ta zmiana nigdy nie powinna wejść do repozytorium...Ona jest przyklejona w ten sposób, że po 'spushowaniu' kolejnego 'patchseta', który będzie coś poprawiał, -2 zostaje. W pozostałych przypadkach wszystko jest 'resetowane' do zera. -1 - drobne uchybienia w kodzie...+1 - wygląda dla mnie dobrze, ale wolę, aby ktoś jeszcze na to spojrzał...+2 - jest dla mnie ok, może iść do repozytorium. Dlaczego jest takie rozróżnienie pomiędzy +2 a +1? Dlatego, że możecie nie mieć dostępu do +2. Do każdego takiego poziomu, do każdej flagi można ustawić dostęp. Dana grupa będzie mogła tylko taką wagę ustawić."

23:38 "Co do grup - mechanizm jest dość skomplikowany, bo grupa może 'includować' grupę, może być oddelegowana, np. do LDAP. Grupa może być właścicielem innej grupy, więc poziom skomplikowania konfiguracji ACLi w gerricie jest dość wysoki."

24:35 "Zmianę można porzucić. Po prostu klikamy przycisk 'Abandon', podajemy odpowiedni komentarz, dlaczego to porzucamy. Ta zmiana zostaje w gerricie. Można ją potem wskrzesić. Ogólnie, nic z gerrita nie znika. Wszystkie komentarze, które zrobicie w gerricie i je zapiszecie są w gerricie. Wszystkie zmiany, 'patchsety', które 'pushujecie' są w gerricie. Tak więc możecie je potem odzyskać."

25:12 "Zróbmy coś bardziej skomplikowanego...Przede wszystkim zaakceptujmy jakąś zmianę, a po drugie, te zmiany będą ze sobą połączone."

28:24 "Po to się robi 'branche' tematyczne, żeby rozłączne zmiany trzymać osobno. Jeżeli zmiany między sobą zależą, 'pushujecie' je po kolei, tak jak pokazałem. Nie ważne, czy są dwa 'commity' czy 80 'commitów', 'pushujecie' je razem. Macie zapewnione przez gerrita, że 'commit' 77 wejdzie po 76."

// w tym momencie pada pytanie z sali

29:21 "Właśnie! Konflikty! Dobre pytanie."

29:28 "Z konfliktami jest w ten sposób, że gerrit część potrafi konfliktów sam rozwiązać. On używa jgita, który ma algorytm do rozwiązywania konfliktów, ale jeżeli ich nie potrafi rozwiązać, po prostu powie "sorry Winetou, ktoś tu musi przyjść i 'zmergeować'"".

30:00 ekran wraca do normalnych rozmiarów.

34:20 Koniec przykładów.

34:40 "Parę 'hintów' odnośnie 'code review'." => na slajdzie pojawiły się punkty: 'It's like TDD, review code before it hits main repository.' oraz 'Do code review on daily basis...remember when you are not reviewing other's code then application's not progressing.'

34:42 "Przede wszystkim [...] bądźcie konstruktywni i nie piszcie takich rzeczy typu 'Taki kod ja pisałem w liceum', albo 'To nigdy nie powinno wejść' bez podania dlaczego. Piszecie to tak, jakbyście pisali komentarz do kodu, a nie do osoby. Starajcie się ten kod przeglądać tak, jakby to był Wasz kod. Wasz kod, który napisaliście pół roku wcześniej, wracacie i myślicie 'Co ja tu miałem na myśli?! Gdzie ja tu mogę coś zrefaktorować? Gdzie mogę coś poprawić? Gdzie użyć nowej biblioteki, o której dowiedziałem się tydzień temu?'"

35:20 "Jeżeli dostajecie 'code review', to nie jest tak, że ktoś mówi Wam 'Jesteś głupi. Nie widziałeś tego NullPointerException?!' a raczej 'W tym kodzie jest błąd i to powinieneś poprawić. Następnym razem po prostu uważaj na to, że ta metoda zwraca nulla. Mogłeś o tym nie wiedzieć.' Chodzi o to, żeby sobie pomagać. Żeby razem to nasze małe zwierzątko zwane aplikacją wychować tak, żeby zachowywało się dobrze na produkcji."

35:46 "Code review powinno być robione codziennie." 

27 października 2013

Scalania 7 w Javart już w tę środę - stacjonarnie i wirtualnie

0 komentarzy
Dostałem kiedyś taki komentarz dotyczący jednego z poprzednich spotkań pod szyldem scalania:
"Fajnie byłoby móc w jakiś sposób uczestniczyć w scalaniach na odległość."
I się wydarzy już w tę środę, 30 października! "Uważaj, o co prosisz, bo się spełni."

Opublikowałem właśnie zaproszenie na meetupie na Scalania 7, które będzie w kilku aspektach nowatorskie.

Po pierwsze, będzie to spotkanie w biurze firmy Javart na Postępu 21 (Park Postępu, Budynek A, 2 piętro).

Po drugie, scalania będzie dostępne również na platformie Google Hangout na moim koncie na Google+. Mam już potwierdzone trzy osoby, które sprawdzą ten rodzaj "dystrybucji" wiedzy na własnej skórze. Dzięki Danielowi, Mateuszowi i Radkowi dowiemy się, czy warto kontynuować pomysł. Dziękuję Panowie. Ktoś jeszcze chętny?

Po trzecie, planuję nagrać wprowadzenie ze spotkania, aby zachęcić do udziału większą liczbę osób.

Firma Javart zapewni nam lokal, sieć, sprzęt, kawę, herbatę i wyżywienie. Atrakcji nie powinno zabraknąć dla każdego. Zapraszam!

22 października 2013

Wirtualne scalania - jak do tego podejść? Google Hangouts?

0 komentarzy
Given...

Zaangażowałem się w te scalania na tyle, że pomyślałem o wyjściu poza ramy tradycyjnego spotkania w Warszawie, w budynku MIM UWu. Myślę, że to zbyt tradycyjne podejście, aby dotrzec do większej liczby zainteresowanych, a okazuje się, że jest ich całkiem niemało.

Chociażby ostatni komentarz, który dostałem po edycji na warsjawie, sugeruje potrzebę odpalenia takiej wersji:
"idealnie by było dla mnie jakby scalania było więcej = trwało dłużej - jak zorganizujesz 5 godzinne scalanie to wsiadam w pociąg i przyjeżdżam z Łodzi... dla ludzi ze stolicy to mogłoby być za dużo, ale można by organizować krótkie i długie scalania :) dla różnych grup."
I tu pojawia się seria znajomych pytań kontrolnych, która zwykła mnie nękać, kiedy tylko rozpoczynam nowy temat, w której prym wiedzie jedno - "Jak do tego w ogóle podejść?"

Pomyślałem, aby skorzystać z doświadczeń innych grup, które korzystają z Google Hangouts - jestem pod ogromnym wrażeniem konferencji wirtualnej dotNetConfPL z tym narzędziem - i od tego bym właśnie zaczął.

When...

Utrzymałbym również godzinę spotkania 18:00 - 20:30 w środę, zanim zdecydowałbym się na dalszy krok odpalenia całodniowego scalania.

Then...

Pozostaje dotrzeć do kilku zainteresowanych osób, które zechciałyby na próbę skorzystać z tej formy nauki języka Scala i przyłączyć się do spotkania.

Wyobrażam sobie, że na spotkaniu mam duży ekran, na którym wyświetlana byłaby sala z grupą osób pod drugiej stronie lub po prostu pojedyncze osoby i w połączeniu z osobami na miejscu znacznie uczłowieczyć spotkanie. To mogłoby być bardzo ciekawe doświadczenie.

Kiedy to już spisałem i upubliczniłem, to musi się takie spotkanie odbyć. Nie znam wielu podobnych inicjatyw i chętnie przetarłbym szlaki z Twoją pomocą. Koniecznie skontaktuj się ze mną, jeśli jesteś zainteresowany udziałem, dysponujesz wolnym czasem w środę po 18:00 i wyrażasz zainteresowanie nauką języka Scala.

Co powiedział(a)byś na środę w przyszłym tygodniu?

20 października 2013

Relacja ze scalania 6 - niespodzianek końca nie widać

0 komentarzy
Byłoby niegrzecznie wychwalać własne dzieło, ale przywdziewając czapkę uczestnika spotkań z językiem Scala - Scalania - mogę śmiało oznajmić, że ostatnie, szóste spotkanie było jeszcze lepsze niż poprzednie (wliczając te podczas warsjawy). Na wsparcie tych słów, przytoczę opinie uczestników ze strony Scalania 6 - spotkania z językiem Scala.


Jacek Kołodziejski napisał:
"Kolejne bardzo udane scalanie i nawet się zmieściliśmy w czasie! Składam oficjalne gratulacje na ręce prowadzącego:)
Pomysł z wywoływaniem losowych ludzi do zadania z poprzedniej edycji jest bardzo ciekawy."
Co zechciał wesprzeć Piotr Kowalski swoim "lajkiem".

Andrzej Jóźwik dodał:
"Bardzo udana współpraca - praca w grupach wyzwoliła konkurowanie na ilość różnych podejść/rozwiązań. Jak widać ile osób tyle pomysłów - a scala daje duży potencjał."
Z "lajkiem" Rafała Krzewskiego.

Biorąc pod uwagę, że na spotkaniu było 15 uczestników (16 ze mną) i 4 wyraziło swój zachwyt, daje to ponad 25% zadowolonych, co uważam za solidne wsparcie mojego (być może przesadzonego tu i ówdzie) myślenia.


Daleki jestem od stwierdzenia, że to moja zasługa. Wręcz przeciwnie! Owe dzieło - scalania - wyjątkowo dobrze się samoorganizuje, a ja jedynie nadaję temu ramy spotkania. Liczba pomysłów, które mógłbym określić moimi, stanowi pewnie jedynie połowę wszystkich wdrożonych, co jest kolejnym sukcesem tej inicjatywy.


Ot, choćby ostatnie "ćwiczenia" polegające na podziale uczestników na grupy i ścisłe przestrzeganie ram czasowych. To nie są moje pomysły, a jak widać to właśnie one stanowią o doskonałości spotkania. I tak trzymać! Ja ustawiam się w roli bacznego obserwatora i "zbieracza" pomysłów, a uczestnicy, jako główni aktorzy na scenie, określają formę i kierunek rozwoju (własnego i spotkania). Widzę samych wygranych.


Dziękuję tym, którzy zabrali głos w sprawie (na meetupie), pozostałym uczestnikom, wydziałowi MIM UW, aby nie zapomnieć o sponsorze - firmie Javart. Zabrzmi banalnie, ale należy to napisać...oddawając tedy, co jest cesarskiego, cesarzowi, a co jest bożego, Bogu...że bez nich scalania nie miałyby miejsca. Dziękuję!


W zasadzie, komentarze wyżej, dają pojęcie o zmianach wdrożonych podczas ostatniego spotkania - utrzymanie podziału na 3-osobowe grupy oraz ścisłe trzymanie się agendy. Dla mnie największym sukcesem było trzymanie się czasu i wciąż jest zaskakująca łatwość, z jaką idzie to utrzymać. Chociaż niewielu potrafi rozwiązać zadanie w zadanym czasie, to nie słychać głosów, które mogłyby świadczyć, że to coś niewłaściwego. To się musi podobać każdemu!


Zaczęliśmy spotkanie o 18:10, od wprowadzenia do Scali, które poprowadził Andrzej Goławski. Dostał 15 minut i ich nie zmarnował! Trudno było znaleźć czas, aby się nudzić. Wielkie brawa dla Andrzeja.


Później "odpaliłem" nowość tego spotkania - 15-minutową rozgrzewkę, czyli sprawdzian dla osób, którzy byli na poprzednich scalaniach, a którzy "poproszeni" rozwiązywali już zrobione wcześniej zadania (niekoniecznie przez nich samych).

Jak wybierać osoby do tego sprawdzianu jest jeszcze do wypolerowania, ale z pewnością należy to utrzymać. Daje to możliwość wyjścia na scenę osobom, które zwykły trzymać się z dala od blasku fleszy, a także wdrożyć nowe osoby do mechaniki rozwiązywania zadań. Bardzo podobała mi się dyskusja z pierwszym na scenie (wybacz chwilową amnezję, bom imienia nie pomniał), aby rozwiązać zadanie, którego akurat nie robił wcześniej (bo udział w scalaniu nie musi oznaczać, że dane zadanie właśnie wtedy było robione).


W końcu nadeszła pora na przerwę żywieniową i chwilę na dyskusję. Ten element uważam za kluczowy, bo nie tylko, że można się posilić, ale przez miejsce (korytarz) i niewielką liczbę osób (poniżej 20) próbuję animować dyskusje między uczestnikami. Podczas przedostatniego spotkania mieliśmy jedno wielkie kółko, w którym każdy dzielił się swoimi wdrożeniami Scali w firmie, a na ostatnim widać już było kilka podgrup i raczej nikogo pozostawionego samemu sobie. To zdecydowany sukces scalania i odejście od tradycyjnego, opartego na slajdach i jedzeniu w ławkach, formatu spotkań Warszawskiego JUGa.


Od 19:00 można liczyć faktyczne rozwiązywanie zadań. Zgodnie z planem, na pierwszy ogień poszło P14. O 19:10 dzielimy się gistami. Poniżej zebrane propozycje.
W agendzie zaplanowałem kolejną niespodziankę spotkania, ale najwyraźniej sprawność grupy sprawiła, że pojawiła się ona w propozycjach rozwiązań - napisać rozwiązanie w trzech wersjach - z użyciem dopasowania wzorców, jednolinijkowca z foldLeft/flatMap czy podobnie, oraz wersję z rekurencją ogonową. Zakładając, że jedno z wymienionych jest bieżącym rozwiązaniem, pozostałe stanowiły(by) uzupełnienie i kolejne ćwiczenie umysłowe. Zwykle dawało to trzy różne rozwiązania.


O 19:30 podeszliśmy do P15.

Właśnie wtedy uzmysłowiłem sobie kolejną nowość spotkania - baczniejszą analizę błędu podczas uruchomienia testu. Do tej pory zakładałem, że należało przeczytać test, aby dowiedzieć się, co jest wymagane w implementacji, ale już samo uruchomienie testu daje taką informację.

Uruchom polecenie ~exercises/testOnly *P15* i po prostu przeczytaj błąd, w którym napisano, czego oczekuje się od implementacji.
> ~exercises/testOnly *P15*
[info] P15Spec
[info]
[info] P15 solution should
[info] x Duplicate the elements of a list a given number of times.
[error]    an implementation is missing (S99_P15.scala:4)
Trzeba więcej?! Raczej nie. To znacznie upraszcza operowanie projektem i udział w spotkaniu. Gdyby podzielić ekran na dwa i u dołu pokazywać wynik testu, a u góry edytor, byłoby to idealne środowisko pracy. Tutaj IDE, np. IntelliJ IDEA, mogłoby spełnić pewną rolę.


I tu mnie olśniło - zaproponowałem, aby w 3-osobowej grupie był tylko jeden otwarty komputer ze zmianą osoby piszącej rozwiązanie. Moja pamięć zawodna i nie pamiętam grupy, która nie wdrożyłaby tego pomysłu.
O 19:50 siedliśmy przy P16.
O 20:30 ogłosiliśmy spotkania koniec.


Dziękuję uczestnikom, wydziałowi MIM UW, firmie Javart oraz Tobie za przeczytanie sprawozdania. Zapraszam na kolejne spotkanie, które odbędzie się już za 2 tygodnie. Do zobaczenia!

p.s. Zachodzę w głowę, jak gromadzić rozwiązania, aby stały się częścią projektu scalania na GitHubie. Pomysły mile widziane.

15 października 2013

Scalania 5 - wydanie specjalne i warsjawa 2013 przechodzą do historii

0 komentarzy
Projekt spotkań w formie warsztatowej o nazwie scalania odpaliłem po raz pierwszy 9 lipca 2013. Pomysł nie był nowatorski w swej formie, a wciąż nie posiada swojego konkurenta, przez co można choćby z tego powodu okrzyknąć go sukcesem. Podobnie jak warsjawę.


Kiedy 6 lat wcześniej - 21 listopada 2007 - uruchamiałem (jeszcze na tamten czas nazywaną) WarsJavę - projekt polegający na serii krótkich wykładów praktycznych, które miały być odpowiedzią na rosnące zapotrzebowanie poznawaniem technologii przez warsztaty - nie sądziłem, że może kiedykolwiek przyciągnąć ponad 500 uczestników, a dodatkowo będzie prowadzony przez grupę niesamowicie nakręconych łebków, którzy już dawno udowodnili, że jak można, to będzie i nie potrzeba ciągać za sobą balastu w postaci mojej osoby. Chwała za decyzję!


I dało się? Pewnie, że się dało! Spełniło się moje marzenie o uformowaniu grupy, która organizuje się samodzielnie i potrafi uruchomić confiturę, warsjawę oraz zadbać o regularne spotkania Warszawskiej Grupy Użytkowników Technologii Java (Warszawa JUG).

Panie i Panowie, szacunek za poświęcony czas i włożony wysiłek. Jestem dumy móc pracować z Wami i korzystać z owoców Waszej pracy! Uczę się przy tym niemało. Dziękuję!

I tak zabrakło mi organizowania czegoś i padło na spotkania warsztatowe ze Scalą. Zaczęło się od poznawania języka Scali samodzielnie, aby wpaść na pomysł odpalenia scalania. Brakowało mi towarzystwa do nauki, więc zorganizowałem spotkania.


I się toczy pomalutku.


Podczas warsjawy okazało się, że projekt scalania pozwala na organizowanie spotkań regularnie na MIMUWie oraz wydanie specjalne. W zasadzie formuła scalania podczas warsjawy nie różniła się zasadniczo od tego, co doświadczam na spotkaniach regularnych, ale kolejny raz dano mi możliwość poeksperymentowania i wdrożenia kilku pomysłów.

Na wydaniu specjalnym scalania na warsjawie pojawiło się 12 osób. Żadna z osób nie uczestniczyła w poprzednich scalaniach.


Po usadowieniu się uczestników i wprowadzeniu ich w tajniki projektu scalania (co trwało około 15 minut) poprosiłem o ujawnienie się bardziej zaawansowanych programistów Scali. Szczęście mnie nie opuściło i okazało się, że osób na poziomie kursu Odersky'iego i kilku samodzielnych prób z językiem było 6 - dokładnie połowa! W ten sposób wdrożyłem w życie pomysł podziału uczestników na pary - nowicjusz i zaznajomiony ze Scalą. Stoły były jakby dopasowane do takiego pomysłu i mieściły pary doskonale.


Przeszliśmy przez P01 wspólnie, później już P02 samodzielnie (w parach), aby około 10:40 zabrać się za P03. Zauważyć można było, że tempo nie każdemu służy i było niemałym zaskoczeniem dla uczestników. Mimo wszystko nie zraził się nikt i zawzięcie widać było na twarzach.


Trzeba było widzieć te pracujące pary - ludzie pracują wspólnie, w parach w rytm expression pair programming! Widać interakcję. Moje marzenie o spotkaniach, które integrują (zamiast tylko przekazywać wiedzę) spełniało się kolejny raz.

O 11:05 przerwa.

Przeszliśmy do P12 około 11:45 i dokończyliśmy spotkanie wspólnym rozwiązywaniem zadania, które pozwoliło mi zademonstrować siłę systemu typów Scali i wymuszanie przez niego implementacji (po prostu należało spełniać wymogi kompilatora, aby ostatecznie wyłoniło się rozwiązanie). Tym wspólnym akcentem zakończyliśmy scalania 5 - wydanie specjalne na warsjawie 2013.


Po warsztacie spędziłem czas do 15:00 na dyskusjach z organizatorami, wolontariuszami, sponsorami oraz uczestnikami warsjawy. Dziękuję wszystkim za wspaniałą atmosferę.


Niech podsumowaniem mojej relacji będą trzy relacje uczestników scalań. Jak nietrudno zauważyć, pojawia się w nich nowy pomysł do wdrożenia ;-)

"Hej,

jeszcze raz dzięki za świetny sobotni warsztat. Poniżej tak jak prosiłeś moje spostrzeżenia.

Na plus:
- muszę przyznać, że przed warsztatem widziałem może z jedno "Hello World" ze Scali więc trochę obawiałem się, że polegnę na składni. Jednak krótkie wstępy teoretyczne przed zadaniami pozwoliły mi o tym zapomnieć. Dodatkowo muszę powiedzieć, że taka metoda (minimum teorii koniecznej do rozwiązania problemu + kodowanie) nauki nowego języka bardzo dobrze się sprawdza.
- tworzenie par nowicjusz + bardziej doświadczony. Można poznać nowych ludzi, czegoś się od nich nauczyć, a i może oni się czegoś nauczą od nowicjuszy przez ich świeże spojrzenie.
- krótki czas na rozwiązanie zadań. Nie pozwoliło to ślęczeć uczestnikom nad rozwiązaniem nie wiadomo ile, dzięki temu nie robiło się nudno.
- sądzę, że wspólne rozwiązanie P12 na moim przypadku (trochę przy nim poległem na kompilatorze, ale rozwiązanie zmierzało w jakimś tam dobrym kierunku jak się okazało :) ) dużo dało nie tylko mi.

Co mogłoby być inaczej, żeby było lepiej (czyli jak ktoś woli minusy):
- zabrać/schować/wyłączyć (niepotrzebne skreślić :] ) jednej osobie komputer. Zdarzało się, że zaczynaliśmy rozwiązywać problem na jednym komputerze, rzucaliśmy swoje pomysły, później następował mały zastój i praca rozpraszała się na dwa komputery. Jedna osoba na chwilę zwątpiła we wspólnie wypracowane rozwiązanie i przechodziła do realizacji własnego pomysłu. Gdyby nie było drugiego komputera dało by się tego uniknąć i wycisnąć ze wspólnej pracy w parach dużo więcej.
- trochę się rozjechaliśmy z czasem/agendą, ale to właściwe plus bo jeśli mamy jakieś pytania do zadania, pojawiają się jakieś ciekawe dyskusje lub Ty miałeś coś extra do powiedzenia to dlaczego nie? Myślę więc, że nie ma co ściśle ustalać ile zadań zrobimy na spotkaniu bo czas poświęcony na jakieś dodatkowe rozmowy, o ile nie odchodzimy za bardzo od tematu, na pewno nie jest czasem straconym :)

Ogólnie jestem bardzo zadowolony z tego warsztatu. Jak napisałem wcześniej nie miałem kontaktu ze Scalą, a z programowaniem funkcyjnym tylko akademicko (LISP, PROLOG) - jakoś do mnie ono nie trafiło. Po warsztacie trochę inaczej na to spojrzałem i pewnie będę się chciał bardziej zagłębić w ten temat. Mam nadzieję, że uda mi się pojawić na następnych scalaniach. To tyle ode mnie."

"Cześć,

Warsztaty były naprawdę fajne i to co mi się najbardziej podobało to w miarę żwawa akcja.
Zauważyłem, że czasami jak omawianie teorii trwa zbyt długo i ludzie jeszcze nie za bardzo czują, że ta teoria może im się do czegoś przydać, to lubią się wyłączać.
Tutaj tempo było w sam raz.

Dzień wcześniej zrobiłem sobie dwa pierwsze zadania na ifach. Dzięki temu, że na zajęciach padła sugestia by użyć pattern matching, łatwiej mi było zauważyć różnicę pomiędzy tymi rozwiązaniami. Być może będziecie chcieli na przyszłych spotkaniach rozwiązywać dany problem na kilka sposobów 
i omawiać różnice.

To co można poprawić to pozostawić jeden laptop na grupę aby zachęcić do większej współpracy.

pzdr,"

"Witaj,

Podobało mi się:
- praca w parach (może warto pójść jeszcze dalej i spróbować pair programmingu ze zmianą kompa co zadanie?)

Podobało mi się mniej:
- skakanie między Sublime i REPLem gdy "spełniałeś wymagania kompilatora" (może wtedy lepiej byłoby użyć jakiegoś IDE które na żywo podkreśla błędy kompilacji?)"

Zaczynam zastanawiać się, na ile zasadne byłoby myślenie, że scalania należałoby odpalić w innych częściach Polski? Już realizuję pomysł, aby odpalić scalania w pewnej firmie (ogłoszenie niebawem), ale może i należałoby zastanowić się nad innymi miastami. Może również należałoby oprzeć na scalaniach całodniowe szkolenie? A może nawet kilkudniowe? Jesteś chętna, aby podjąć wątek? Porozmawiajmy!

13 października 2013

Scalania 6 - spotkania z językiem Scala w najbliższą środę, 16 października od 18:00

1 komentarzy
Zapraszam na szóste spotkanie z językiem Scala - Scalania 6, które odbędzie się w najbliższą środę, 16 października na MIMUWie. Szczegóły organizacyjne znajdziesz na stronie spotkania http://scalania.pl.

Rozpoczynamy o godzinie 18:00 w sali 3180.

Po ostatniej warsjawie pojawiło się w mojej głowie kilka pomysłów, które chciałbym zrealizować właśnie podczas tego spotkania. Z pewnością będzie inaczej niż podczas poprzednich spotkań, więc stali bywalcy powinni ponownie poczuć się jak nowicjusze.

Motywem przewodnim będzie praca z projektem scalania z GitHuba w obszarze zadań P14-P16 (z możliwością rozszerzenia aż do P19).

Na scenie zobaczymy Andrzeja Goławskiego, który "uzbroi" nas w niezbędne konstrukcje języka Scala potrzebne do rozwiązywania zadań.

Zastanawiasz się, czy to spotkanie dla Ciebie?! Na pewno! Świeże spojrzenie zawsze w cenie. Po prostu nie może Cię zabraknąć! Zapraszam!

11 października 2013

Szanowny uczestniku specjalnej edycji Scalania na warsjawie

0 komentarzy
Drogi uczestniku scalania - wydanie specjalne,

Z niecierpliwością oczekuję nadchodzącej soboty, 12 października, kiedy o godzinie 9:30 będziemy mogli się spotkać na tegorocznej warsjawie, w której wspólnie weźmiemy udział w wydaniu specjalnym Scalania.

Przekonasz się na własnej skórze, że nie ma lepszego sposobu na poznanie Scali, jak obcowanie z nią w gronie podobnych zapaleńców. Odmienność spojrzenia na ten sam problem współtowarzysza i możliwość poznania powodów takiego rozumienia jest bezcenna, a jednak dostępna na wyciągnięcie ręki podczas tych spotkań.

Spotykamy się w sali 2045 na MIMUWie. Wcześniej zachęcam do udziału w oficjalnym rozpoczęciu konferencji o godzinie 9:00.

Na mój warsztat zapisało się 23 osoby i planuję zastosować wszystkie techniki uatrakcyjniania spotkań, które miałem możliwość doświadczyć podczas poprzednich 4 edycji scalania.

Zaczynamy punktualnie o godzinie 9:30. O 11:00 jest obowiązkowa 30-minutowa przerwa. To daje nam 2 bloki warsztatowe = odpowiednio 90 minut i 60 minut.

Wstępna agenda scalania - wydanie specjalne jest następująca:

CZĘŚĆ 1 :: 09:30 - 11:00 - 90 minut - część wprowadzająca/rozgrzewająca
15 minut - wprowadzenie do projektu scalania
10 minut - tematy scalowe do rozwiązania zadań
30 minut = 3 x 5 minut - rozwiązywanie zadania + 5 minut - omówienie rozwiązania
10 minut - tematy scalowe do rozwiązania zadań
25 minut = 3 x 5 minut - rozwiązywanie zadania + 5 minut - omówienie rozwiązania

PRZERWA 11:00 - 11:30 - 30 minut

CZĘŚĆ 2 :: 11:30 - 12:30 - 60 minut - część (bardziej) zaawansowana
10 minut - tematy scalowe do rozwiązania zadań
20 minut = 2 x 5 minut - rozwiązywanie zadania + 5 minut - omówienie rozwiązania
10 minut - tematy scalowe do rozwiązania zadań
20 minut = 2 x 5 minut - rozwiązywanie zadania + 5 minut - omówienie rozwiązania

RAZEM 3+3 + 2+2 = 10 zdań

Dzielenie się agendą przed spotkaniem jest nowością tego wydania. Chciałbym, aby tempo zostało dotrzymane i  tym samym proszę o wspólne pilnowanie harmonogramu, gdybym sam nie dawał z nim rady. Nie będzie lekko, ale nikt tego nie obiecywał, więc po co sobie odpuszczać! :-)

Proszę zapoznać się z projektem scalania na GitHubie. Najważniejsze, aby pobrać projekt (git clone) na swój komputer, z którym pojawisz się na warsztacie. Dodatkowo należy odpalić sbt (w wersji 0.13) i wykonać polecenia opisane w README projektu. To pozwoli nam na pracę bez konieczności dostępu do sieci, gdyby takowa zawiodła. Jako IDE będę korzystał z Sublime Text 3 i/lub IntelliJ IDEA 13. Wybór IDE pozostawia się uczestnikowi.

W miarę możliwości proszę o zabranie ze sobą przedłużacza.

O czymś powinienem jeszcze wspomnieć? Pytania? Sugestie? Komentarze? Proszę o kontakt.

Do zobaczenia na warsjawie!
Jacek

07 października 2013

Czytelność kodu a przegląd kodu w moim zespole w Citi

0 komentarzy
Nie miałem jakiejkolwiek wątpliwości, że przejście do Citi będzie dla mnie wyjątkowe pod wieloma względami. Ot, chociażby dzisiejsze spotkanie zespołu celem przeglądu kodu jednego z nas - nazwisko ominę (wybacz Artur).

W jeden sali miałem okazję zasiąść z (kolejność przypadkowa) Marcinem, Grześkiem, Tomkiem, Arturem, Pawłem i innymi, mniej lansującymi się w Sieci, ale wciąż światłymi osobami (określenie "lansowanie" używam tutaj wyłącznie w pozytywnym znaczeniu). Wielu ich zna, niektórzy nawet osobiście, ale niewielu może z nimi pracować na co dzień. Ja taką okazję mam i nie zamierzam jej marnować, więc uczestniczę we wszystkich spotkaniach. Uważam, że obcowanie z mądrym sprawia, że sam się nim stanę (?), a co najmniej zbliżę się do takiego poziomu. Dziękuję Panowie!

Podczas pierwszego przeglądu kodu, wyniknęła dyskusja o czytelności kodu. Początkowo sądziłem, że to kolejne marnowanie czasu, ale wystarczyło wstrzymać się z dalszymi ocenami, aby przekonać się, jak bardzo się myliłem. Dyskusja rozgorzała, kiedy pojawił się poniższy kawałek kodu:
  val wasStateChanged = prevCMStatusState match {
    case Some(prevState) => prevState != currentState
    case None => true
  }
Ten kawałek został zganiony za powtórzenie implementacji metody Option.fold. Korzystając z niej możnaby powyższe zapisać następująco:
  val wasStateChanged = prevCMStatusState.fold(true)(_ != currentState)
I tu się zaczęło.

Kiedy zobaczyłem fold zacząłem rozkładać prevCMStatusState na elementy (zakładając, że to kolekcja). To był błąd, bo prevCMStatusState to scala.Option.

Zajęło mi chwilę, co mogłoby to robić, ale kiedy dowiedziałem się, spodobało mi się. Jakieś takie geek'owe :) I tu cały pies pogrzebany. Może faktycznie geek'owe, albo po prostu moja nieznajomość (ignorancja) podstawowych klas i ich metod w Scali sprawiła, że odniosłem takie wrażenie. Nieistotne, bo szybko stałem się zwolennikiem Option.fold. Nie wszyscy.

Inny przykład mógłby być taki:
  case class X(age: Int)
  Some(X(40)).fold(false)(_.age > 30)
Odczytanie tej linijki z Option.fold zajmuje mi tyle samo czasu, co odczytanie pattern matching wyżej, a pisze się krócej, więc obstaję za wersją krótszą.

Ale czy krócej to piękniej? I czy nie przekraczamy cienkiej granicy czytelności kodu nad jego zwięzłością? I czy czytelność kodu jest cechą kodu czy relacją między kodem a czytelnikiem. Sądzę, że to drugie.

Dla mnie czytelny kod nie musi implikować jego czytelności dla Ciebie czy Twoich znajomych. Dyskusja sprowokowała mnie do zastanowienia się nad (lekko wyświechtanym) określeniem "czytelność kodu". Dla mnie, czytelność kodu jest wypadkową doświadczenia czytelnika, a nawet nastroju. Dzisiaj jestem w stananie czytać między liniami, ale czy jutro również będzie mi to dane? Zdecydowanie obstaję nad pełną znajomością standardowej biblioteki języka (w tym przypadku Scali), więc jeśli mamy Option.fold w Scali, to będę z tego korzystał (zamiast pisać implementację za każdym razem, gdzie Option.fold mógłby być zastosowany).

A jak z Twoją definicją czytelności kodu? Czy powyższy przykład mógłby stanowić podstawę do takiej dyskusji z Tobą? Czy znasz inne, kontrowersyjne przykłady?

03 października 2013

Scala scala na Scalaniu - 4-te spotkanie za nami

0 komentarzy
Zacznę od rzeczy najważniejszej - podziękowań. Dzisiejsze, czwarte spotkanie ze Scalą - Scalania 4 - było bezsprzecznym sukcesem współpracy wielu osób, o których byłoby nietaktem nie wspomnieć. Wcześniejsze nie były specjalnie inne, ale efekt dzisiejszych jest jakiś szczególny i tak mnie naszło.

Dziękuję firmie Javart za opiekę nad spotkaniem. Kolejny raz. Pozwoliło nam to na pełne oddanie się "trawieniu" wiedzy o języku Scala, zamiast walce z głodem i pragnieniem. Dzięki wsparciu firmy Javart, głód i pragnienie poszły w zapomnienie, kiedy…

pojawiła się strawa i napoje,
a na scenie kolejno nasi prelegenci we troje.

Zaczął +Andrzej Goławski. Pierwsze dziesięć minut upłynęło sprawnie i zapoznaliśmy się z metodami map, List.make, List.flatMap oraz List.zipWithIndex. Andrzej korzystał z prezi. Wyjaśnienie, przykład i kolejny, wyjaśnienie ponownie, itd. Przerwałem jego wystąpienie po tym, kiedy mój stoper oznajmił upływ 10 minut. Oklaski i wchodzi kolejny prelegent.


Na scenie pojawia się +Anita Fronczak. Anita wykorzystała Google Docs jako platformę do slajdów. Z pewnymi problemami sprzętowymi (Anity komp bez wyjścia VGA, a mój Mac kolejny raz się zawiesza przy podłączeniu do wyjścia projektora, więc Andrzej nas ratuje swoim) zaczynamy kolejne 10 minut. Anita przeprowadza nas przez tajniki krotek (ang. tuples), przypisania przez dopasowanie wzorców, Either/Left/Right i kończymy po kolejnych 10 minutach. Oklaski i wchodzi kolejny prelegent.


Ostatnim "czarodziejem" staje się +Piotr Marczewski. Tym razem jedynie IDE. Omówił klauzulę import w ramach object, typ scala.Any oraz scala.Symbol. Dokładne wpasowanie do przydzielonych 10 minut i kończymy o czasie.

Wielkie gratulacje dla naszych prelegentów! Utrzymanie materiału w ryzach 10 minut z pewnością nie było łatwe i wymagało od nich starannych przygotowań. Udało się i było super. Anita, Andrzej i Piotr zasługują na gromkie brawa.

Utrzymanie owych 10-minutówek zgodnie z ich planowanym czasem (i nazwą) okazało się strzałem w dziesiątkę! Było różnorodnie (merytorycznie i osobowościowo), sprawnie, krótko i treściwie. To zdecydowanie należy utrzymać.

I tu nowość tego spotkania - podział na trójki. W zamyśle celem trójek miało być zintensyfikowanie interakcji między uczestnikami, a to miało się przełożyć na większą porcję wiedzy dla pojedynczego słuchacza (który miał się stać aktywnym uczestnikiem). Odliczyliśmy do trzech i ostatecznie uformowały się 3 czwórki (hmmm...dlaczego nie podzieliliśmy grup na 4 trójki?!)


Sądzę, że to był hit sezonu. Praca w mniejszych grupach sprawiła, że ludzie musieli się poznać z innymi w grupie (wartość sama w sobie) oraz trudniej było utrzymać siebie w roli biernego słuchacza. Nie trzeba było być bacznym obserwatorem, aby zaobserwować zalety takiego podejścia. Wystarczy spojrzeć na zdjęcia.


Po podziale na grupy, kiedy to wszyscy się dobrze usadowili, oznajmiłem przerwę "obiadową". Postanowiłem tym samym rozruszać nasze informatyczne ciała i kolejny raz zmusić do interakcji między uczestnikami. Udało się! Po chwili uformowaliśmy koło, w którym każdy podzielił się swoimi doświadczeniami z wdrażania/użycia Scali w projektach. Szkoda, że nie mam zdjęcia z tego momentu. Trzeba było w tym wziąć udział, aby przekonać się, jak ważne są takie małe ruchy integracyjne.


Około 18:15 (tak, tak, uważny obserwator dostrzeże pewną, nieznaczną rozbieżność w czasie między tą relacją a stanem faktycznym) przeszliśmy do zadań.

I tu kolejna nowość, trzymanie się czasu na rozwiązywanie zadań. Włączyłem stoper i rozpoczęliśmy rozwiązywanie P11. Później było P12 i skończyliśmy na P13. Wymienialiśmy się rozwiazaniami za pomocą serwisu GitHub Gist. Dzięki uprzejmości MIM UW mieliśmy pełny dostęp do Internetu, więc wystarczyło poznać numer gista i można było omawiać rozwiązanie zadania. Jakoś tak czas nam upływał przy dyskusjach i ostatecznie jedynie 3 zadania udało nam się rozwiązać. Tutaj trzeba popracować nad sprawniejszą obsługą.


Kolejna edycja scalania 5 będzie specjalna, bo prowadzona podczas warsztatów warsjawa 12 października na MIM UWie. Zaczynamy o 9:30. Są jeszcze miejsce, więc gorąco zachęcam do udziału! Wystarczy napisać do mnie.