Archiwum autora: Marcin Kowalczyk

Siedlce.dev spotkanie branży informatycznej

Ważną częścią rozwoju programistów i osób związanych się wytwarzaniem oprogramowania jest wymiana doświadczeń, wiedzy i pomysłów z innymi. Tak ważny aspekt jak networking, może być częściowo realizowany online. Szczególnie w naszej branży, gdzie swobodnie posługujemy się nowymi technologiami, zaś wymiana informacji na czacie czy bycie ciągle online to coś normalnego. Ale nic nie zastąpi swobodnego spotkania twarzą w twarz. Daje to większe zaangażowanie, wspólne środowisko i więcej możliwości.

Dlatego organizowane są konferencje, warsztaty i różne spotkania. Szczególnie cieszy się tym branża IT. W większych ośrodkach takich jak Warszawa, Karków czy Wrocław nie ma problemu ze znalezieniem interesującego nas wydarzenia. Odbywa się ich przynajmniej kilkanaście w miesiącu, prawie codziennie coś się dzieje. Przykładowa baza z wydarzeniami IT to Crossweb.

Dlaczego nie lokalnie?

Częste wyjazdy do innego miasta wiążą się z pewnymi niedogodnościami, chociażby długi czas i męcząca podróż. Na większe wydarzenia np. Warszawskie Dni Informatyki lub InfoMEET przybywają słuchacze również z okolicznych miejscowości. Na te mniejsze już rzadko komu chce się jechać.

Dlaczego by nie robić wydarzeń również lokalnie? Otóż są. Przykładowo w Siedlcach:

  • konferencja Inżynieria Gier Komputerowych (IGK) – wydarzenie dla twórców gier komputerowych, towarzyszą im Siedleckie Targi Gier,
  • konferencja Współczesne Zastosowania Informatyki – przeznaczona do bardziej ogólnych tematów,
  • seminaria kół naukowych (np. Koła Naukowego Informatyków Genbit, Koła Naukowego Programistów) – zazwyczaj studenckie spotkania,
  • inne okazjonalne wydarzenia.

Jak widzimy nie ma tego dużo. Trochę brakowało zainteresowania lokalnej branży informatycznej, tak jak to jest w większych ośrodkach. Na szczęście się to jednak zmienia. Być może niektórzy już zauważyli, że warto wyjść do innych i zainwestować w społeczność, bo zamknięcie się tylko na siebie jest krótkowzroczne.

Wreszcie spotkanie dla programistów!

Powstało to czego brakowało w Siedlcach. Regularnych spotkań dla programistów z branży. Nisza wreszcie została częściowo zapełniona. Inicjatorami oraz organizatorami Siedlce.dev i bliźniaczego Podlasie.dev w Białej Podlaskiej są Rafał Muszyński i Karol Wójciszko. Rafał przed laty był organizatorem, już wspomnianej, konferencji Inżynierii Gier Komputerowych (którą po nim przejąłem na lata 2014-2015). Z pewnością mógł wykorzystać nabyte doświadczenie w organizacji takich wydarzeń. Karol prowadzi bloga wojciszko.com na temat zarządzania projektami, analizą i wytwarzaniem oprogramowania.

Pierwsza edycja już była

Pierwsza, pilotażowa edycja Siedlce.dev odbyła się 27 kwietnia 2017.

Relacje z wydarzenia:

Wystąpienia były trzy:

  • „SOLIDny kod” – Rafał Muszyński
    Każdy kto uczył się programowania obiektowego pewnie zetknął się z tymi pięcioma podstawowymi założeniami projektowania i pisania kodu (SOLID). Gdyby jednak wszyscy się do tego stosowali, to kod byłby piękny. Dlatego tak ważnych, prostych w założeniach, a jednocześnie trudnych do ciągłej realizacji, tematów nigdy za wiele.
  • „HTTP Cache – dlaczego/kiedy/jak?” – Paweł Mikołajczuk
    Czyli głównie omówienie Varnish Cache. Jak jakiś startup napisał aplikację bez optymalizacji, a serwera już przestaje wyrabiać, to można na szybko wrzucić to rozwiązanie. Oczywiście w normalnych sytuacjach również można je stosować z powodzeniem. Często nawet po prostu się powinno, trzeba tylko uważać co keszować, a czego nie.
  • „Twój pierwszy startup” – Karol Wójciszko
    Temat mniej techniczny, ale przydatny jeśli ktoś myśli o zakładaniu startupa, co od jakiegoś czasu stało się wręcz modne. Trzeba mieć dobry pomysł, żeby zaspokoić jakieś zapotrzebowanie rynku (nawet jeśli sami to zapotrzebowanie wytworzymy 😉 ). Pierwsze co przychodzi do głowy, to to, że rozwiązanie ma być przeznaczone dla użytkowników końcowych. Okazuje się jednak, że dużym polem do popisu dla startupów jest także rynek B2B, czyli rozwiązywanie problemów innych firm.

Na koniec kilka słów zabrała lokalna firma Tech-Media, która była sponsorem spotkania (darmowa pizza!). W wytwarzaniu oprogramowania, obecnie specjalizuje się głównie w PHP.

Można było też usłyszeć, że w Siedlcach planowane jest coś większego dla społeczności programistów i startupów tzn. biura coworkingowe i mentoring. Więcej informacji zapewne będzie wkrótce.

Drugie spotkanie Siedlce.dev

Pierwsze spotkanie cieszyło się dosyć dużą frekwencją (oczywiście jak na tej wielkości miasto). Na kolejnym, 1 czerwca 2017, nie było gorzej. Byli zarówno ci mający komercyjne doświadczenie, początkujący, studenci, jak również trafiały się osoby, które chcą się przebranżowić. Miejmy nadzieje, że będzie to wydarzenie cykliczne, a prelegentów, firm i słuchaczy nie zabraknie.

Ogłoszenie z agendą było dostępne standardowo na Facebooku w wydarzeniu.

Tak jak na poprzednim spotkaniu, tak i teraz były trzy wystąpienia:

„Testy i ich automatyzacja” – Bartosz Cholewiński

Na początku o podstawach testów. Są takie, które użytkownik testuje bez znajomości wnętrza aplikacji (czarna skrzynka) oraz takie, w której kod jest znany (biała skrzynka). Programista jest przywiązany do swojego kodu i zazwyczaj lepiej jest, gdy to ktoś inny ma go „popsuć” tzn. przetestować. Wiadomo, że ktoś z zewnątrz znajdzie więcej błędów, szczególnie takich, których do głowy podczas pisania kodu nie przyszły.

W sytuacji, gdy testów robi się coraz więcej, a praca coraz bardziej żmudna i powtarzalna nadchodzi czas na testy automatyczne np. takie, które automatycznie klikają w aplikacji webowej i sprawdzają zwrócony wynik na stronie. Można użyć do tego np. narzędzia Nightwatch.js. Korzysta ono z Selenium. Warto zainteresować się także PhantomJS i np. Headless Chrome. Testy w Nightwatch.js pisze się łatwo i przyjemnie. Początkowo trzeba poświęcić trochę czasu, ale potem można testować w sposób ciągły (np. podpiąć do Jenkinsa i prowadzić statystyki). Wybierać elementy na stronie w Nightwatch.js można za pomocą selektorów CSS (podobnie jak np. w jQuery) lub XPath (ma trochę więcej możliwości).

„Jak zacząć zarządzać projektem?” – Karol Wójciszko

Większość projekty nie jest kończona na czas i nie mieści się w ustalonym budżecie. Jest to często wina złego zarządzania projektem i niepełnej analizy projektu.

Trzeba poznać kilka zagadnień, żeby móc swobodnie poruszać się w temacie zarządzania projektami.

  • Czym się różni projekt od procesu? Projekt jest unikalny. Jeśli coś jest powtarzalne, to jest już proces.
  • Czym się różni cel od zakresu? Cel to korzyść, coś po co robimy projekt. Zakres to czynności, które należy wykonać, aby zrealizować cel.
  • Trójkąt projektu: zakres, czas i koszt. Nie możemy swobodnie zmieniać jednego parametru bez naruszania innych. Są ze sobą powiązane.

Czy warto robić analizę? Przecież to kosztuje… Okazuje się, że pisząc projekt bez wykonania analizy i tak ją robimy fragmentami w głowie podczas pisania kodu. Lepiej zrobić ją na początku raz a dobrze. Zaoszczędzimy czas, pieniądze i nerwy.

Dobra analiza powinna być negatywna, a nie pozytywna. Od reklamy jaki to projekt będzie dobry jest dział sprzedaży. Analitycy mają płacone za logiczne myślenie i ustalenie co da się zrobić. Lepiej powiedzieć klientowi na początku czego się nie da zrobić niż na końcu. Jak zgodzi się na założenia, które są bardziej realne, to po skończeniu projektu będzie miał większą satysfakcję. Po prostu spełni to jego oczekiwania.

Jak wycenić projekt? Oprócz czasu, można użyć dwóch parametrów: czasochłonność i skomplikowanie. Przepisanie danych do Excela będzie czasochłonne, ale nie skomplikowane. Wymyślenie jakiegoś algorytmu może być mało czasochłonne (przecież to tylko kilka linii kodu), ale jest mocno skomplikowane. Parametr „skomplikowanie” mówi nam jakie jest ryzyko. To właśnie tutaj może coś się nie udać lub zająć dużo więcej czasu niż przewidywaliśmy.

Jednym z typów zadań, które są ryzykowne to zadania „worki”. Jeśli coś jest opisane na bardzo wysokim poziomie abstrakcji, to może okazać się, że składa się tak naprawdę z wielu zadań. Powoduje to, że projekt jest bardziej skomplikowany, bo nie wiemy co dokładnie ma robić. Przez to rośnie ryzyko niepowiedzenia projektu lub przekroczenie zaplanowanego czasu albo kosztów. Takie zbiorcze zadania należy zidentyfikować i zdekomponować (podzielić) na mniejsze. Jedno zadania powinno rozwiązywać jeden problem. Po podzieleniu zadań często okazuje się, że estymowany czas i koszt zwiększa się, zbliżając się tym do tego rzeczywistego (przypominam, że większość projektów przekracza termin i budżet).

„BDD – change your thinking” – Radek Osak

BDD czyli Behavior Driven Development. To podejście w wytwarzaniu oprogramowania wyrosło na TDD (Test Driven Development) czyli pisaniu najpierw testów, a dopiero potem kodu, który przejdzie napisane testy. Dzięki temu wiemy co dokładnie kod ma zrobić, kiedy jest gotowy i… magicznie mamy gotowe testy, które normalnie nie zawsze się pisze.

Opis zadań opiera się na zdaniach sformułowanych za pomocą trzech słów:

  • W celu (co chcesz osiągnąć, po co coś robić)
  • Jako (kto? interesariusz, nie klient, który jest aktorem)
  • Chcę (co zrobić)

W pierwszym wyrażeniu „w celu”, nie należy mylić celu (do czego dojść) z zakresem (jak dojść).

Analiza powinna być jak najkrótsza, ale treściwa. W tym pomaga opis za pomocą BDD. Istnieje do tego specjalny język Gherkin. Tak przygotowany opis zadań (wykonana analiza) można wykorzystać do automatycznego testowania oprogramowania. Służy do tego narzędzie cucumber.

Dzięki takiemu podejściu, wykonana dokumentacja podczas analizy jest bardziej zwięzła (chociaż ja uważam, że czasem potrzebny jest dodatkowy opis). Dokumentacja sporządzona przez analityków służy do testowania projektu. Jest bliższa programistom. BDD ma ułatwić komunikację.

Oczywiście testerzy nadal są potrzebni. Nie wszystko da się przetestować takim opisem zadań. Przykładowo, często potrzebne są testy, które sprawdzają jak wygląda aplikacja.

Britenet

Firma Britenet była sponsorem tego spotkania (pizza!). Co ciekawe w 2015 i 2016 została wytypowana w rankingu AudIT, prowadzonym przez Computerworld, za najlepsze miejsce pracy IT w Polsce. Jak to duże firmy, szczególnie te skupione na outsourcingu, pracują w wielu różnych technologiach (w tym ostatnio coraz popularniejsze Salesforce).

Kolejne spotkania

Szykują się kolejne spotkania. Miejmy nadzieję, że jeszcze w czerwcu (najpewniej w któryś czwartek). Obecnie trwa nabór prelegentów.

Na fanpage na Facebooku Podlasie.dev pojawiają się aktualne informacje. Jeśli ktoś ma jakieś ciekawe doświadczenia lub idee warte rozpowszechniania (trochę jak idea TED), to zachęcam do zgłaszania się do aktywnego uczestnictwa.

Istnieje również grupa na Facebooku Siedlce.dev, na której można pogadać z lokalną społecznością programistów z Siedlec i okolic.

Warsztaty Angular i Spring na Warszawskich Dniach Informatyki 2017

Co roku, już od ośmiu lat, odbywają się Warszawskie Dni Informatyki. Obszerna relacja z poprzedniego roku, jak również skrót historii WDI dostępny jest w tym wpisie.

Tegoroczne WDI odbyło się 28-29 marca 2017. Jak zawsze było wiele wykładów, warsztatów, panele dyskusyjne i konkursy. Nie zabrakło także Giełdy Pracy IT. W tym roku poprowadziłem również warsztaty: Integracja: Angular i Spring od podstaw.

Wykłady i warsztaty

Jak zawsze WDI rozpoczęło się otwarciem.

Trochę dziwnym posunięciem było wrzucenie na otwarcie reklamy utworzenia nowego kierunku studiów na uczelni. Wiadomo niż demograficzny, mało studentów, ale było na to miejsce w prezentacji, która miała odbyć się później. Chociaż muszę przyznać, że sam kierunek ciekawy: Data Science (Inżynieria i Analiza Danych). Odniosłem jednak wrażenie, że nastawili się bardziej na matematykę i bazy danych niż na sztuczną inteligencję i uczenie maszynowe. Obecnie podobne kierunki są otwierane nie tylko na Politechnice Warszawskiej, ale też np. na UPH w Siedlcach: Inżynieria Systemów Danych.

Pierwsze prezentacje były od sponsorów, ale również niosły ze sobą wartość merytoryczną. Aula była wypełniona po brzegi. Później gdy wykłady odbywały się równolegle w różnych salach było już luźniej.

Asseco podczas swojej prezentacji przygotowało ciekawy sposób na przeprowadzenie konkursu – zamiast zadawać pytanie publiczności i wybierać osobę (co jest trudne jak jest dużo osób), to zadali pytanie i odpowiedź „tak”/”nie” należało przesłać SMS-em podczas prezentacji na wybrany numer. Rozstrzygnięcie odbyło się na koniec wystąpienia. Koszt wysłania SMS-a to było kilka zł, więc nawet nagroda mogła się zwrócić 😉 Sposób wyłonienia zwycięzcy polegał na „kto pierwszy ten lepszy”. Ale należy się pochwała za próbę burzenia czwartej ściany i wykorzystanie technologii do interakcji ze słuchaczami. W końcu mieli temat o technologiach mobilnych. Można by się zastanowić nad zastąpieniem SMS-ów jakąś aplikacją (średni pomysł, bo raczej nie lubimy instalować wielu aplikacji) lub stroną internetową z formularzem (każdy musiałby mieć dostęp do internetu, a przy takim skupisku ludzi czasem może być z tym problem). Pytanie mogłoby mieć też jakiś element „jakościowy”, żeby był większy zakres możliwych odpowiedzi (np. jakaś liczba). Wtedy można by wprowadzić czynnik tego jak ktoś dobrze odpowiedział na pytanie, zamiast samego refleksu. Oczywiście przy takiej liczbie uczestników, musiałaby być aplikacja po stronie serwera, która od razu analizowałaby nadsyłane odpowiedzi, aby możliwe było szybkie wyłonienie zwycięzcy.

Wykładów było bardzo dużo. Chyba każdy z IT mógł znaleźć coś dla siebie. Cała lista tematów dostępna jest w agendzie (jeśli czytasz to długi czas po napisaniu tego wpisu, to na stronie pewnie jest już nowa agenda – tutaj kopia strony – niestety inny archiwizer nie dał rady tego poprawnie przechwycić, ale tematy i tekst abstraktów da się przeczytać).

W tym roku wziąłem również aktywny udział w Warszawskich Dniach Informatyki. Warsztaty „Integracja: Angular i Spring od podstaw”.

Osobiście w tym roku nie byłem na wielu wykładach (jak również na Panelu Rektorskim, który odbył się 31 marca 2017 i jego tematyką był Przemysł 4.0), ale dało się zauważyć kilka ciekawych tematów. Poniżej wybrałem te, które według mniej są najbardziej godne uwagi lub mocno się wyróżniły.

Dzień 1:

  • Prezentacje Asseco (technologie mobilne – już wcześniej wspominane) i Accenture (sztuczna inteligencja).
  • Eclipse Collections (kiedyś nazywało się GS Collections od twórców, firmy Goldman Sachs, ale oddali projekt pod opiekę Eclipse). Mówią, że EC są lepsze od tych kolekcji w standardowej bibliotece Javy, ale nadal zgodne z API Javy (również Java 8).
  • Znane i modne technologie: Java, .NET, JavaScript.
  • Webdev: Flux, Redux, ReactJS, AngularJS, Angular 2, React Native
  • Blockchain (to co jest istotą Bitcoina).
  • Alternatywne języki JVM. Te bardziej znane np. Groovy i mniej znany Gosu (języki JVM będą powstawać w tempie frameworków JavaScript? 😉 ).
  • Salesforce. Jest to CRM, do którego można dopisywać kod, aby rozszerzać jego możliwości i dstosowywać do klienta (coś w stylu Microsoft Dynamics od Microsoftu). Tutorial jest dostępny na stronie. Używają go m.in. w firmach Accenture i PwC.
  • Chmury, Internet of Things.
  • Gamedev: Unreal Engine 4 na iOS i Android.
  • Wirtualna rzeczywistość w przeglądarce internetowej: WebVR i framework A-Frame.
  • Warsztaty: Machine Learning w R, Kanban (Scrum), Data Science i Big Data, Spring Framework, CSS, programowanie w R i wykresy w ggplot2, Scrum, Xamarin.Android w C# oraz warsztaty, które prowadziłem Integracja: Angular i Spring od podstaw – o tym poniżej.

Dzień 2:

  • Tworzenie gier w HTML5 i JavaScript. Temat wielokrotnie pojawiający się na konferencjach, ale jak widać nadal na czasie.
  • Business Intelligence (systemy FDS – Financial Data Store).
  • TIBCO BusinessWorks (integracja danych), TIBCO Spotfire (analiza danych).
  • MVC, MVP, MVVM.
  • Elixir funkcyjny język programowania.
  • TDD (Test Driven Development).
  • Dalej chmury i IoT…
  • Hadoop, Open Modular Environment.
  • Cały panel o bezpieczeństwie od Zaufanej Trzeciej Strony.
  • Panel mobilny: Android, Kotlin na Androida, Xamarin, AppleScript, iOS.
  • Panel Data science: podstawowe algorytmy uczenia maszynowego (algorytm regresji logistycznej, sieci neuronowe, sieci konwolucyjne), Jupitem, RTools i RStudio.
  • Warsztaty: D3.js, Android, gra w Unreal Engine 4 (C++), VBA w Excelu, Spring Boot i MyBatis, BeagleBone (komputer jedno-płytkowy), aplikacje mobilne z Azure, Bizagi, Spring Data.

Warsztaty Angular i Spring

Smycze dla Prelegentów (VIP) na WDI – wreszcie bez kolejek 😉

Prowadziłem już wcześniej warsztaty z podstaw AngularJS na UPH w Siedlcach. Materiały i ich szczegółowy opis umieściłem w podsumowaniu. Bardzo miło je wspominam. Szczególnie jak na pierwszy raz poprowadzone warsztaty.

Na Warszawskie Dni Informatyki jeździłem co roku od kiedy zacząłem studiować (podziękowania dla starszych kolegów i koleżanek z uczelni z KNI Genbit, którzy również jeździli i była większa motywacja jechać). Zawsze jednak jako uczestnik bierny. Jest to duże wydarzenie, na którym słucha się profesjonalistów i można dowiedzieć się czegoś ciekawego. Moja aktywność na WDI w kolejnych latach zwiększyła się jedynie do informowania o wydarzeniu na uczelni w Siedlcach i otrzymywaniu zaproszeń na Panel Rektorski.

W tym roku otrzymałem również zaproszenie do przeprowadzenia warsztatów na WDI. Byłem zaskoczony, ucieszony i jednocześnie trochę wystraszony. Występowałem wcześniej jako prelegent na licznych konferencjach, więc miałem w tym doświadczenie, ale nie były to wydarzenia takiej wielkości. Chciałem wystąpić na WDI, bo to byłby dla mnie zaszczyt – myślałem, że jak zdobędę wystarczająco wiedzy i doświadczenia, to kiedyś to zrobię. Nie myślałem, że nastąpi to tak szybko. Dobrze się złożyło, że dwa tygodnie wcześniej przeprowadziłem lokalne warsztaty (nie zdążyłem jednak przeprowadzić planowanej drugiej części), bo nabrałem trochę doświadczenia w prowadzeniu warsztatów, a nie tylko prezentacjach. Uznałem, że ta sama tematyka będzie odpowiednia. Czyli AngularJS i Spring. Chciałem jednak zaznaczyć, że będą to same podstawy, żeby profesjonaliści z wieloletnim doświadczeniem nie spodziewali się zaawansowanych zagadnień.

Chciałem, żeby wszystko odbyło się bezbłędnie. Należało napisać scenariusz, a czasu na przygotowanie było niewiele. Podczas warsztatów, na których jest większa liczba osób, trudno jednej osobie być dostępnym dla całej sali. Na szczęście udało mi się skompletować zespół czterech osób. Oprócz mnie, byli to studenci II roku informatyki, ale chętni i zdolni. Tematykę warsztatów podzieliliśmy na części i każdy odpowiadał za opracowanie i poprowadzenie własnej części.

  • Jakub Malinowski – Spring Boot, Spring Data, kontrolery, wystawienie API REST,
  • Marcin Kowalczyk – omówienie REST, podstawy AngularJS, pobranie danych z API,
  • Marta Kisielińska – AngularJS, frontend, CSS,
  • Kamil Chaciak – więcej możliwości AngularJS.

Napisaliśmy sobie scenariusz i zaplanowaliśmy live coding, żeby pisać kod i tłumaczyć go równocześnie (było to ułatwione, bo prowadzących było kilku).

IDE na warsztaty wybraliśmy Spring Tool Suite, żeby każdy mógł swobodnie używać (jest na bazie Eclipse, więc wygląda znajomo; zaś IntelliJ IDEA w wersji darmowej jest dostępna tylko Community). Do samego frontendu mogliśmy wziąć inne IDE (np. Sublime Text), ale nie chcieliśmy komplikować – zrobiliśmy jeden projekt w obu technologiach.

Do pokazania Spring Data potrzebna była jakaś baza danych. Nie chcieliśmy używać MySQL lub PostgreSQL, aby uczestnicy nie musieli instalować kolejnej rzeczy. SQLite nie jest domyślnie wspierany przez Spring Data. Użyliśmy więc bazy H2, która umieszczona była jedynie w pamięci operacyjnej (in-memory).

Do testów endpointa API REST użyliśmy wtyczki Postman w Chrome.

Kod na GitHubie

Czas warsztatów był ograniczony, więc wygenerowaliśmy podstawowy szablon projektu i wrzuciliśmy na GitHuba do repozytorium warsztaty-wdi-2017, aby uczestnicy mogli je sobie ściągnąć i pracować.

W repozytorium są commity:

Wrażenia z przeprowadzonych warsztatów

Warsztaty ostatecznie zostały wpisane do agendy pod tematem: Integracja: Angular i Spring od podstaw. Abstrakt jaki umieściliśmy w agendzie:

Budowanie aplikacji webowych to obecnie najczęstsze zajęcie programistów. Chcesz dowiedzieć się jak w szybki sposób zrobić aplikację w stylu SPA oraz jak to połączyć z REST-ową resztą w backendzie? Na warsztatach nauczysz się od podstaw tworzyć projekty z użyciem Angular i Spring.

Warsztaty poprowadzą studenci z Koła Naukowego Programistów działającego przy Instytucie Informatyki Uniwersytetu Przyrodniczo-Humanistycznego w Siedlcach.

Książeczki z agendą rozdawane podczas konferencji WDI

Widzieliśmy, że podczas rejestracji miejsca na nasze warsztaty zostały bardzo szybko zapełnione. Efektem tego było dużo osób pod salą przed warsztatami. Oczywiście nie obyło się bez drobnych problemów organizacyjnych, ale przy takiej skali wydarzenia wcale się nie dziwię. W czasie gdy próbowaliśmy uzyskać dostęp do sali i pilot do projektora, uczestnicy zaczęli wnosić krzesła z korytarza do sali, bo było tyle osób, że zabrakło miejsc (!). Widać rejestracja była zrobiona „z zapasem”, bo było więcej chętnych niż przewidziano.

Przed uruchomieniem projektora zrobiliśmy krótki wstęp i rozpoznanie na jakimś poziomie są uczestnicy (pomaga to w dostosowaniu programu warsztatów i tego jak szczegółowo tłumaczyć). Dalej poszło według scenariusza. Trochę szkoda, że uczestnicy nie mieli dostępu do internetu i nie mogli pracować razem z nami (chociaż nawet jakby zostało uruchomione WiFi, to ciekawe jakby to wyglądało przy takim tłumie). Ale nic straconego, bo kod umieściliśmy na GitHubie. Niektórzy od razu planowali swoje „warsztaty” jako prezentacje – my chociaż spróbowaliśmy. Chociaż oprócz IDE i projektu mogliśmy spróbować wrzucić na pendriva również Mavena offline.

W trakcie warsztatów i po warsztatach były pytania, nawet dużo. Widać było zainteresowanie. Jednak popularne technologie na rynku pracy przyciągają.

Warto było się przygotować i wziąć aktywny udział w WDI. Dobrze również, że udało się skompletować zespół i poprowadzić to wspólnie – zawsze to raźniej i więcej pomysłów. Przećwiczyłem sobie również pracę w zespole. Co ciekawe niektóre osoby lepiej sprawdzały się przed warsztatami podczas przygotować, a inne już w trakcie prowadzenia – każda z osób była bardzo przydatna w różnych etapach.

Giełda Pracy IT

Nie samymi wykładami i warsztatami człowiek żyje. Jak zawsze, odbyły się również targi pracy. Były one dla mnie szczególne ważne, bo gdy kończy się studia to myśli się o stałym zatrudnieniu.

Firm było dużo, dlatego przygotowałem sobie o co pytać firmy, co ja mogę zaoferować i co bym chciał, żeby miała firma:

  • Java i Angular (Spring i JavaScript). Można kłócić się, który język programowania lepszy: Java, C#, PHP czy jeszcze inny, ale na któryś trzeba się zdecydować. Wybrałem Javę. Najlepiej aplikacje w Springu. Obecnie większość aplikacji pisze się w REST, dlatego trzeba wybrać jakiś framework frontendowy w JavaScript (bo jednak chciałbym dążyć do full stack developer). Wybór też jest duży: Angular, React, Vue itd. Wybrałem Angular (znam AngularJS, ale wchodzi Angular 2, a nawet 4 i chętnie go się nauczę).
  • Chciałbym, aby w firmie używało się dobrych/modnych/nowych narzędzi m.in. GIT, Jira/Jenkins/Gerrit. Licencja na IntelliJ IDEA to chyba już obowiązek. Tak samo jak praca w Scrumie.
  • Czy firma ma głównie klientów z Polski czy z zagranicy (ma to związek koniecznością bardzo dobrej znajomości języka angielskiego, a nie tylko czytania dokumentacji).
  • Branża, aby nie finanse (z tego co słychać panuje tam inna, bardziej formalna, kultura pracy np. dress code, praca u klienta zamiast w siedzibie firmy).
  • Czy umożliwia pracę w niepełnym wymierza godzin np. 3/5 lub chociaż 4/5.
  • Lokalizacja to oczywiście Warszawa. Najlepiej z dobrym dojazdem komunikacją (metro jest OK, ale ul. Domaniewska może niekoniecznie). Dobry dojazd do siedziby firmy też jest na nic jak praca jest głownie u klienta.
  • Warto spytać o wynagrodzenie, chociaż na juniora odpowiedź jest raczej znana (zazwyczaj i tak nie podana aż do rozmowy rekrutacyjnej).

Przejdźmy do konkretnych firm. Nie byłem u wszystkich, ale wspomnę te ciekawe lub bardziej wyróżniające się. To tylko opinie na podstawie giełdy pracy:

  • Asseco. Wiadomo, sponsor, więc wyróżnia się, ale firma i tak znana. Niewiele jest polskich korporacji IT. Szkoda, że na stoiskach był głownie HR, a technicznych osób nie zauważyłem, więc nie można było wypytać o szczegóły. Ofert bardzo różne, skupię się jednak ja Javie i JS. Mocno skupiają się na stażach (a potem z przedłużeniem na kolejny staż). Ale nie dziwię się, bo jest wiele studentów, którzy technologii nie znają. Nie wszystkie uczelnie mają rzeczy na czasie w programie studiów, a niewiele studentów samemu się dokształca. Oferta na Javę jest, jednak wypisane trochę stare technologie: Java EE z serwletami i JSP (nie ma Springa), Ant (serio? nie Maven?), JAX-WS i SOAP (zamiast REST), Eclipse (nie IntelliJ IDEA), pojawia się też SVN. Albo po prostu mają stare, nieaktualizowane ogłoszenie albo krążące negatywne opinie po części się sprawdzają. Mimo tego wrażenie sympatyczne, stawiają na rozwój (przynajmniej na papierze, ciekawe jak w praktyce).
  • Accenture. Kolejny sponsor. Zagraniczna korporacja, ale bardzo aktywna na wydarzeniach. Ciekawe tematy i projekty patrząc po wystąpieniach na konferencjach. W ogłoszeniach mało konkretów. Na stoisku głównie HR, ale techniczne osoby też można spotkać. Ogłoszenia dla Javowców niby są, ale zauważyłem, że szukają mocno osób do… Cobola.
  • Sollers Consulting. Pisanie jakiejś aplikacji w mało znanym alternatywnym języku JVM Gosu? Nie, dzięki. Jeśli nie Java, to wolałbym uczyć się już Scali, Groovy’ego lub Clojure.
  • Citi. Mimo że bank, to zapewniali, że dział IT jest duży i są dosyć autonomiczni (tzn. po prostu piszą sobie sami projekty). Aż dziwne, że jest taka swoboda w banku. Technologie rzeczywiście mają nowe. Na stoisku osoby techniczne i znające używane rozwiązania.
  • Billennium. Pamiętam, że kiedyś byli aktywniejsi na WDI. Dobre wystąpienia, aktywne stoisko z technicznymi osobami, fajne oferty pracy dla Javowców. Czyżby zapotrzebowanie zostało już zaspokojone?
  • BMS. Mniej znana firma. Może nie jest jakaś duża, ale polska i wydaje się sympatyczna. Dobra oferta pracy dla Javowca, modne narzędzia (tak, jest IntelliJ itd). Udzielają się na wielu konferencjach i wydarzeniach, a to się ceni. Lokalizacja dobra. Ale kawałek drogi od metra. Podobno przenoszą się bliżej? Szkoda, że nie ma o tym nigdzie publicznej informacji.
  • CodiLime. Swego czasu bardzo aktywni, co chwilę było widać gdzieś warsztaty od nich. Chyba w połowie zagraniczna. Fajnie, że zajmują się Data Science  Deep Learningiem (deepsense.io).
  • EL Passion. Firma dla luzaków. Trochę hipsterskie technologie (Ruby,  Swify, Kotlin). Starają się sprawiać wrażenie zagranicznej firmy.
  • Lingaro. Firma jak firma, wiele ofert, chcą sprawiać wrażenia luzaków.
  • SAS. Bardzo znana firma jeśli chodzi o Data science. Teraz to coraz modniejsze. Programiści raczej szukają pracy gdzie indziej. Tutaj mogliby się odnaleźć matematycy. Oni jednak odpadają przez nieumiejętność podstaw programowania. Teraz powstają na uczelniach kierunki studiów związane z Data science (dobry pomysł jako drugi kierunek dla matematyków). Jeśli to się sprawdzi, to SAS nie powinien już mieć problemu z pracownikami. Jeśli chcieli by ściągnąć programistów do Data science, to bardziej zachęcające jest skupienie na sztucznej inteligencji (np. uczenie maszynowe).
  • TIBCO. Mają swoje rozwiązania. Tylko czy programiści chcą dopisywać do istniejących narzędzi czy jednak wolą pisać nowe aplikacje (oczywiście pytanie retoryczne)?
  • PwC. Szczerze mówiąc nie wiedziałem czym się zajmują. Okazuje się, że wieloma rzeczami (kosnulting, wdrożenia itd. itd). Co jednak oferują dla programistów? Rozwój przy CRM albo .NET z Microsoft Dynamics albo Salesforce. Niestety nie ma ofert na Javę. Pracownicy mocno zmotywowani. Oby tak dalej. Gdybym nie był zdecydowany co chcę robić (pisanie kodu w Javie/JS), to może i dałbym się przekonać na tego Salesforce. Już wyżej wspominałem, dostępny jest tutorial, więc można sobie zobaczyć jak to wygląda. Jak ktoś umie podstawy programowania, ale nie przeszkadza m, że będzie dopisywał do istniejącego narzędzia w jakimś wewnętrznym języku, to jest to bardzo dobra oferta. Na stoisku były osoby, które rzeczywiście pracują przy danym rozwiązaniu – może to jest klucz do dobrego zaprezentowania firmy na targach pracy.
  • SAP. Wiadomo, wsparcie i wdrożenia ich rozwiązania. Nie pytałem teraz, ale kiedyś podobno nie szukali programistów do Warszawy (tylko do innego miasta).
  • Connectis. Na stronie wyglądają bardzo dobrze. Na targach było słabiej. Może kwestia tego, że był tylko HR bez technicznych osób oraz okazało się, że to tylko outsourcing (wynajmowanie programistów dla klientów). Niektórzy może potraktują to jako zaletę, bo różnorodność projektów i klientów oraz potencjalnie większe zarobki. Ale nie do wszystkich to przemawia.

Te wypunktowania może wydawać się trochę na wyrost. Zwłaszcza mogą tak pomyśleć osoby z HR-ów, które dbają o dobry wizerunek dla pracownika. Może rzeczywiście czegoś nie zauważyłem, nie usłyszałem lub pomyliłem i ktoś może mi to mieć za złe. Ale jeśli chociaż część trafiłem i pracodawcy będą w stanie niskim kosztem to poprawić, bo dowiedzą się jakie oczekiwania mają pracownicy, to myślę, że było warto. Można by to podsumować:

  • Jak wystawiać się na targach pracy, to oprócz HR-u niech będzie ktoś techniczny (albo ktoś z HR kto wcześniej wypytał pracowników z odpowiednich działów). Inaczej równie dobrze może być hostessa do rozdawania ulotek. Kandydaci chcą wiedzieć jakich technologii w firmie się używa, jak wygląda praca, co technicznie jest zapewnione, jakie są wykorzystywane narzędzia itd. itd.
  • Oferty pracy powinny być aktualne. Chyba że rzeczywiście używacie starych technologii. Najlepiej jakby oferty odpowiadały rzeczywistym zapotrzebowaniu w projektach. Wpisanie do oferty jakiejś technologii „a wpisz tego Springa, bo teraz wszyscy to wpisują” jest niedopuszczalne.
  • Zawarcie w ofercie jak najwięcej informacji, o które pytają kandydaci (może to być również na stronie internetowej). Takie FAQ, żeby wszyscy nie pytali o to samo.

Podsumowanie

Działo się dużo – jak co roku. Wiele ciekawych wykładów, warsztatów i giełda pracy. Sam nie ze wszystkiego w pełni skorzystałem, bo brałem również aktywny udział prowadząc warsztaty.

Było to moje ostatnie WDI jako student. Zobaczymy jak potoczy się moje dalsze życie zawodowe i co przez rok się zmieni. Mam nadzieję, że mój przyszły pracodawca przychyli się do mojego kolejnego wyjazdu na WDI za rok 😉

Wierzę, że studenci informatyki z uczelni Siedlec nadal będą odwiedzać Warszawskie Dni Informatyki. Szczególnie z dwóch kół: Koła Naukowego Informatyków Genbit i Koła Naukowego Programistów. Daje to przecież wymierne korzyści: w postaci praktycznej wiedzy i inspiracji oraz zdobycia pracy w przyszłości. Oby tylko prowadzący zajęcia byli wyrozumiali, że studenci ich opuszczają na dwa dni.

PS. Na stronie Instytutu Informatyki pojawiło się sprawozdanie: Studenci naszego instytutu poprowadzili warsztaty na Warszawskich Dniach Informatyki 2017.

Podsumowanie projektu AgendaEditor 2016

W poprzednim roku wziąłem udział w konkursie Daj Się Poznać 2016. Miałem wiele różnych pomysłów, jednak wybrałem edytor agendy. Aplikacja ma zautomatyzować prace wykonywaną w Excelu i Wordzie.

Projekt AgendaEditor był rozwijany na GitHubie: https://github.com/mkczyk/agenda-editor/

Pełna wersja aplikacji nie powstała, ale udało mi się zrobić założoną wersję MVP (Minimum Viable Product – minimalna wersja produktu). Ostatnia wersja wyglądała tak (tutaj ostatni wpis z aktualizacją).

Dzięki konkursowi i rozwojowi projektu, powstał też prawie-kurs AngularJS. Nie jest to dokładnie forma kursu, ale w większości co drugi post dotyczył samego Angulara, a każdy kolejny zastosowania wiedzy w praktyce. Dlatego na blogu najlepiej wpisy czytać od końca (w kolejności dodawania). Tutaj wygodna kolejność:

Funkcjonalności jakie zakładam do dodania, to:

  • Import danych z Google Docs (jak robimy formularz zgłoszeniowy, to dane lądują w arkuszu Google Sheets; zamiast ręcznie kopiować, dane mogłyby automatycznie lądować w edytorze po podaniu linku).
  • Generowanie agendy w formie ogłoszenia (PDF/DOC/DOCX/PNG).
  • Dodawanie przerw (nie tylko wystąpień).

Obecnie dużo da się zrobić po stronie klienta. Ale spodziewam się, że wreszcie przyda się backend i będę mógł pisać o Javie i Springu.

Wartymi rozważenia funkcjonalnościami jeszcze są:

  • Automatyczne tworzenie ankiet Google Forms przez API. Często na konferencje/seminaria formularze zgłoszeniowe tworzone są własnie tam. Aplikacja mogłoby robić takie formularze automatycznie (a może i od razu pobierać link do arkusza).
  • Aby utworzyć formularz, wymagane są uprawnienia. Dlatego należy dodać logowanie przez Google OAuth 2.
  • I tutaj może już być wymagany backend. Przechowywanie w bazie zarejestrowanych użytkowników czy implementacja OAuth (przechowywanie niejawnych kodów aplikacji).

Chciałem również pobawić się sztuczną inteligencją (Machine Learning, Deep Learning np. TensorFlow lub Deeplearning4j). Ale w takiej aplikacji nie mam pomysłu jakie mogłoby mieć tu zastosowanie. Początkowo chciałem zaprzęgnąć uczenie maszynowe do pobierania danych ze zgłoszeń przez emailowych (często organizatorzy konferencji w ten sposób mają rejestrację – a potem trzeba szukać gdzie jest tytuł wystąpienia, kto się zgłosił itd.). Ale po pierwsze nie miałbym dużo danych uczących. A po drugie chyba lepiej próbować zachęcać do korzystania z formularzy zamiast pisania emaili ze zgłoszeniami (a co jakby zgłoszeń było 500?). Może uda się zastosować uczenie maszynowe w innym miejscu (np. wykrywanie pól w arkuszu z danymi). Albo po prostu pobawię się poza tym projektem (zobaczymy czy mi czas pozwoli).

Pierwsze warsztaty z AngularJS

Niedawno poprowadziłem warsztaty z podstaw AngularJS (3 marca 2017 w Siedlcach na UPH). Uczestnicy poznali framework i byli zadowoleni. Materiały dostępne są na stronie: http://marcinkowalczyk.pl/warsztaty/uph/angular

W tym artykule chciałbym przedstawić jak doszło do tego, że zrobiłem te warsztaty, dlaczego takie a nie inne zagadnienia i jak to wyglądało od kuchni.

Gdzie poznałem AngularJS

Około 3 lata temu, jak byłem w połowie studiów, było ogłoszenie, że będą Warsztaty dotyczące AngularJS. Jak to usłyszałem, to nie miałem pojęcia co to jest. Poszukałem i dowiedziałem się tyle, że to taka „biblioteka” do JavaScript (a właściwie framework). Pomyślałem, że warto iść i nauczyć się czegoś nowego. Nawet jak teraz nie miałem zamiaru tego wykorzystywać. Teraz sobie myślę, że jak początkujący zapisywali się na warsztaty, któe teraz sam prowadziłem, mogli podobnie się czuć.

Warsztaty, owszem, odbyły się: Warsztaty z Angular JS – podsumowanie. Poziom merytoryczny był bardzo wysoki (a przynajmniej z tego na ile teraz pamiętam i na ile byłem wtedy to w stanie ocenić). I tego można było się spodziewać, w końcu robili to ludzie, którzy piszą w tym na co dzień. Tu nie mam nic do zarzucenia. Trochę przeszkadzała mi jednak inna kwestia. Materiału było dużo, a według mnie treści niewystarczająco wytłumaczone, co powodowało, że miało się wrażenie, że warsztaty toczyły się to zbyt szybko. Żeby nie było, że to tylko moje zdanie, bo po prostu nie zrozumiałem, to rozmawiałem z kolegami i większość miała to samo zdanie. Być może studenci z ówczesnych starszych lat lepiej załapli ideę. Ale spodziewałem się wszystkiego od podstaw. Z warsztatów wynieśliśmy jedynie początkową wiedzę np. jak pisać {{wyrażenia}}. Ale już to co było dalej, praktycznie od kontrolerów, zbytnio nie trafiło do nas. Nie wspominając o pisaniu dyrektyw czy filtrów. Tak naprawdę nie miałem pewności jak działają te kontrolery w Angularze (czy to wykonuje się po stronie klienta czy może jednak w stylu Node.js po stronie serwera – bo przecież serwer był wymagany do pisania aplikacji). Ale cieszę się, że chociaż tyle zapoznaliśmy się z tym frameworkiem.

Jakiś czas później poszedłem na staż. Mieliśmy pisać w Spring MVC, ale w zespole zdecydowaliśmy, że jednak wprowadzimy Angulara (a Spring będzie tylko na backendzie i komunikacja przez REST). Dwóch pracowników firmy zrobiło nam krótkie szkolenie z Angulara. Było to szybkie wprowadzenie dla tych co nie mieli z nim doczynienia i powtózenie dla tych co już coś wcześniej słyszeli. I po prostu zaczęliśmy pisać projekt. Trochę tutoriali z Internetu, dokumentacja, jakieś przykładowe projekty i jakoś poszło. Ale pamiętam jak np. zastanawialiśmy się na zwykłym przełączaniem podstron – chwilę nam zajęło zanim zorientowaliśmy się, że do tego jest routing. Teraz jest to oczywiste.

Następnie jak wybierałem technologie do pisania pracy inżynierskiej, to wybrałem to co znałem i jest modne, czyli Spring+AngularJS. Bardzo przyjemnie się w tym pisało.

Pomysł na nauczenie innych Angulara

Na kole naukowym na uczelni był pomysł, żeby pisać projekty, ale trochę się z tym zeszło (wiadomo: priorytet miały projekty w ramach programu studiów). Trzeba też było wybrać jakąś fajną technologię, którą wszyscy znają lub jej się nauczą.

Pamiętałem, że Angular jest fajny, ale większość nie miała z nim do czynienia. Jednak ja już czegoś się nauczyłem. Dlatego wpadłem na pomysł, że mógłbym nauczyć innych.

Seminarium?

Był to czas, w którym często występowałem na seminariach naukowych. Mógłbym zrobić prezentację, ale spodziewałem się, że samo opowiedzenie o frameworku, to tylko zachęta do uczenia i nikt przez to nie zdobędzie praktycznych umiejętności. Żeby nauczyć Angulara, prezentacja na seminarium by nie wystarczyła – to musiało być coś więcej. Opowiedziałem jednak o ogólnej idei – jak to się robi, że backend tylko wystawia dane, a Angular na frontendzie je pobiera i coś z nimi robi – czyli po prostu styl architektoniczny REST.

Warsztaty!

Oczywiście najlepszym rozwiązaniem były warsztaty. Wtedy uczestnicy mogą coś praktycznie napisać. Jednak w jakiej formie je zrobić?

„Wykład” na auli, gdzie na projektorze pokazuję livecoding, a uczestnicy siadają ze swoimi laptopami i robią zadania. Tak zazwyczaj są przeprowadzane u nas warsztaty. Bo fizycznie nie da się zrobić inaczej, bo jest duża publiczność. Ale ma to wady. Po pierwsze prowadzący nie ma możliwości pochylić się nad każdym uczestnikiem. A po drugie, na auli nie można się wygodnie rozłożyć. Dodać też należy, że nie każdy ma swój spręt (szczególnie na pierwszym roku).

Zajęcia w sali laboratoryjnej. Tak są u nas przeprowadzane laboratoria. Grupy są małe, więc jest w miarę indywidualne podejście. Chociaż z drugiej to też problem, gdy chętnych jest wielu – trzeba robić powtórkę, bo sala nie pomieści więcej niż 20-25 osób. Taka sala jest wygodna i nie ma problemu, żeby pracować uczelnianym sprzęcie lub przynieść własny. Ale była pewna duża wada: w sali laboratoryjnej nie ma projektora (tak, owszem, nowsze wydziały mają, ale nie wszędzie to jeszcze jest). Gdzie miałem pokazywać kod? Pisać na tablicy? Uczestnicy mieli tylko sami patrzeć w przygotowane materiały? To nie byłoby tak jak chciałem to zrobić.

Zajęcia w sali laboratoryjnej + projektor. Udało się wypożyczyć projektor i po prostu postawić w sali. Było to najlepsze rozwiązanie. Miałem zalety i wyeliminowane wady poprzednich rozwiązań. Może poza pojemnością sali – ale z drugiej strony to była też zaleta, bo wymuszone ograniczenie spowodowało możliwość kontroli postępów każdego na sali i ewentualnej pomocy.

Przygotowanie do warsztatów

Miałem za sobą wiele wystąpień na konferencjach czy seminariach. Przez tyle czasu nauczyłem się robić sprawnie prezentacje i przygotować się do wystąpienia. Jednak warsztaty to co innego. Tu jest dużo większa interakcje z uczestnikami (bo na wykładach też jest, ale rzadziej) i trzeba zaplanować nie tylko co ja będę robił, ale także co inni będą robili. To była dla mnie szansa, aby nauczyć się to robić i zebrać doświadczenie. Gdzie indziej mógłbym sprawdzić swoje umiejętności? Ja przetestowałem prowadzenie warsztatów na studentach, a oni dostali wiedzę, którą mogłem przekazać. Myślę, że to sytuacja win-win.

Forma materiałów

Jak już zdecydowałem, że zrobię warsztaty, to trzeba było przygotować jakieś materiały. Sama prezentacja to za mało, bo uczestnicy powinni mieć możliwość skopiowania fragmentów kodu lub powrotu do wcześniejszych informacji.

Popularnym sposobem na laboratoriach jest umieszczenie materiałów w dokumencie PDF. Z jednej strony jest to dobre rozwiązanie, bo można łatwo pobrać i wydrukować. Ale z drugiej format PDF ma wiele wad. Po pierwsze nie jest responsywny i jest przez to niewygodny − jeśli po jednej stronie ustawimy edytor kodu, a po drugiej chcielibyśmy PDF-a z materiałami, to dokument będzie albo bardzo pomniejszony albo będzie trzeba go przewijać. Poza tym są trudności we wstawianiu np. animacji do PDF-a (to temat na dłuższy wpis).

Innym podejście jest po prostu strona internetowa z materiałami. Jeśli jest dobrze zrobiona, to bardzo wygodne narzędzie. Początkowo chciałem to napisać sam w HTML z pomocą Angulara+Bootstrapa w samym HTML-u. Uznałem jednak, że przyda mi się jakiś backend np. do włączania/wyłączania dostępu do podstrony lub edycji online w przeglądarce.

Naturalnym do mojego celu wydawałby się Wordpress. W końcu go znam i mam na nim bloga. Jednak nie chciałem umieszczać materiałów bezpośrednio na blogu, a do kilku podstron uznałem, że WordPress jest za ciężki. Poza tym chciałem to pisać w markdown. Pozwoliłoby mi to skupienie się na treści zamiast na technicznych aspektach tworzenia treści. Oczywiście najpierw i tak trzeba poświęcić czas na konfigurację.

Uznałem, że potrzebny jest mi jakiś generator HTML z plików markdowna lub CMS obsługujący płaskie pliki pisane w markdownie. Polecane były:

  • Jekyll − ale go odrzuciłem, bo jest pisany w Ruby. Nie zaprzyjaźniłem się zbytnio z tym językiem, a spodziewałem się, że może być potrzeba zajrzenia w kod lub dopisania czegoś.
  • Sphinx – jest to jednak narzędzie używane do tworzenia dokumentacji w Pythonie.
  • Pico CMS − to już wygląda nieźle, o to mi chodziło.
  • Grav CMS − podobny do Piko, ale nowszy.

Jeckyll jest bardzo popularny, ale chciałem coś innego. Został wybór pomiędzy Piko a Grav. Wybrałem Grav (w skrócie: jest nowszy i fajniejszy).

Wziąłem jeden z dostępnych szablonów, dostosowałem pod siebie i miałem ładna responsywną stronę, na której w prosty sposób mogłem pisać materiały. Uczestnikom warsztatów spodobała się taka forma.

Reklama

Jak robi się jakieś wydarzenie, to trzeba je zareklamować. Członkowie kół dowiedzieli się o warsztatach bezpośrednio poprzez wpis na grupie na Facebooku. Nie chciałem jednak ograniczać uczestników tylko do tych osób.

Na stronę Instytutu Informatyki wrzucony  był news z krótkim opisem (obecnie został usunięty, bo wydarzenie nieaktualne). Oczywiście było także wydarzenie na Facebooku.

Zrobiłem również plakat, który został rozwieszony na uczelni:

warsztaty 3 marca 2017 czarno-biale

Rejestracja i wyniki ankiety

Na warsztaty chciałem przeprowadzić rejestrację. Żebym wiedział kto przyjdzie, ale też ze względu na limit miejsc w sali. Dzięki temu miałem okazję zadać kilka dodatkowych pytań, aby dowiedzieć się czegoś więcej o uczestnikach, poznać oczekiwania i dostosować program warsztatów. Ankietę zrobiłem w Formularzach Google i umieściłem na stronie z materiałami.

Miałem 22 zgłoszenia.

Dlaczego chcesz wziąć udział w warsztatach?

Chcę uczyć się Angulara 18
Chcę uczyć się czegoś nowego 16
Chcę uczyć się JavaScriptu 13
Chcę się uczyć programowania 12
Chcę działać w kole 11
Przyda mi się to przy pisaniu własnych projektów 11
Spędzę ciekawie czas 11
Przyda mi się to w pracy zawodowej 10
Chcę się uczyć frontendu 9
Może to być dobra zabawa 9
Spotkam się ze znajomymi 5
Inne 3

Jak widać ludzie chcieli przyjść na warsztaty z Angulara, bo uwaga… chcieli uczyć się Angulara 😉 Ale warto zwrócić uwagę, że chęć przyjścia na warsztaty wynikała bezpośrednio z chęciu nauki (uczenie się czegoś nowego, uczenie się JS-a, programowania), a w mniejszym stopniu z innych czynników (sposób na nudę, dobra zabawa, spotkanie ze znajomymi).

Rok studiów

rok studiów

Większość uczestników na warsztatach to studenci młodszych lat. Pierwszy i drugi rok, to razem 73% wszystkich osób.

Znajomość technologii które przydają się w pracy z Angularem (JavaScript, jQuery, HTML, CSS, Bootstrap, AngularJS)

technologie

W ankiecie była zdefiniowana skala:

1 – nie słyszałeś o tym wcale.
2 – słyszałeś i widziałeś kod.
3 – umiesz napisać hello world, kiedyś coś w tym napisałeś.
4 – znasz podstawowe konstrukcje, umiesz coś w tym napisać z pomocą poradników.
5 – dobrze znasz podstawy, umiesz napisać coś przydatnego i więcej niż w tutorialu.
6 – znasz więcej szczegółów, wiesz co się dzieje w kodzie, umiesz pomóc innym z problemami.
7 – umiesz wykorzystać bardziej zaawansowane konstrukcje, umiesz rozwiązywać trudniejsze problemy, napisałeś w tym duży projekt lub masz doświadczenie komercyjne.
8 – napisałeś w tym duży projekt lub masz dłuższe doświadczenie komercyjne; widzisz/poprawiasz błędy w samym języku/bibliotece/frameworku.
9 – jesteś specjalistą w tej technologii, masz wieloletnie doświadczenie.
10 – serio to ty napisałeś ten język lub znasz całą dokumentację na pamięć? 😉

Widać, że warsztaty z podstaw Angulara są potrzebne. Ankieta tylko to tylko potwierdziła.

A odnośnie podstawowych technologii, które trzeba znać, żeby móc zacząć z Angularem:

  • JavaScript − wiele osób go nie zna lub zna tylko podstawy, więc trzeba było zacząć od początku. Osoby bardziej zaawansowane miały to już z głowy.
  • HTML − prawdziwy rozkład normalny w sensie probabilistycznym. Z tym problemu nie było.
  • CSS − jest dosyć duże zróżnicowanie, dlatego pominąłem na warsztatach.

jQuery też kilka osób znało, więc zawsze to łatwiej, bo mieli do czynienia z jakimiś bibliotekami JavaScript. Zaś Bootstrap to na oddzielny temat.

Co wiesz o AngularJS?

Większość odpowiedzi to było, że nic nie słyszeli, albo coś słyszeli, ale nic nie umieją. Pojedyncze odpowiedzi, że jakieś minimalne podstawy i wyjątki, że coś więcej. Także przekonało mnie to, że trzeba zacząć wszystko od podstaw.

Czy znasz inne biblioteki lub frameworki JavaScriptowe?

Przeważająca większość nie znała nic dodatkowego (oczywiście poza wyjątkami). Trochę byłem zaskoczony, bo JavaScript jest dosyć popularny (mimo że studiach nie ma na niego położonego dużego nacisku). Ale tym bardziej cieszyłem się, że przyczynię się do poznania przez większość uczestników pierwszego frameworka JS.

Jakiego narzędzia do JavaScript-u używałeś?

Gulp 3
Bower 3
NPM 3
Webpack 2
Grunt 1
Require.js 1
System.js 1
Inne 0

Tu zaś część osób używała różnych menadżerów zależności i innych narzędzi do JS-a. Trochę dziwne, że używali tych narzędzi, a nie podali we wcześniejszym pytaniu jakich używają bibliotek (może nie wszystkim chciało się wpisywać 😉 ).

Wdać, że jest zapotrzebowanie na Gulpa czy Webpacka.

Jakiego IDE używasz/używałeś?

Notepad++ 9
Atom 9
NetBeans 9
Eclipse 8
Sublime Text 6
IntelliJ IDEA 5
Visual Studio Code 4
Brackets 2
WebStorm 2
Inne 2

Ja używam IntelliJ IDEA. Na warsztaty jednak uznałem, że wybiorę coś lżejszego, żeby każdy mógł szybko pobrać. Padło na Sublime Text.

Zadałem pytanie, trochę z ciekawości, a trochę, żeby zorientować się w czym inni piszą. Notepad++ jest popularny i jego wynik jest oczywisty. Atom i NetBeans prawdopodobnie ma wysoką pozycję, bo jest używany na laboratoriach na studiach (NetBeans w związku z Javą na Programowaniu Obiektowym, a Atom na nowym przedmiocie Podstawy Technologii WWW). Można się spierać który z tej grupy trzech edytorów jest najlepszy: Atom, Sublie Text, Brackets (ostatnio dołączył Visual Studio Code). Ale w takich podstawach edytor nie był tak istotny.

Inne technologie (C/C++, Java, Spring, Node.js, c#, PHP, Python)

inne technologie

(Skala jak wyżej: 1 – nie umiem, 10 – umiem bardzo dobrze.)

Nie musiałem zadawać tego pytania, ale chciałem się dowiedzieć jak ogólnie uczestnicy czują się z programowaniem. Poza tym chciałem też wybadać sytuację na przyszłość, jakie byłyby możliwe do zrobienia kolejne warsztaty. Przykładowo, żeby zrobić warsztaty ze Springa, uczestnicy muszą najpierw dobrze znać Javę.

W języku C/C++ ponownie widać rozkład normalny. Ankieta była przeprowadzana jak już pierwszy rok skończył pierwszy semestr, więc teoretycznie wszyscy powinni go umieć. I nie jest tak źle. Z Javą widać zróżnicowanie. Ci co byli na drugim roku to już umieli, a ci co byli na pierwszym to jeszcze nie. Springa większość nie zna (chyba że jest na wyższym roku lub ktoś uczy się sam). Node.js i Python to margines. Z C# trochę większe zainteresowanie. Zaś PHP część osób zna dosyć dobrze, a część w ogóle go nie dotykała – wiadomo próg wejścia jest niski, więc ludzie sami się uczą.

Warsztaty w przyszłości

warsztaty w przyszłości

Z niektórymi warsztatami to odległy temat. Ale teraz już wiem dokładniej, jakie jest zainteresowanie. Jak najbardziej kontynuacja Angulara (jeszcze pierwsze się nie odbyły, a już chcieli kolejne 😉 ). Springiem troszkę mniej pewnie zainteresowani, ale też nieźle. Podstawami Javy trochę podobnie (chociaż wiadomo, część już umie, więc nie potrzebuje). Dosyć duże zainteresowanie zaawansowaną Javą. Ze sztuczną inteligencją mniejsze zdecydowanie. Sporo mniejsze zainteresowanie LaTeX-em (wiadomo, nie każdemu to potrzebne). Na Git-a większość chętna. Z Lego Mindstorms zdania już bardziej podzielone. Własnych propozycji warsztatów zasadniczo nie było.

Materiały

Teraz wiedziałem czego dokładnie mogę uczyć, co muszę wytłumaczyć, a co mogę pominąć.

Materiały udostępniłem na stronie:
http://marcinkowalczyk.pl/warsztaty/uph/angular/

Nawet jak ktoś nie był na warsztatach, to może się z nimi zapoznać. Jednak zadania nie są napisane z myślą do samodzielnego wykonania, więc może być z tym problem. W zadaniach jest kilka haczyków. Był to sposób na kontrolowanie postępu programu warsztatów.

Ogólnie podczas tworzenia materiałów i prowadzenia warsztatów przyświecała mi zasada:

Istnieją dwa rodzaje wykładowców. Są tacy, kiepscy, którzy wykładając mówią: „Patrzcie, jaki ja jestem mądry!” i są inni, którzy mówią: „Patrzcie, jakie to proste!”.

Nie chciałem popełnić błędu, który był na innych warsztatach. Po prostu chciałem nauczyć ludzi tego frameworka. Starałem się pisać i mówić jak najprościej oraz dawać przykłady i omawiać więcej niż wydaje się, że powinno. Czasem lepiej powtórzyć drugi raz to samo, niż zostawić niedomówione i w efekcie niezrozumiane.

Warsztaty z AngularJS były tydzień wcześniej poprzedzone moją prezentacją Przegląd technologii do budowy aplikacji sieciowych (wersja PDF) na 0010 Seminarium Koła Naukowego Programistów (większość uczestników na warsztatach była z tego koła). Chciałem, że początkującym ta prezentacja dała pewien ogląd na języki programowania, frameworki i sposoby pisania aplikacji webowych. Żeby wiedzieli czym jest AngularJS i w którym miejscu się znajduje. Co jest dla niego konkurencją, a z czym zazwyczaj jest wykorzystywany. Oczywiście bez tego też by się dało pisać aplikacje w Angularze, ale jednak z mniejszym zrozumiem całego ekosystemu.

Treść materiałów, scenariusz i przeprowadzenie warsztatów

Materiały podzieliłem na kilka sekcji:

  • Wstęp do warsztatów − To takie podstawowe informacje o warsztatach. Były dostępne przed wydarzeniem.
  • Co to jest AngularJS? − Na początek poprosiłem o pobranie wymaganych narzędzi. W trakcie opowiedziałem kilka ogólników (m.in. powtórzenie najważniejszych fragmentów z wcześniej przedstawianej prezentacji, bo nie wszyscy na niej bylii).
  • Hello World − Wiadomo, od czegoś trzeba zacząć poznawanie nowego języka/frameworka. Przygotowałem tu uczestników, że nie zawsze będą mieli podane wszystko na tacy, a tylko napisane w jaki sposób coś znaleźć lub zrobić.
  • Podstawy − Najważniejsza część podstaw. Tu jest całe „łał” Angulara.
  • Kontrolery − Tą kwestię chciałem dokładnie wytłumaczyć, żeby każdy zrozumiał. Od razu zaznaczyłem, że to wszystko dzieje się w frontendzie, żeby nie było nieporozumień.
  • JSON − Żeby przejść dalej, to trzeba poznać ten format danych. Bez tego w JavaScripcie dużo się nie zrobi. Tutaj też zawarłem np. pętlę ng-repeat, żeby pokazać praktyczne zastosowanie.
  • Routing − Coś co nie zawsze na początku jest oczywiste. Jednak potem bez tego nie można sobie wyobrazić używania Angulara. Tutaj też uczestnicy poznali strukturę plików i katalogów projektu. Poczatkujący mogli trochę się zagubić, ale miało to właśnie pokazać namiastkę specyfiki realnych projektów.
  • Nasza aplikacja − Zwykła aplikacja ToDo z wykrozystniem tego czego się nauczylismy.
  • Wstęp do API − Korzystanie z usług REST. Czyli to do czego Angular jest docelowo wykorzystywany.
  • Na kolejnych warsztatach − Tematy do kontynuacji warsztatów.

Do warsztatów napisałem sobie scenariusz (skrypt co po kolei będę robił ja i uczestnicy). Mogłem to pominąć i ułożyć to sobie tylko w głowie, jednak spisanie pomaga to dopracować i przemyśleć. Podczas prowadzenia zawsze można też zerknąć i zobaczyć co robić dalej. Poza tym można po dłuższym czasie wrócić do scenariusza i szybko sobie przypomnieć, żeby poprowadzić kolejny raz.

scenariusz

Początkowo wszystko szło czasowo zgodnie z planem według scenariusza (ku mojemu zaskoczeniu 😉 ). Później jednak zaczęło pojawiać się więcej pytań, potrzeba było więcej pomocy uczestnikom. Uważam jednak, że to było potrzebne. Dało możliwość lepszego zrozumienia i rozszerzenia tego co akurat zaciekawiło uczestników.

Dlatego nawet nie próbowałem przyspieszać i po prostu dwa ostatnie punkty opuściłem (a i tak chwilę przedłużyliśmy). Materiały były też przygotowane trochę na wyrost, gdyby jednak uczestnicy robili zadania szybciej niż myślałem, żeby nie wyszło, że skończymy w połowie. W ogóle cały temat z API REST chciałem dać na kolejną część warsztatów, a tu tylko zasygnalizowałem, że coś takiego jest. Przecież miały to być warsztaty dla początkujących, gdzie większość uczestników pierwszy raz się spotkała z Angularem (albo frameworkiem w ogóle).

W materiałach oczywiście zdarzyły się drobne błędy (np. brak dodania jakiegoś pliku JS lub inne nazwy zmiennych – teraz to już zostało poprawione na stronie), ale już podczas warsztatów wszystko się wyjaśniło. Uczestnicy również pomagali sobie wzajemnie. Byłem zadowolony, że ci bardziej zaawansowani starali się nie przeszkadzać tym początkującym.

Refleksja po warsztatach

Dobrą praktyką jest prowadzenie ewaluacji tego, co się robi. Dlatego zrobiłem ankietę, w której uczestnicy mogli wyrazić swoją opinię. Jeszcze nie wszyscy uczestnicy ją wypełnili (i można spodziewać się, że 100% nie będzie), ale wyniki nadal spływają. Jednak można wyciągnąć jakieś wnioski już z tego co jest.

W ogóle po samych warsztatach przeczytałem miłe słowa, więc spodziewałem się, że się podobało. Daje to motywację do prowadzenia kolejnych tego typu zajęć.

Wyniki ankiety ewaluacyjnej

Na jakim poziomie trudności były dla Ciebie zadania na warsztatach?

trudnosc

(Skala: 1 – zbyt łatwe, 10 – za trudne.)

Warsztaty miały być od podstaw. Chciałem się jednak przekonać jak odczuli to uczestnicy. W większości jest tak jak chciałem. Zadania miały wydawać się bardzo proste, bo miały nauczyć, a nie pokazać „jaki to ten Angular jest trudny”. Jest to dla mnie sygnał, że materiał w większości został zrozumiany i można teraz przejść kawałek dalej.

Czy zadania były wystarczająco wytłumaczone?

wystarczająco wytłumaczone

I bardzo się z tego cieszę. Tak miało być.

Czy Twoim zdaniem długość warsztatów była odpowiednia?

dlugosc

Tego się spodziewałem, że 3 godziny to jest dużo. Ale żeby poznać chociażby podstawy frameworka, to trzeba na to poświęcić trochę czasu. Mógłbym zrobić więcej spotkań, które trwałyby krócej, ale byłoby to trudniejsze organizacyjnie (znaleźć termin, który większości pasuje, potem sala, rejestracja itd).

Wiadomo, człowiek nie może się tak długo skupić, dlatego zaplanowałem dwie przerwy (co godzinę). Na pierwszej jednak nie było widać, aby była potrzebna (materiał był lekki i dopiero co zaczęliśmy), więc kontynuowaliśmy. Druga już była konieczna (jakby nie była zaplanowana, to pewnie i tak naturalnie by się zrobiła). Jednak zmęczenie i tak trochę dało o sobie znać.

Co było dobre, co Ci się podobało?

Podobala mi sie forma i prowadzenie
Zaangażowanie prowadzącego
Indywidualne podejscie do kazdego
Odpowiednie podejście do studentów
Fachowy prowadzący, luźna forma, jasny i przystępny przekaz.
wszytko
prowadzący ( ͡° ͜ʖ ͡°)
Dobre wytłumaczenie mechanizmów frameworka
Wszystko mi się podobało. Całokształt prowadzenia warsztatów i pomoc w każdym problemie 10/10.

Zadałem to pytanie po to, żeby dowiedzieć się co było dobre, żeby powtarzać to w przyszłości i się na tym skupić.

Cieszę się z takich odpowiedzi. Mogę się spodziewać, że to trochę z uprzejmości − ale i tak specjalnie zrobiłem anonimową ankietę, żeby otrzymać bardziej wiarygodne wyniki.

Czego zabrakło, co Ci się nie podobało?

Wsio ok
Mało ciastek
nicc
Brak
Czasu zabrakło 🙂
____
niczego, było spoko
Niczego nie brakowało
Zabrakło czasu by warsztaty trwały dłużej. 🙂

Zadałem to pytanie po to, żeby wiedzieć co było źle, żebym kolejny raz mógł to wyeliminować lub chociaż zminimalizować.

Tutaj znów cieszę się, że zasadniczo nie ma zastrzeżeń. Chociaż jak zawsze pewnie coś można jeszcze poprawić. Tylko jak zachęcić uczestników do wyciągnięcia z nich tych informacji? 😉

Uwagi, sugestie do przeprowadzonych warsztatów

Moglyby byc nieco krotsze, 3 godziny to troche za duzo 😀
Większa częstotliwość warsztatów 🙂
czesciej 😉
Więcej tego typu warsztatów 🙂

WINCYJ!!! Widać jest zapotrzebowanie i jak uczestnicy chcą więcej, to rzeczywiście było dobrze. Chyba ustawiłem sobie wysoką poprzeczkę.

Czy chciałbyś wziąć udział w kolejnej części warsztatów z Angulara (kolejne zagadnienia)?

kolejne

Zadałem podobne pytanie w ankiecie przed rejestracją. Jakby wypełnili wszyscy, to mógłbym porównać jak po pierwszych warsztatach zmieniło się zainteresowanie kolejną częścią. Na razie procentowo jest podobnie (z drobną przewagą na plus).

Podsumowanie

Pomysł na warsztaty z Angulara był trafiony. Oczywiście trzeba było zacząć od podstaw. Cieszę się, że je przeprowadziłem, bo zdobyłem cenne doświadczenie. Po własnych odczuciach i opiniach mogę sądzić, że warsztaty przeprowadziłem poprawnie. Tym bardziej się cieszę, że kogoś czegoś nauczyłem (zobaczymy na kolejnych warsztatach ile z tego rzeczywiście zostało w głowach 😉 ). Są chętni na kolejną część, więc fajnie by było to kontynuować.

PS. Na stronie Instytutu Informatyki również pojawiła się relacja: Podsumowanie z warsztatów AngularJS.

Drag & drop w AngularJS

Chcemy, aby z naszej aplikacji korzystało się jak najszybciej i jak najwygodniej. Dzięki temu poprawiamy produktywność i wpływamy na pozytywne doświadczenia użytkownika podczas korzystania z aplikacji (ang. User experience, UX).

Możemy do aplikacji dodać mechanizm przeciągnij i upuść (ang. drag and drop). Zastosujemy go w aplikacji AgendaEditor, aby można było łatwo zmieniać kolejność wystąpień. Oczywiście moglibyśmy dodać przyciski, po których kliknięciu, wystąpienie przesuwałoby się w górę lub w dół. Ale będzie to wyglądało lepiej, jeżeli będziemy mogli je po prostu przeciągnąć.

Biblioteki drag & drop

Możemy w JavaScript sami zaimplementować taką funkcjonalność. Ale po co wymyślać koło na nowo. Ktoś już to dawno zrobił, dopracował i udostępnił, aby inni mogli skorzystać. Jeżeli kogoś by to jednak zainteresowało, to może poczytać o tym np. tutaj.

Znalazłem fajną bibliotekę dla AngularJS: angular-drag-and-drop-lists (demo). Ma wiele możliwości, dobre przykłady użycia i jest łatwa w użyciu. Dokładnie to czego potrzebuję. Jednak ma jedną, dużą wadę. Domyślnie nie działa na urządzeniach mobilnych (testowałem na Androidzie i rzeczywiście nie działa):

Touch devices are not supported, because they do not implement the HTML5 drag & drop standard. However, you can use a shim to make it work on touch devices as well.

Oczywiście jest więcej bibliotek np.

A tutaj można znaleźć spis jeszcze innych bibliotek dla drag&drop: Best AngularJs Drag & Drop Directives Plugins.

Jest jeszcze jedna biblioteka: Dragula, którą wykorzystam. Jej zaletą jest to, że działa na urządzeniach mobilnych (testowałem na Androidzie). Jest dosyć nowa i świeża, ale działa prawidłowo.

Dziękuję mik-laj z GitHuba za podpowiedź odnośnie biblioteki Dragula, bo tej jeszcze nie znałem, a jest dosyć dobra (swoją drogą dostałem pierwszy pull request do projektu; zajmę się nim po zakończeniu konkursu).

Dragula

Dostępna jest w wersji JavaScript: https://github.com/bevacqua/dragula
Ale dostępny jest takze wrapper pod AngularJS (wersja przystosowana, żeby można było jej łatwiej użyć w Angularze): https://github.com/bevacqua/angular-dragula/
Demo można znaleźć tutaj: http://bevacqua.github.io/angular-dragula/

Dodanie Draguli do projektu

Aby dodać pliki biblioteki do naszej aplikacji, możemy je ściągnąć z GitHuba z katalogu dist. A jeśli chcemy dodać link do zewnętrznego serwera, możemy skorzystać z serwerów CDN. Musimy dodać plik angular-dragula.js oraz dragula.css. Do wyboru mamy wersję zwykłą i zminifikowaną (z końcówką min).

W pliku index.html w sekcji <head> doklejamy linki do biblioteki:

Oczywiście musimy pamiętać o odpowiedniej kolejności dodawania plików. Najpierw dodajmy pliki CSS, następnie pliki JavaScript: jQuery, Bootstrapa, Angulara, tutaj bibliotekę do Angulara i na końcu pliki z naszymi kontrolerami.

Konfiguracja Draguli

W pliku konfiguracyjnym naszej aplikacji app.js mamy linijkę definiującą aplikację i moduły wstrzyknięte do niej:

Musimy dodać zależność: angularDragula(angular). Oczywiście poprzednie zależności (w nawiasach kwadratowych) jakie mamy zostawiamy, tylko po przecinku dodajemy kolejną. Będzie to wyglądać tak:

Teraz możemy już skorzystać z Draguli.

Modyfikacja szablonu HTML

Skorzystamy z udostępnionych dyrektyw, aby uruchomić Dragulę. Zadanie mamy ułatwione, gdyż dobrze zaprojektowaliśmy naszą aplikację. Dane wystąpień są dostępne na liście agenda.list (pobierana z naszego serwisu). Na niej będzie operować Dragula.

Mieliśmy taką tabelę w pliku home.html:

Musimy dodać dyrektywy:

  • dragula='"bag-one"', mówi nam, który element będzie miejscem do przeciągania elementów (moze być ich kilka, my jednak potrzebujemy jednego),
  • dragula-model="agenda.list", podajemy na jakiej liście ma operować (przenosić w niej elementy),
  • dragula-scope='$parent', ta dyrektywa jest potrzebna, żeby Angular odnalazł właściwy $scope (bez tego upuszczanie elementów nie działa poprawnie, nie lądują w odpowiednim pojemniku). Umieszczamy ją w elemencie, który ma być przenoszony (czyli tym samym, w którym jest ng-repeat).

Te dyrektywy musimy dodać w elemencie nadrzędnym, które chce chcemy przeciągać (chcemy przeciągać wiersze <tr>). Umieścilibyśmy dyrektywy Draguli w elemencie <table>, ale nie chcemy włączać przeciągania dla nagłówków. Dlatego dodamy kolejny element <tbody> grupujący zawartość tabeli bez nagłówków (dla nich jest odpowiedni element <thead>, który przy okazji możemy dodać).

Nasz tabela powinna teraz wyglądać tak:

Aplikacja z drag & drop

Po dodaniu biblioteki Dragula, skonfigurowaniu i modyfikacji tabeli (dodaniu dyrektyw), przeciąganie i upuszczanie dla wystąpień działa. Zauważmy, że zmiany są wykonywane na bieżąco, a wynikowy tekst agendy jest modyfikowany od razu po przeciągnięciu (również godziny są obliczane). Jak widzimy nie było to trudne, a daje dobry efekt.

Podgląd działającej aplikacji (lub otwórz w nowej karcie lub edytor Plunker):

Pamiętajmy, że możemy wkleić przykładowe dane w zakładce import, aby móc szybko przetestować działanie:

Programowanie	Jan	Kowalski	00:20
AngularJS	Anna	Nowak	00:25
JavaScript	Janusz	Programista	00:15

Trzeba tylko dopisać godzinę rozpoczęcia np. 15:00 i możemy przeciągać wystąpienia.

Kod aplikacji, jak zawsze, dostępny na Githubie: https://github.com/mkczyk/agenda-editor

Prosty import i eksport danych w AgendaEditor

W naszej tworzonej aplikacji AgendaEditor, możemy wpisywać dane poprzez pola tekstowe w formularzu. Jednak po odświeżeniu strony wszystkie dane zostają usuwane. Nie będziemy jeszcze teraz implementować zapisu danych do bazy danych. Ale chcielibyśmy, aby użytkownik miał możliwość importu i eksportu danych z/do aplikacji.

Na początek wybrałem dane w formie tekstowej, oddzielone tabulatorami. Dlaczego? Bo jeśli mamy dane w Excelu, to po ich skopiowaniu automatycznie wstawiane są tabulatory, aby oddzielić od siebie kolumny. Jeśli mamy dane w takiej formie (oddzielone tabulatorami), to po wklejeniu do Excela, zostaną poprawnie wklejone w oddzielne wiersze i kolumny. Dzięki temu będziemy mogli swobodnie przenosić dane pomiędzy aplikacją AgendaEditor a Excelem.

Struktura danych ma odpowiadać formularzowi. Jeden wiersz ma mieć postać:

tytuł	imię	nazwisko	czas_wystąpienia

Oczywiście wierszy może być więcej (kolejne wystąpienia na liście). Przykładowo:

Programowanie	Jan	Kowalski	00:20
AngularJS	Anna	Nowak	00:25

import_eksport_excel

Formularz importu/eksportu w HTML

W pliku import.html dodajemy wielowierszowe pole tekstowe textarea:

Ustawiamy dla niego model dyrektywą ng-model. Skorzystamy z getterów i setterów, tak jak w tym wpisie. Dlatego też musimy włączyć ich obsługę za pomocą dyrektywy ng-model-options. Dane wklejane do tego pola tekstowego będą automatycznie aktualizować model w aplikacji. Jak również modyfikacja modelu (np. poprzez poprzedni formularz) będzie aktualizować zawartość tego pola.

Kontroler w JavaScript

Dlatego potrzebne nam dodatkowe pole z getterami i setterami (które będą konwertować dane z modelu na tekst z tabulatorami) w naszym serwisie Agenda. W pliku import.js po prostu korzystamy z serwisu:

Serwis Agenda w JavaScript

Przejdźmy zatem do naszego serwisu w pliku agenda.js. Dodajemy w nim nowe pole z getterem i setterem:

Implementacja settera

W zmiennej newImport mamy zawartość wielowierszowego pola tekstowego z danymi do agendy oddzielonymi tabulatorami.

Najpierw musimy podzielić wszystko na osobne linie za pomocą metody split (jako separator podajemy znak nowej linii \n).

Następnie w pętli przechodzimy po wszystkich liniach. Wrzucamy na pustą listę z danymi kolejne rekordy. Żeby mieć do nich dostęp, należy linię podzielić z separatorem tabulator \t.

Implementacja gettera

Przechodzimy po liście z danymi i przepisujemy każde pola do jednego stringa oddzielając je tabulatorami \t. Zaś kolejne rekordy oddzielamy znakami nowego wiersza \n (opuszczamy ostatni znak nowej linii, żeby nie wstawiać pustej linii na końcu wszystkich rekordów).

Podgląd działającej implementacji

Gettery i settery dla dwustronnego wiązania w AngularJS

Opisywałem już na blogu czym jest dwustronne wiązanie (ang. two way binding). Dzięki niemu, dane w widoku są wyświetlane z modelu oraz na bieżąco aktualizują się w modelu na podstawie widoku.

Jest ono realizowane w AngularJS za pomocą dyrektywy ng-model:

Co jeśli chcemy jakoś przetworzyć dane z modelu zanim trafią do widoku? Oraz chcemy mieć wpływ na dane z widoku, które trafiają do modelu? W innych językach programowania (np. w Javie) używa się getterów i setterów, czyli metod, które odpowiadają za pobieranie i ustawianie danych w obiekcie. Dzięki nim mamy zapewnioną kontrolę nad danymi, które trafiają z zewnątrz do obiektu i są z niego pobierane (hermetyzacja).

Żeby móc w AngularJS napisać gettery i settery, musimy skorzystać z dyrektywy ng-model-options i ustawić opcję getterSetter na true:

Teraz w kontrolerze możemy do zmiennej myText przypisać funkcję, która będzie odpowiadała za getter i setter.

Funkcja taka powinna mieć parametr (który będzie przyjmował wartość dla settera). Jeśli nowa wartość będzie zdefiniowana:

lub jeśli liczba argumentów będzie większa niż zero:

co można też zapisać tak:

to ma wykonać się część odpowiedzialna za settter. Bo znaczy to tyle, że jest dostępny parametr z nową wartością.

Jeśli parametr nie jest dostępny (czyli nie spełnia wybranego warunku z powyższych – są one wymienne), to ma wykonać się część odpowiedzialna za getter. Bo oznacza to tyle, że funkcja została wywołana bez parametru (czyli w celu pobrania wartości).

Przykład użycia

Na potrzeby przykładu chcemy, aby podczas wpisywania liter do pola tekstowego były automatycznie zamieniane na duże litery (nawet jeśli wpisywane są małe). Użyjemy do tego gotowej funkcji z JavaScript .toupperCase.

Litery są pobierane, przetwarzane przez setter (a właściwie pierwszą część instrukcji warunkowej), zamieniane na duże litery i przypisywane do zmiennej w kontrolerze. Podczas pobierania tekstu wykonywana jest jedynie druga część warunku (getter) zwracająca zamienione litery.

Oczywiście $scope.myText (zmienna z funkcją gettera i settera) i myText (zmienna z tekstem), to co innego i dlatego możemy użyć takich samych nazw (to pierwsze jest w $scope, a drugie jedynie w kontrolerze).

Podgląd działającego przykładu:

AgendaEditor: wymiana danych pomiędzy zakładkami poprzez serwisy

W poprzednim wpisie poznaliśmy teorię na temat serwisów i proste przykłady. Teraz możemy je zastosować w praktyce w naszej aplikacji, aby zachowywać dane podczas przechodzenia pomiędzy zakładkami. W przyszłości będzie nam to potrzebne, aby dodać różne funkcjonalności na różnych zakładkach (np. import danych). W tym wpisie dodamy tylko zakładkę z wynikiem tekstowym ankiety, aby przetestować utworzony serwis.

Tworzenie serwisu

Na nasze potrzeby wybraliśmy serwis typu Service (wygodnie się go używa poprzez this, a początkowa konfiguracja dostępna w Provider nie jest nam potrzebna).

Utwórzmy nowy folder, w którym będziemy trzymali nasze serwisy: services. Tam plik o nazwie agenda.js, w którym będzie nasz serwis. Przeniesiemy tam funkcjonalność z kontrolera z pliku home/home.js.

Problem będziemy mieli ze zmienną startTime, bo jest ona typu prymitywnego (lista list i funkcja myResult będzie działać) i nie będzie działać bindowanie. Rozwiązania są dwa.

Rozwiązanie 1 – zmienna opakowana w obiekt

Nie ma referencji? To opakujmy zmienną w obiekt o nazwie model, aby mieć się do czego odwołać. Jeśli aplikacja będzie się rozrastała, będzie można tam dorzucić dodatkowe zmienne (ale obecnie jest to trochę brzydkie rozwiązanie).

W serwisie będzie to wyglądało tak:

W kontrolerze będziemy musieli przypisać obiekt do $scope:

A w widoku odwołać się do konkretnej zmiennej:

W kontrolerze oczywiście musimy przypisać wszystkie zmienne i funkcje do $scope, aby mieć do nich dostęp w widoku:

Rozwiązanie 2 – przypisanie całego serwisu do $scope

Jest jeszcze drugie rozwiązanie tego problemu. Ogólnie dobra praktyką w AngularJS przy bindowanie jest „zawsze używaj kropek” (bo oznacza to, że będzie referencja). Dlatego opakowaliśmy zmienną startTime w obiekt model, aby móc się odwołać do niego za pomocą kropki: model.startTime.

Jeśli jednak nie opakujemy zmiennej, to skąd wziąć tę kropkę? Przypiszmy cały serwis do $scope. Wtedy będziemy mieli: naszSerwis.startTime.

Czyli w serwisie mamy ładnie zmienną:

A w kontrolerze przypisujemy cały serwis do $scope:

Dzięki temu nie będziemy musieli tez pojedynczo przypisywać wszystkich zmiennych i funkcji z serwisu.

Jednak teraz w widoku musimy się odwołać do serwisu, aby uzyskać dostęp do danej zmiennej:

Na pierwszy rzut oka to wygląda gorzej, ale jeśli się zastanowić, to jest lepiej, bo dane są usystematyzowane (godzina rozpoczęcia wydarzenia powinna być w „pojemniku” związanym z agendą). Jeśli mielibyśmy kilka serwisów, byłoby to dużo bardziej czytelne niż poprzednie rozwiązanie (i mniej pracy oraz błędów z przepisywaniem wszystkich zmiennych – nie było też konfliktów nazw).

Kod serwisu (plik agenda.js) wygląda następująco:

Kontroler (plik home.js) wygląda teraz tak:

Jak widzimy pozostała tu funkcja dodawania kolejnego pustego pola na liście. Nie zaśmiecaliśmy nią serwisu, bo nie dotyczy bezpośrednio przetwarzanych danych, a tylko widoku w danej zakładce. Dlatego idealnym miejscem na nią jest ten kontroler.

Zaś w widoku musimy odwoływać się do zmiennych za pomocą agenda.nazwaDanePola:

Teraz nasze dane po wpisaniu będą zapamiętywane w serwisie i po przełączeniu się na inną zakładkę nie będą tracone.

Dodatkowa zakładka z wynikiem agendy

Możemy teraz bardzo łatwo skorzystać z już utworzonego serwisu. Dodajmy zakładkę, w której będzie umieszczony wynik agendy w formie tekstowej (czyli to co już mamy, ale na osobnej zakładce).

Tworzymy nowy folder (zgodnie ze strukturą „folder dla funkcjonalności/podstrony”result.

Umieszczamy w nim plik result.js z kontrolerem i konfiguracją routingu dla danej zakładki:

Dodajemy też plik result.html z widokiem:

Oczywiście musimy dodać w pliku index.html plik z kontrolerem i zakładkę w menu:

W ten sposób szybko utworzyliśmy nową zakładkę z funkcjonalnością korzystającą z naszego serwisu.

Podgląd działania aplikacji

Otwarcie w nowej oknie.

Wymiana danych pomiędzy kontrolerami w AngularJS czyli serwisy

W aplikacji AngularJS dane przetwarzane są w kontrolerach. Jeśli coś wpiszemy np. w formularzu w jednym widoku (na jednej podstronie), dane dostępne są w kontrolerze przypisanym do niego.

Czasem jednak zachodzi potrzeba, aby dane były dostępne na wielu zakładach (czyli w wielu kontrolerach i widokach). Jak widzimy w naszej aplikacji, jeśli na głównej zakładce w formularzu wpiszemy dane, a następnie przełączymy się na inną i powrócimy, to zobaczymy, że dane z formularza zostały utracone (były w tym jednym widoku i po przełączeniu on się przeładował).

Jak sobie z tym poradzić? Moglibyśmy za każdym razem zapisywać dane do bazy danych, a po powrocie na daną zakładkę przywracać je. Tylko rodzi to kilka problemów. Kiedy zapisywać dane (po kliknięciu na inną zakładkę? po każdorazowym naciśnięciu klawisza)? Po co obciążać serwer? Dane każdorazowo musiałyby być wczytywane, co spowalniałoby działania aplikacji. Nie jest to dobre rozwiązanie w tym przypadku. Dane powinny być przechowywane po stronie klienta.

Serwisy w AngularJS

AngularJS udostępnia nam gotowy mechanizm, aby rozwiązać ten problem: serwisy. Jest to dodatkowa warstwa logiki aplikacji. Na początku tworzony jest obiekt, w którym będą przechowywane i przetwarzane dane (dostępne w całej aplikacji), a w kontrolerach i widokach będziemy się do niego tylko odwoływać.

Są trzy rodzaje serwisów:

  • Factory – zwracamy obiekt z polami (zmienne lub funkcje), użycie return,
  • Service – przypisanie zmiennych lub funkcji do pól obiektu za pomocą słowa kluczowego this,
  • Provider – serwis, który można skonfigurować w sekcji config, zwracanie obiektu poprzez funkcję $get.

W tutorialu, do którego wcześniej linkowałem, są opisane wszystkie trzy serwisy: Factory vs Service vs Provider. Również w książce AngularJS. Pierwsze kroki, w rozdziale Dependency Injection — wstrzykiwanie zależności: DI w praktyce (str. 37) są opisane wszystkie rodzaje serwisów.

Który wybrać? Factory jest najprostsze. Jednak konieczność używania return jest trochę niewygodne (chociaż kto co lubi). Według mnie lepiej użyć Service, gdyż dostęp do pól obiektu poprzez słówko this jest wygodniejszy (tylko przypisujemy tam wartości i jest już dostępne, nie musimy nic zwracać). Jeśli mamy potrzebę konfiguracji serwisu przed załadowaniem aplikacji, wybierzmy Provider (w prostych aplikacjach zazwyczaj nie ma takiej potrzeby). Jednak jego użycie jest trochę bardziej skomplikowane.

Dlatego na nasze potrzeby wybierzmy serwis typu Service.

Serwis typu Service

Ogólna składnia wygląda tak:

Polami mogą być zmienne (również, a nawet przede wszystkim obiekty) oraz funkcje. Należy pamiętać, że jeśli polem będzie zmienna typu prymitywnego (np. napis, liczba), to będziemy mogli z niej korzystać, jednak bindowanie w AngularJS nie będzie działało prawidłowo. Dlatego polami serwisu muszą być obiekty (A dopiero w nim prymitywne zmienne), żeby można było zbindować referencję.

W naszym przykładowym serwisie będziemy mieli obiekt model z jednym polem myValue (pól może być więcej) oraz funkcję myText.

Utworzymy dwa kontrolery, żeby sprawdzić czy wymiana działa oraz dwa pola input, aby sprawdzić czy prawidłowo działa bindowanie:

Jak widzimy, aby skorzystać z naszego serwisu, wystarczy go wstrzyknąć (umieścić nazwę serwisu w funkcji kontrolera). Jest to tzw. DI (Dependency Injection czyli wstrzykiwanie zależności). Chcemy z danych z serwisu skorzystać w widoku, więc musimy umieścić je w $scope poprzez kontroler.

Podczas wpisywania danych w pola tekstowe, informacje powinny być przenoszone pomiędzy kontrolerami (czyli przepisywane do drugiego pola) oraz funkcja powinna być obliczana na bieżąco (obok dopisywanie słowa Hello).

Oczywiście jest to tylko przykład. Oba kontrolery zostały umieszczone na jednej podstronie (więc aby uzyskać ten sam efekt, można by trzymać wszystko w jednym kontrolerze). Jednak ta wiedza przyda nam się na przyszłość. Nic nie stoi na przeszkodzie, aby teraz kontrolery rozdzielić na dwie podstrony i wspóldzielić pomiędzy nimi dane poprzez serwis.

Serwis typu Factory

Pokażę jeszcze rozwiązanie tego samego zadania z wykorzystaniem serwisu typu Factory. Według mnie jest mniej wygodne, ale dosyć często używane, więc warto z nim się zaznajomić.

Kontrolery i widoki zostają identyczne. Zmienia się tylko definicja serwisu.

Ogólna składnia wygląda tak (tworzymy pole i potem je zwracamy):

Lub szybciej tak (od razu zwracamy pole):

W naszym serwisie będzie to wyglądało w ten sposób:

I działający przykład:

Serwis typu Provider

Została nam jeszcze najtrudniejsza wersja serwisu czyli Provider. Ogólna jego składnia wygląda tak:

Widzimy, że podobnie zwraca się pola jak w Factory. Jednak tu musimy dodatkowo skorzystać z funkcji $get. Nie jest to zbyt wygodne, ale jeśli chcemy mieć serwis, który będziemy mogli skonfigurować przed uruchomieniem aplikacji, będziemy musieli skorzystać z tej wersji (Provider).

Czyli w naszym przykładzie będzie to wyglądać tak (sama definicja serwisu Provider, bez jego konfiguracji):

I przykład działania:

Dodawanie godzin w JavaScript

W naszej aplikacji możemy wpisywać tematy oraz imię i nazwisko prelegenta. Jednak tak naprawdę nic więcej się nie dzieje poza przepisaniem tych danych i dodaniem odpowiednich cudzysłowów i myślników. Dodajmy obliczanie godzin występów!

Chcemy do godziny rozpoczęcia wystąpienia np. 16:50 dodać jego czas trwania np. 15 minut, zapisane w formacie 00:15. Powinniśmy otrzymać godzinę zakończenia danego wystąpienia tj. 17:15. Dzięki takiemu formatowi, będziemy mogli wpisywać wystąpienia trwające dłużej niż godzinę np. półtorej godziny będzie zapisane 01:30.

W JavaScript niestety nie ma gotowej funkcji pozwalającej na sprasowanie godziny w takim formacie, ani ich dodawanie. Niemożliwe jest też dodanie własnego formatu (jak to można zrobić np. w Javie za pomocą DateTimeFormatter).

Własna funkcja dodająca godziny

Napiszmy więc własną funkcję. Chcemy przyjąć dwa parametry addTime(start, time):

  • start np. "16:50",
  • czas do dodania np. "00:15".

Wynikiem wywołania funkcji addTime("16:50", "00:15") powinien być tekst: "17:05".

Jak zaimplementować tę funkcję? Stwórzmy nowy obiekt new Date() i przypiszmy go do jakiejś zmiennej np. o nazwie now. Ustawmy godziny i minuty z pierwszego parametru za pomocą setHourssetMinutes. Następnie pobierzmy liczbę godzin i minut z drugiego parametru i dodajmy je do naszego obiektu (osobno godziny, osobno minuty).

Przykładowo jeśli liczbą minut z pierwszego parametru będzie 50, a będziemy chcieli dodać 25, to sumą będzie 75. Co się stanie jak ustawimy to jako minuty?

Tu JavaScript zachowa się ładnie i dostaniemy dokładnie to co chcieliśmy (licznik w godzinie się „przekręci”, wskoczy następna godzina i dostaniemy prawidłową liczbę minut; jest to niejakie dzielenie modulo 60).

Jak pobrać godziny i minuty z formatu HH:mm?

Jak już wspomniałem, nie ma w JavaScript możliwości dodania własnych formaterów. Po prostu pobierzmy odpowiednie liczby z ciągu tekstowego np. za pomocą metody split.

Metoda split(separator) działa w ten sposób, że zwraca tablicę z fragmentami tekstu podzielonymi za pomocą separatora. U nas separatorem będzie dwukropek „:”.

O to nam chodziło.

Kod funkcji będzie wyglądał tak:

Niby działa:

Ale w przypadku innych danych brakuje zer wiodących:

Zera wiodące

Zauważmy, że jeśli pobierzemy godzinę, minuty lub sekundy, które są poniżej 10, to otrzymamy liczbę bez zer wiodących:

Wynik:

Nie znalazłem eleganckiego rozwiązania. Trzeba po prostu zrobić if-a, który będzie to sprawdzał i doklejał „0” w odpowiednim miejscu:

Krócej można to zapisać:

Wynikiem będzie tekst:

Nasza poprawna funkcja będzie teraz wyglądać tak:

Jak widzimy, teraz wszystko działa poprawnie:

Wykorzystanie funkcji w AgendaEditor

Mamy gotową funkcję obliczającą godziny. Dodajmy ją do projektu.

Zmiany w HTML

Naszym widokiem z agendą obecnie jest plik home.html. Przede wszystkim musimy dodać tam pola gdzie będziemy mogli wpisać dane. Dodanie kolumny z miejscem na czas wystąpienia („time”):

Jak widzimy, system gridowy możemy stosować również do kolumn tabel, tak jak do całej strony.

Jako nowy wiersz wstawiamy dodatkowe pole analogiczne do innych:

Zostało nam do dodania pole, w które będziemy wpisywać godzinę startu całego wydarzenia. Dodajmy je nad tabelą:

Skorzystaliśmy z klasy form-group, w elemencie nią oznaczoną możemy umieścić napis label. Ustawiamy mu szerokość taką samą jak dla kolumny wyżej „Time” tzn. col-sm-2. Dodajmy również offset, który umieści pole nad kolumną tabeli „Time”. Po lewej stronie są kolumny „Title” (5), „Name” (2), „Surname” (2), co razem daje 5+2+2=9. Dlatego offset jest równy: col-sm-offset-9. Do tego nasze pole (2) i jeszcze puste miejsce, pod którym jest przycisk do usuwania (1), razem daje 12 bootstrapowych kolumn.

Zmiany w JavaScript

Przejdźmy teraz do naszego Angularowego kontrolera home.js.

Dodajmy naszą funkcję. W kodzie poniżej widzimy, że musimy ją wstawić dokładnie w kontrolerze. Nie będziemy jej przypisywać do $scope, bo nie ma takiej potrzeby (będzie wykorzystywana tylko lokalnie w kontrolerze):

W naszej liście $scope.list na początku umieszczamy jeden element za pomocą push. Pamiętajmy aby dodać tam nowe pole time: "", tak jak w kodzie wyżej.

Zajmijmy się teraz funkcją $scope.myResult, w której powinny wystąpić wywołania funkcji addTime, aby obliczyć godziny wystąpień.

Poprzednia wersja wyglądała tak:

Dodajmy sobie zmienną lastTime przechowującą godzinę zakończenia poprzedniego wystąpienia. Będzie to automatycznie początek kolejnego wystąpienia. Na początku oczywiście musimy ustawić ją jako czas startowy całego wydarzenia:

W pętli będziemy obliczać koniec wystąpienia za pomocą naszej funkcji addTime:

Oczywiście obliczone godziny musimy dopisywać do wykonu końcowego.

Oprócz tego dodajmy kilka warunków:

  • Nie wykonuj pętli (czyli nie rób niczego z naszą listą), jeśli nie została wpisana godzina wystąpienia:
  • Nie przetwarzaj danego wiersza jeśli nie został wpisany tytuł lub jeśli nie został wpisany czas wystąpienia (czasem zdarza się pusty string a czasem undefined).

Cały kod funkcji myResult będzie teraz wyglądał tak:

Podgląd działającej aplikacji

W zakładce „Code” oczywiście można podejrzeć kod całej aplikacji. Klikając tutaj, otworzymy ją w nowej karcie.