Sławek Rudawski2019-03-14T14:17:39+00:00https://slawciu.github.ioSławek Rudawskislawomir.rudawski@gmail.comTo uczucie, kiedy możesz sprawdzić, czym oddychasz...2018-11-19T08:01:00+00:00https://slawciu.github.io/dajsiepoznac/2018/11/19/smogomierz-2<p>Już podczas eventu w Katowicach, okazało się, że czujniki mierzące skład powietrza w tym samym pomieszczeniu podają różne odczyty. Dlatego zanim zapakujemy nasze czujniki do sugerowanego opakowania w postaci kolan kanalizacyjnych, pora na kilka testów.</p>
<h2 id="praca-w-jednym-miejscu">Praca w jednym miejscu</h2>
<p>Pierwszy test - czujniki umieszczone są jeden obok drugiego, czas trwania testu 20 min, wprawne oko dowie się, gdzie ostatecznie znajdą się czujniki. Odczyty na wykresie.</p>
<p><img class="postImage" style="width: 100%" src="/public/024/01.png" /></p>
<p>Wniosek 1: Powietrze w domu powyżej normy?!</p>
<p>Wniosek 2: Wskazania różnią się o 4 mikro gramy na metr sześcienny.</p>
<h2 id="oczyszczacz-powietrza">Oczyszczacz powietrza</h2>
<p>Czy na pewno działa? Czy też daje tylko poczucie świeżego powietrza na sam dźwięk pracującego w nim wentylatora? Jeden z czujników zmienia lokalizację, teraz będzie w pokoju z oczyszczaczem tuż obok niego.</p>
<p><img class="postImage" style="width: 100%" src="/public/024/02.png" /></p>
<p>Wniosek 1: Różnica widoczna już na pierwszych kilku odczytach.</p>
<p>Wniosek 2: Wygląda na to, że nasz oczyszczacz powietrza działa - przynajmniej w drugim pokoju powietrze mieści się już w granicach normy.</p>
<h2 id="oczyszczacz-powietrza-podejście-2">Oczyszczacz powietrza podejście 2</h2>
<p>O 7:30 przenosimy oczyszczacz do pokoju z drugim czujnikiem (Imielin).</p>
<p><img class="postImage" style="width: 100%" src="/public/024/03.png" /></p>
<p>Wniosek 1: widać tu, że sobie całkiem nieźle radzi. W ciągu kilku minut powietrze ma stężenie pyłów PM2.5 i PM10 mieszczące się w granicy normy europejskiej.</p>
<p>Wniosek 2: spadek stężenia pyłu z 28 na 10 ug/m^3 w niecałą godzinę</p>
<h2 id="otwórzmy-okno">Otwórzmy okno</h2>
<p>Od 11:58 do pokoju bez oczyszczacza wpada powietrze z zewnątrz.</p>
<p><img class="postImage" style="width: 100%" src="/public/024/04.png" /></p>
<p>Wniosek: Jest ciepło, jak na listopad i nawet ocena wzrokowa nie wróży żadnych rewelacji - wykres lekko w górę.</p>
<h2 id="antyperspirant-w-sprayu">Antyperspirant w sprayu</h2>
<p>Przy okazji - co się stanie, gdy rozpylimy antyperspirant w okolicy czujnika pyłów? To ta szpilka kilka minut po 9…</p>
<p><img class="postImage" style="width: 100%" src="/public/024/06.png" /></p>
<h2 id="czujnik-bliżej-otwartego-okna">Czujnik bliżej otwartego okna</h2>
<p><img class="postImage" style="width: 100%" src="/public/024/05.png" /></p>
<p>Odczyty znacząco w górę, mimo nienajgorszej widoczności, ilość pyłów jest ponad kreską wyznaczającą normę.</p>
<p>Wniosek: Czas mija, ludzie wracają do domów i zaczynają dogrzewać okoliczne gospodarstwa… Pora zamknąć okno. Szansę na wietrzenie lepszym powietrzem można wykorzystać pracując z domu lub stosując jakąś automatykę, która nam uchyli okna. Można sprzęgnąć czujnik z domową automatyką - wietrzyć, gdy na zewnątrz jest lepsze powietrze (akurat jak jesteśmy w pracy)… I pojawia się luka szansa dla złodzieja! “Ogłupić” czujnik świeżym powietrzem i poczekać, aż okna same się uchylą…</p>
<h2 id="a-co-się-dzieje-w-nocy">A co się dzieje w nocy?</h2>
<p>Okna rozszczelnione.</p>
<p><img class="postImage" style="width: 100%" src="/public/024/07.png" /></p>
<p>Wniosek 1: Na noc zamykamy okna i włączamy oczyszczacz. Koniecznie.</p>
<p>Wniosek 2: 9 listopada przenieśliśmy oba czujniki do tego samego pokoju - z oczyszczaczem. Wygładzenie wykresu za pomocą średniej kroczącej (10 ostatnich pomiarów). Widać wyraźnie, że odczyty PM2.5 są prawie identyczne, nadal występuje różnica przy PM10</p>
<h2 id="podsumowanie">Podsumowanie</h2>
<p>Zakup smogomierza w częściach przyniósł nie tylko frajdę w postaci zabawy z elektroniką (pamiętacie jeszcze <a href="http://rzeczybezinternetu.blogspot.com">rzeczybezinternetu</a>?), ale też dał nam możliwość sprawdzenia wydajności naszego oczyszczacza powietrza. Niebawem elektronika wyląduje w sugerowanym opakowaniu i zostanie zamontowana na zewnątrz. Aż strach pomyśleć, co się pojawi na wykresach, gdy nadejdzie sroga zima…</p>
To uczucie, kiedy możesz zobaczyć powietrze, którym oddychasz...2018-11-16T22:00:00+00:00https://slawciu.github.io/dajsiepoznac/2018/11/16/smogomierz<p>Co można dostać na urodziny? A co można dostać jeśli to są duże urodziny i otwiera się wiele możliwości? Jak jest się nudnym człowiekiem chcącym dbać o swoje zdrowie można dostać oczyszczacz powietrza! Zwłaszcza, że są momenty w roku, gdzie widok za oknem może zmusić do refleksji…</p>
<p><img class="postImage" style="width: 100%" src="/public/023/04.png" /></p>
<p>Tak oto w naszym mieszkaniu pojawił się oczyszczacz powietrza Sharp, którego testy pojawiły się na <a href="https://www.spidersweb.pl/2017/03/sharp-kc-a50euw-opinie-recenzja.html">Spider’s Web</a> - artykuł mocno przyczynił się do wyboru akurat tego modelu. Z tym oczyszczaczem żyjemy już prawie rok, przez cały ten czas łudząc się, że nasze powietrze jest lepsze. W tym miejcu historii pojawiają się internety, konkretnie facebook. Na rzeczonym facebooku pojawiają się różne rzeczy, zwłaszcza gdy się pomoże trochę szczęściu i algorytmom, klikajac Lubię to dla <a href="https://www.facebook.com/tedxkatowice/">TEDxKatowice</a> i <a href="https://www.facebook.com/HackerspaceSilesia/">HackerSpace Silesia</a>. Tak oto wydarzenie “zbuduj sobie smogomierz” objawiło przede mną tajemne sekrety: gdzie i kiedy.</p>
<h2 id="smogomierze">Smogomierze</h2>
<p>W okolicy można znaleźć wiele czujników zanieczyszczeń, rozmieszczonych w różnych miejscach w mieście. Jakość powietrza zależy od wielu czynników - otoczenia domów jednorodzinnych, ruchliwych dróg w okolicy, ukształtowania terenu albo urbanisty, który nie pozwoli na wybudowanie kilkunastopiętrowego budynku w tzw. korytarzu powietrznym miasta. Żaden z okolicznych czujników nie wzbudzał w nas zaufania na tyle, by choćby przez chwilę nie myśleć o złożeniu własnego (mieszkamy trochę dalej i wyżej, niż domy jednorodzinne, przy których zamontowany jest najbliższy czujnik). Dlatego nim się obejrzeliśmy, siedzieliśmy w siedzibie HackerSpace Silesia w Katowicach, z elektroniką gotową do rozpakowania.</p>
<p>Event był mocno związany z niemiecką inicjatywą o polskich korzeniach - <a href="https://luftdaten.info/">luftdaten.info</a>. Jak się okazało, jest to <a href="https://github.com/opendata-stuttgart">open source’owy</a> projekt zapoczątkowany przez Lucasa, a właściwie Łukasza, który swego czasu wyemigrował za zachodnią granicę i na jednym z eventów typu Code for Germany stworzył zalążki systemu, którego czujniki pokrywają prawie całe Niemcy i coraz częściej pojawiają się w innych krajach - patrz <a href="http://deutschland.maps.luftdaten.info/#6/51.165/10.455">mapa</a>.</p>
<p>W skład smogomierza wchodzą:</p>
<ul>
<li>mikrokontoler NodeMCU ESP8266 v3</li>
<li>czujnik pyłu SDS011</li>
<li>czujnik temperatury i wilgotności DHT22</li>
<li>zasilacz 5V/2.1A (mam nadzieję, że nie jest na czarnej liście na elektrodzie…)</li>
<li>przewód microUSB</li>
<li>kabelki!</li>
</ul>
<h2 id="sds011-i-dht22">SDS011 i DHT22</h2>
<p>SDS011 (<a href="https://nettigo.pl/attachments/398">datasheet</a>) to czujnik wykorzystujący lasery do pomiaru stężenia cząstek w badanym powietrzu. Badanie polega na zaciągnięciu powietrza do wnętrza czujnika (pomaga tu mały wentylator) i pomiar za pomocą lasera. Warto w tym momencie wspomnieć o niedoskonałości tego rozwiązania - kiedy wzrasta wilgotność, cząsteczki wody mogą być rozpoznane jako cząsteczki pyłu, co może negatywnie wpływać na odczyt. Dlatego wspomagamy się jeszcze DHT22 (<a href="https://www.sparkfun.com/datasheets/Sensors/Temperature/DHT22.pdf">datasheet</a>) - czujnikiem, który mierząc temperaturę i wilgotność, pozwoli nam wprowadzać korekty do odczytów czujnika pyłu.</p>
<p><img class="postImage" style="width: 75%" src="/public/023/03.png" /></p>
<p>Producent czujnika pyłu gwarantuje prawidłowe odczyty przez około rok ciągłej pracy. By móc korzystać z czujnika dłużej, niż rok, potraktujemy go trochę tak, <a href="http://rzeczybezinternetu.blogspot.com/2016/03/wyjscie-blink-world.html">jak powinno się traktować LEDy</a> - będziemy go załączać co jakiś czas. Dzięki temu rozciągniemy w czasie nasz rok ciągłej pracy. Nie potrzebujemy pomiarów w czasie rzeczywistym, w zupełności zadowolimy się odczytami co kilkudziesiąt sekund.</p>
<p>Samo składanie polegało na podłączeniu odpowiednich pinów czujników do pinów wyprowadzonych na płytce z czujnikiem. Dostarczony był też skompilowany kodzik, który wystarczyło wrzucić na procka, jak tylko system zaczął go wykrywać pod którymś portem COM. Na sam koniec pozostała konfiguracja. I najciekawsze - gdzie można te dane zobaczyć/wysłać?!</p>
<p>Aplikacja od luftdaten stawia na ESP serwer www, za pomocą którego mamy dostęp do ostatniego odczytu i szeregu ustawień konfiguracyjnych.
<img class="postImage" src="/public/023/02.png" /></p>
<p>Zaznaczając w konfiguracji checkbox “Wysyłaj tam Feinstaub-App” jesteśmy w stanie podglądać odczyty czujnika także za pomocą aplikacji mobilnej <a href="https://play.google.com/store/apps/details?id=com.mrgames13.jimdo.feinstaubapp">Particulate Matter App</a>. Uwagę zwracają miejsce na link do zewnętrznego API i pola konfiguracyjne dla serwera bazy InfluxDB.
Wrodzona ciekawość, co się wysyła sprawiła, że po paru minutach stał json-server. Hint - w adresie serwera nie podawać http. Z czujnika przyszedł piękny json:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>{
"esp8266id": "760xxxx",
"software_version": "NRZ-2018-111",
"sensordatavalues": [
{
"value_type": "SDS_P1",
"value": "51.80"
},
{
"value_type": "SDS_P2",
"value": "28.10"
},
{
"value_type": "temperature",
"value": "21.80"
},
{
"value_type": "humidity",
"value": "56.20"
},
{
"value_type": "samples",
"value": "602632"
},
{
"value_type": "min_micro",
"value": "229"
},
{
"value_type": "max_micro",
"value": "2457095"
},
{
"value_type": "signal",
"value": "-72"
}
],
"id": 2
}
</code></pre></div></div>
<p>No to teraz wykres! I proces myślowy: trzeba postawić api, gdzieś serwer, potem UI, pewnie React, pewnie d3js… Czy nie da się prościej?</p>
<h2 id="grafana-i-influxdb">Grafana i InfluxDB</h2>
<p>Podczas samego eventu, <a href="https://github.com/bfaliszek">Błażej</a> pokazał swój dashboard skonfigurowany w Grafanie, na którym prezentuje odczyty z własnych czujników. Odrobina googlowania z słowami kluczowymi “Grafana InfluxDB” doprowadziła do tego, że nim się obejrzałem miałem już prywatne konto na Grafanie i szukałem miejsca na hosting bazy. Tu z pomocą przyszła maszyna wirtualna hostowana na Azure, z Ubuntu na pokładzie. 2 komendy - jedna instalacyjna, druga uruchamiająca serwer w tle, umożliwiły utworzenie nowej bazy danych i użytkowników - dla sensorów i grafany. InfluxDB jest jednym z dostępnych źródeł danych w samej Grafanie. Po dodaniu namiarów na serwer, użytkownika, można testować połączenie i przekonać się, że… trzeba jeszcze otworzyć port na Azure i wtedy - wszystko bangla.</p>
<h2 id="dashboard">Dashboard</h2>
<p>Jeszcze tylko wytłumaczyć Grafanie, co chciałbym zobaczyć - wykres stężenia pyłu PM2.5 i pyłu PM10. Z czujnika jeszcze otrzymujemy informację o wilgotności i temperaturze - te dane też wylądują na ekranie. Fajnym pomysłem było też naniesienie europejskich norm jakości powietrza - stąd threshold w postaci czerwonej linii.</p>
<p><img class="postImage" style="width: 100%" src="/public/023/01.png" /></p>
Konfiguracja per środowisko w ReactNative2017-05-18T21:00:00+00:00https://slawciu.github.io/dajsiepoznac/2017/05/18/konfiguracja-per-srodowisko-react-native<p>Informacje, którymi nie warto się dzielić znaleźć się mogą także w plikach projektu mobilnego. Oprócz tego możemy trafić na wszelkie zmienne zależne od środowiska, w którym chcemy uruchomić aplikację (adres serwera), klucz do api, z którego korzystamy bezpośrednio na telefonie i czego sobie tylko dusza developera zamarzy.</p>
<p>I w przypadku tworzenia aplikacji w ReactNative nie pozostajemy bez wsparcia w tej trudnej sytuacji. Wpisując słowa kluczowe <code class="highlighter-rouge">reactnative config</code>, możemy odnaleźć paczkę:</p>
<p><a href="https://github.com/luggit/react-native-config">react-native-config</a>,</p>
<p>która rozwiąże wszystkie nasze problemy :)</p>
<p>W celu skorzystania z biblioteki musimy ją oczywiście zainstalować, następnie w głównym katalogu aplikacji mobilnej utworzyć plik .env (tworząc plik o nazwie <code class="highlighter-rouge">.env.</code> w eksploratorze windows lub korzystając z konsoli - wtedy bez sztuczek), w którym zawrzemy wszelkie interesujące nas dane, zależne od środowiska. Podobnie jak w ostatnim przypadku, warto dorzucić ten plik do .gitignore’a i zostawić sample’a na repo.</p>
<p>Korzystając z <code class="highlighter-rouge">react-native-config</code> możemy działać na wielu różnych plikach konfiguracyjnych. Obok .env możemy utworzyć .env.prod, .env.test, a przed zbudowaniem projektu wskazać ten, z którego dane powinny być dostępne w aplikacji. Jedyna niedogodność tej biblioteki jest taka, że nazwę pliku konfiguracyjnego wpisujemy do zmiennej środowiskowej ENVFILE, którą wcześniej musimy utworzyć w systemie. Chcąc zbudować aplikację wykorzystując plik .env, w konsoli wpisujemy zatem:</p>
<p><code class="highlighter-rouge">set ENVFILE=.env & react-native run-android</code></p>
<p>Konsola powie nam, który plik wykorzystujemy, a następnie zbuduje aplikację. Proste! Teraz możemy napisać skrypty, które przygotują nam aplikację dla różnych środowisk. Co ciekawe, react-native-config udostępnia dane z pliku konfiguracyjnego także dla kodu napisanego w javie - możemy więc z łatwością ładować zmienne konfiguracyjne zarówno w plikach z rozszerzeniem .jsx jak i .java. Jak korzystam z danych zapisanych plikach konfiguracyjnych? Sprawdź w <a href="https://github.com/slawciu/home-library/blob/master/HomeLibraryMobile/lib/signalrClient.js">repo</a>.</p>
Informacje, którymi nie warto się dzielić2017-05-17T19:36:00+00:00https://slawciu.github.io/dajsiepoznac/2017/05/17/informacje-ktorymi-nie-warto-sie-dzielic<p>Tworząc oprogramowanie prędzej czy później dotrzemy do momentu, że gdzieś w repozytorium pojawią się nam dane, którymi nie chcielibyśmy się dzielić z całym światem: connection string do bazy danych, nasz klucz prywatny do zewnętrznego api. W idealnym świecie takie informacje nie powinny leżeć nigdzie na repo z kodzikiem. Połączenie z bazą danych powinno być załatwione przez serwer CI (konfigurację możemy trzymać na INNYM - niepublicznym - repozytorium), na pewno znajdzie się też sposób na wstrzyknięcie innych ustawień. Jednak co zrobić w przypadku, gdy nasze repozytorium leży na githubie, stawianie CI mija się z celem, bo projekt jest na tyle mały, że nakład pracy włożony w postawienie kolejnej instancji TeamCity zwróci się po długim czasie, a kodzik musi leżeć w publicznym miejscu?</p>
<p>Wtedy warto ukryć wrażliwe dane przed światem - najlepiej na maszynie developerskiej i nie chwalić się nimi na lewo i prawo. Dotychczas w Domowej Bibliotece connection string i klucz prywatny do Books api leżały sobie w repozytorium, co było bardzo nieodpowiedzialne z mojej strony. Klucz dezaktywowałem, teraz czas zabezpieczyć się przed podobnymi wpadkami w przyszłości.</p>
<h2 id="connectionstringsconfig">connectionStrings.config</h2>
<p>W świecie .NETa możemy śmiało wyodrębniać poszczególne składowe app i web configów do osobnych plików. Jedyne, co musimy zrobić, to wskazać, gdzie znajduje się właściwa konfiguracja, kodzikiem mówiąc:</p>
<script src="https://gist.github.com/slawciu/61e1a1dd40455d155621dab7c3f594a6.js"></script>
<p>zamieniamy na</p>
<script src="https://gist.github.com/slawciu/039efa92d385a409960acbe5c9db97c1.js"></script>
<p>a we wskazanym pliku umieszczamy nasze connection stringi. Proste! Tak samo można postąpić z pozostałymi częściami web/app configa (np. wydzielając appSettings). Skoro już mowa o connectionStringach. Może się zdarzyć, że będziemy chcieli posiadać informację o sposobie łączenia do bazy danych w wielu miejscach. Problem? Skądże znowu! W każdym projekcie wymagającym połączenia do bazy wstawiamy connectionStringa, a jak się zmieni… Problem, bo trzeba zmieniać w wielu miejscach. Rozwiązanie? Umieść plik connectionStrings.config w katalogu Configuration, a w miejscach, gdzie plik musi się znajdować wewnątrz projektu (np. w przypdaku web site’ów) dodaj go do tego projektu JAKO LINK - (PPM -> Add Existing Item):</p>
<p><img class="postImage" src="/public/021.png" /></p>
<h2 id="apikeysconfig">apiKeys.config</h2>
<p>Sprawa się nieco komplikuje w momencie, gdy chcemy zrobić coś niestandardowego - np. swój własny typ konfiguracyjny. Klucze do api mógłbym trzymać w sekcji appSettings, ale wtedy musiałbym ukryć cały ten plik przed potencjalnymi kontrybutorami, a tego nie chcę robić. Dlatego też klucze do api będą posiadać swoją własną sekcję w konfiguracji, którą to sekcję będzie można wyodrębnić do osobnego pliku. Chcąc stworzyć nową sekcję, musimy stworzyć klasę dziedziczącą po ConfigurationSection, a w niej umieszczamy logikę odpowiedzialną za pobieranie danych z naszej sekcji.</p>
<script src="https://gist.github.com/slawciu/fa522a5581202f6a2c81ac723c81c8ef.js"></script>
<p>Następnie rejestrujemy sekcję w pliku konfiguracyjnym i posiadając wszystkie wymagane glejty możemy śmiało wpisywać nasze tajne informacje do kolejnego xml’a - apiKeys.config i obowiązkowo dopisać go do .gitignore.</p>
<p>Btw, zastanawialiście się kiedyś, jak stworzyć plik .gitignore w eksploratorze windows? “Nie, bo zawsze kopiowałem z innego projektu… lol” - eksplorator nie pozwoli nam utworzyć pliku o nazwie “.gitignore”, bo brakuje mu rozszerzenia, z chęcią natomiast utworzy plik o nazwie “.gitignore.” - logiczne ;)!</p>
<p>By nie zostawić potencjalnych towarzyszy od kodu w niekomfortowej sytuacji, w której musieliby zgadywać, co powinno się znaleźć w nieobecnych plikach konfiguracyjnych, możemy dodać przykładowe pliki z konfiguracją (apiKeys.sample.config) i wrzucić je na repo.</p>
<script src="https://gist.github.com/slawciu/dd8f96e0194a9fd3ac01455b1191bd70.js"></script>
<p>Moje klucze są bezpieczne na mojej maszynie, a w repo leżą przykładowe pliki. I co najważniejsze - pobierając źródła na inną maszynę VS nie krzyczy o brakujące pliki.</p>
ReactNative Remote Debugging2017-05-05T08:52:00+00:00https://slawciu.github.io/dajsiepoznac/2017/05/05/react-native-remote-debugging<p>Rozwijanie aplikacji mobilnej wymaga połączenia między maszyną developerską a urządzeniem mobilnym. O ile w przypadku korzystania z emulatora to nie jest żaden problem - po prostu uruchamiamy kolejne okienko, to w przypadku fizycznych urządzeń sprawa zaczyna się delikatnie komplikować. Przywykłem do tego, że aby wgrać nową wersję aplikacji, musiałem podpinać telefon do komputera za pomocą kabelka USB.</p>
<p>ReactNative daje nam “opakowanie” wspomagające proces developmentu. Jego częścią jest menu, do którego możemy wejść przytrzymując przycisk menu na naszym telefonie lub potrząsając nim. Kiedy telefon jest podpięty kabelkiem, potrząsanie nie jest zbyt wygodne, a kabelek uderza o blat biurka - same problemy. Na szczęście istnieje rozwiązanie tego problemu. ReactNative chwali się tym, że w przypadku błędu, nie wyrzuca w kosmos całej aplikacji, tylko “dyskretnie” pokazuje, co poszło nie tak, prezentując biały tekst na czerwonym ekranie. Na jednym z takich ekranów możemy wyczytać, że w celu połączenia z serwerem developerskim należy fizycznie podpiąć telefon lub jeżeli z poziomu telefonu i komputera mamy dostęp do tej samej sieci - możemy podać adres IP serwera i port, pod którym serwer jest dostępny. Awesome!</p>
<p><img class="postImage" src="/public/020.gif" /></p>
Szukajka2017-05-05T08:38:00+00:00https://slawciu.github.io/dajsiepoznac/2017/05/05/szukajka<p>Połączenie między telefonem a backendem działa znakomicie - możliwe jest dodawanie książek i ich wyświetlanie. Potencjalnym problemem, który może się pojawić w przyszłości jest duża ilość książek i konieczność przewijania listy w poszukiwaniu tej jednej. Jak temu zaradzić? Dodać szukajkę!</p>
<p>A właściwie pole, którego zawartość odfiltruje nieco ekran. W tym celu posłużymy się polem tekstowym komponentu <code class="highlighter-rouge">Toolbar</code>, którego wartość będziemy trzymać w stanie komponentu odpowiedzialnego za wyświetlanie listy książek.</p>
<script src="https://gist.github.com/slawciu/bf31e6bb3435d5d0c22a4cac678053a5.js"></script>
<p>Wpisany tekst wykorzystamy w metodzie filter, która wywołana na kolekcji książek zwróci nam tylko te, które łapią się w kryteria wyszukiwania.</p>
<script src="https://gist.github.com/slawciu/cdeac960414d4523dbece2285e813a9a.js"></script>
<p>W praktyce:</p>
<p><img class="postImage" src="/public/019.gif" /></p>
<p>Banał! Ale dlaczego poszło tak łatwo?
Za każdym razem, gdy zmieniamy tekst filtrowania, zmienia się stan komponentu, więc wywoływana jest metoda render, we wnętrzu której lista książek jest filtrowana. Event ‘przerysowania’ widoku mamy zapewniony ze strony Reacta.</p>
Czas decyzji2017-04-27T19:24:00+00:00https://slawciu.github.io/dajsiepoznac/2017/04/27/czas-decyzji<p>Projekt wkroczył w etap, w którym trzeba podjąć decyzję o tym, jak informacje będą przekazywane wewnątrz systemu. U bram huba stoi aplikacja mobilna i łaskawie czeka, aż ktoś obsłuży jej zapytanie odnośnie stanu biblioteki. Ta sama aplikacja jest też w stanie zażądać odnalezienie książki, której ISBN w pocie procka zeskanowała z książki umieszczonej w świecie niedostatecznego światła i nie wiadomo jakich jeszcze niebezpieczeństw…</p>
<p>Chcąc przećwiczyć podejście CQRS i zamknąć drogę klasie <code class="highlighter-rouge">SuperHelpfulManagerUtil2.cs</code>. Zdecydowałem, że do huba zostaną wstrzyknięte handlery odpowiedzialne dokładnie za 1 akcję. Handler zaimplementuje prosty interface, który pozwoli zdefiniować typ, jaki obsługuje dany handler i typ, jaki dany handler zwróci wyniku wykonania metody Handle:</p>
<script src="https://gist.github.com/slawciu/89fc09e60f84c5cc946ed49f2eac3882.js"></script>
<p>Problem może się pojawić, gdy w mój hub będzie wymagał podjęcia większej ilości akcji - ale w myśl zasady “Problemy rozwiązujmy jak się pojawią” - rozwiążemy ten problem jak się pojawi :). To podejście podpatrzyłem u <a href="https://github.com/mbalda/bookstore">Marcina Bałdy na githubie</a> - spodobało mi się, polecam, implementuję:</p>
<script src="https://gist.github.com/slawciu/37dad131eafd28a7eb09edde6e066b26.js"></script>
<p>…być może w przyszłości pokuszę się o refactor…</p>
<p>Klasa implementująca interfejs będzie miała wstrzyknięte repozytorium - w ten sposób załatwimy dostęp do bazy.
Hub będzie wiedział, że jest jakiś byt, który obsłuży jego chęć wykonania akcji. Wspomniany byt będzie wiedział, skąd ma wziąć dane do wykonania (repozytorium), ba może nawet skorzysta z innych bytów, które zrobią część pracy za niego. Repozytorium posiądzie wiedzę, czy dane obecnie trzymamy na statycznej liście, czy już może w bazie danych. Nikt nie wie za dużo, a wszyscy wykonują swoją pracę. Na chwilę obecną brzmi spoko. Do roboty!</p>
Drugie spotkanie Microsoft Azure User Group na Śląsku2017-04-27T13:00:00+00:00https://slawciu.github.io/dajsiepoznac/2017/04/27/drugie-spotkanie-microsoft-azure-group-na-slasku<p>26.04.2017 odbyło się 2 spotkanie grupy Azure. Tym razem swoją wiedzą podzielili się <a href="https://twitter.com/@bsobczyk">Bartosz Sobczyk</a> - opowiedział o Active Directory i przyległościach w Azure i <a href="https://www.future-processing.pl/blog/tkrawczyk-2/">Tomasz Krawczyk</a> - opowiedział o swoich doświadczeniach z Azure Data Lake</p>
<h2 id="bartosz-sobczyk---zarządzanie-tożsamością-na-platformie-microsoft-azure">Bartosz Sobczyk - Zarządzanie tożsamością na platformie Microsoft Azure</h2>
<p>Active Directory nigdy nie leżało blisko moich kręgów zainteresowań. W ramach zaliczenia jednego z przedmiotów na studiach musiałem skonfigurować prostą domenę - sprowadziło się to do postawienia kontrolera domeny na jednej maszynie wirtualnej i wpięcie do niej dwóch innych maszyn wirtualnych. Przy okazji poznałem teorię, jaka za praktyką, której mogłem ‘dotknąć’ w pracy - już jako użytkownik, nie domorosły administrator.
Ale co to ma wspólnego z Azure? Azure udostępnia usługę Active Directory. Ba! Możemy w łatwy sposób zmigrować naszą lokalną domenę do chmury i korzystać ze wszystkich dobrodziejstw tego rozwiązania. Bartek bardzo obszernie opowiedział o możliwościach, jakie nam daje taka migracja. Z ciekawszych rzeczy, out of the box mamy integrację z popularnymi serwisami świadczących usługi uwierzytelniające - np. z Facebookiem - w ramach <a href="https://docs.microsoft.com/en-us/azure/active-directory-b2c/active-directory-b2c-overview">Azure Active Directory B2C</a>. Integracja z istniejącymi aplikacjami wydaje się być całkiem prosta - wszystkie potrzebne informacje znajdziemy w dokumentacji. Skoro już mowa o integracji z aplikacjami - azurowe AD pozwoli nam zrzucić z siebie konieczność implementacji systemu uprawnień użytkowników, funkcjonalności resetowania haseł, czy w końcu trzymania tych haseł na serwerach i konieczności dbania o ich bezpieczeństwo w ramach aplikacji
W ramach chmurowego AD Microsoftu możemy też uruchomić usługę <a href="https://docs.microsoft.com/en-us/azure/active-directory/active-directory-conditional-access">Conditional Access</a>, w które która gdzieś w środku jest w stanie korzystając z nauczania maszynowego rozpoznawać zachowania użytkownika niepasujące do wzorca logowania - np. logowanie z różnych lokalizacji w krótkim czasie. W ramach Conditional Access jesteśmy w stanie określić polityki logowania zależne od lokalizacji, z której użytkownik chce się zalogować do naszej usług np. z wewnątrz sieci firmowej wymagać tylko loginu i hasła, a spoza dodatkowo kodu przesłanego SMSem.</p>
<h2 id="tomasz-krawczyk---analiza-big-data-z-azure-data-lake">Tomasz Krawczyk - Analiza Big Data z Azure Data Lake</h2>
<p>Tomasz zaczął swoją prezentację od przypomnienia, ile to Zetabajtów danych ludzkość będzie posiadać za 3 lata. Posłużył się ciekawym sposobem zobrazowania tej ilości - zakładając, że 1 bajt danych to ziarenko ryżu, w 2020 roku ilość danych w ziarenkach ryżu wypełni cały Ocean Spokojny. Szkoda, że ten ryż nie rozwiąże problemu głodu na świecie… ale może chociaż się przyczyni do odnalezienia rozwiązania :) Tomek wspomniał o <a href="https://blog.sqlauthority.com/2013/10/02/big-data-what-is-big-data-3-vs-of-big-data-volume-velocity-and-variety-day-2-of-21/">3Vs</a> - atrybutach/wymiarach opisujących Big Data. Internet nie śpi i w <a href="http://www.klarity-analytics.com/2015/07/27/dimensions-of-big-data/">sieci</a> można znaleźć kolejne propozycje angielskich słów zaczynających się na V, które mogą posłużyć do określenia, z czym tak naprawdę mamy do czynienia. Po określeniu przestrzeni, w której będziemy się poruszać, Tomek w skrócie omówił język U-SQL (skrót skrótu - połączenie możliwości SQLa i C#), który zaraz po tym pokazał nam w praktyce. Korzystając z Visual Studio zaprezentował skrypty analizujące logi (po prostu kolejna analiza tekstu) oraz skrypty przetwarzające obrazy z wykorzystaniem modułów opatrzonych słówkiem <a href="https://azure.microsoft.com/en-us/services/cognitive-services/">Cognitive</a>. Za pomocą Cognitive-rzeczy możemy analizować obrazy - wyszukiwać na nich obiekty, osoby o określonej płci, wieku, śmiejące się, smutne. Nie musimy przy tym posiadać zaawansowanej wiedzy na temat przetwarzania obrazów. Dostępne moduły “przemielą” dane wejściowe za nas i “wyplują” wynik w postaci zbioru tagów opisującego obraz. To daje niekończące się możliwości.</p>
<h2 id="podsumowanie">Podsumowanie</h2>
<p>Obie prezentacje były na bardzo dobrym poziomie, a zaprezentowane zagadnienia były poruszone w ciekawy sposób i widać było, że obaj panowie znają się na rzeczy. Zakres materiału był całkiem fajnie wpasowany w okienka czasowe obu prelegentów. Zarówno Tomasz jak i Bartosz zaprezentowali ogólny zarys i skupili się później na smaczkach. Były też demo na żywo - kolejny raz mogliśmy zaobserwować, że najbardziej czasochłonnym procesem w obu przypadkach było “stawianie” środowiska :). Z kwestii organizacyjnych - catering pierwsza klasa, za to zdecydowanie musimy popracować nad gotowością do działania projektora w ProgressBarze.</p>
<h2 id="jesteś-ciekaw-co-było-na-pierwszym-spotkaniu">Jesteś ciekaw, co było na pierwszym spotkaniu?</h2>
<p><a href="https://www.meetup.com/pl-PL/Microsoft-Azure-Users-Group-Poland/members/192982177/">Bartek</a> wrzucił prezentacje na youtube’a:</p>
<ul>
<li>
<p>Krzysiek Szabelski <a href="https://www.youtube.com/watch?v=mPfPM02uLJM">Rozproszona i asynchroniczna architektura oparta na Azure - case study z projektu</a></p>
</li>
<li>
<p>Stanisław Wawszczak <a href="https://www.youtube.com/watch?v=YqyiwO8NAmw">Wykorzystanie Azure Functions do zbierania danych z urządzeń pomiarowych</a></p>
</li>
<li>
<p>Damian Mazurek <a href="https://www.youtube.com/watch?v=WHW_Q2hbvi4">Od zera do IoT bohatera - czyli jak w prosty sposób przy wykorzystaniu Azurem zbudować własny system IoT</a></p>
</li>
</ul>
<p>Interesujesz się Azure i bywasz na Śląsku? Nie przegap kolejnych <a href="https://www.meetup.com/pl-PL/Microsoft-Azure-Users-Group-Poland/">spotkań</a>.</p>
IT Science Fiction(?)2017-04-21T19:18:00+00:00https://slawciu.github.io/dajsiepoznac/2017/04/21/it-science-fiction<p>Spisując rozważania na temat <a href="/dajsiepoznac/2017/03/09/czy-programista-potrzebuje-studiow/">“Czy studia są potrzebne programiście”</a> przypomniałem sobie o pewnym micie noszącym miano “Projekt grupowy”. Projekt grupowy to taki projekt, do wykonania którego niezbędne jest utworzenie grupy ludzi. Ważne, by w tej grupie znalazła się osoba, która ten projekt wykona, by pozostałe mogły się go ewentualnie “nauczyć” i obronić - zaliczając tym samym przedmiot.</p>
<h2 id="projekt-grupawy">Projekt “grupawy”</h2>
<p>Nauka pracy grupowej - niedokonana. Frustracja osoby, której zależy na dobrej ocenie i zrobi ten projekt samodzielnie - ogromna. Bardziej obrotne osoby dobierają się w grupy i tworzą ową grupą projekty na kilka przedmiotów - co kończy się zwykle podziałem zadań: 1 osoba - 1 przedmiot. Wszyscy podpisują się pod wszystkim - tu frustracja maleje, każdy coś robi, więc zasługuje przecież na ocenę… Nauka pracy grupowej - już lepiej, bo można zaobserwować element komunikacji w zespole i zbudowane zaufanie. A gdzie wiedza i umiejętności pracy nad 1 projektem w kilka osób? Brak. Wiedza i umiejętności, które wykorzystam w pracy? Nie ma.
Sam byłem świadkiem i członkiem opisanych grup, choć wcale mi się to nie podobało. Podoba mi się za to podejście: tylko konstruktywna krytyka…</p>
<h2 id="projekt-grupowy">Projekt grupowy</h2>
<p>W standardowym modelu oceniany jest przeważnie wynik projektu - co skutkuje tym, że ta jedna osoba robi go na noc przed oddaniem. Według mnie powinna być dodatkowo oceniana systematyczność i wkład w pracę poszczególnych osób. Jak to łatwo sprawdzić? - wykorzystując githuba albo inne ogólnodostępne uczelniane repozytorium.
Zakładamy, że projekt polega na zakodzeniu jakiejś aplikacji. Każdy student powinien posiadać swoje własne konto i pushować swoją część kodziku. Ze strony prowadzącego przedmiot jedynym wysiłkiem musiałoby być jedynie sprawdzenie, kto, kiedy i jak często commitował. Dodatkowo przy okazji takiego projektu studenci mogliby przećwiczyć robienie Code Review. Można też dorzucać inne zabawki w postaci serwera CI albo Issue Trackera.
Przychodząc do pracy takie rzeczy nie będą nowością, tylko czymś, z czym miało się kontakt. Na koniec oceniana jest tylko praca kontrybutorów - osoby niewystępujące w logach mogą spróbować za rok… Oczywiście istnieje opcja commitowania przez 1 osobę na 4 czy 6 różnych kontach, ale pewnie i temu można sprytnie zaradzić.</p>
<h2 id="egzamin-z-programowania-na-kartce">Egzamin z programowania na kartce</h2>
<p>Wszyscy przez to przechodzili. Pilnowanie, by nikt nie miał dostępu do Internetu, co wymusza znajomość składni i nazw wszystkich metod i klas, które chcemy wykorzystać w kodzie. Jak to się ma do pracy? Niech pierwszy rzuci kamieniem, kto nigdy nie wszedł na stackoverflow, by zakodzić coś dla klienta. Co można zaproponować w tym miejscu?</p>
<h2 id="egzaminy-przy-komputerach">Egzaminy przy komputerach.</h2>
<p>Zacznijmy od tego, że proces sprawdzania można zautomatyzować - pisząc odpowiednie testy, a studentom dając zadanie implementacji interfejsów, które to implementacje wstrzyknięte do gotowej aplikacji powinny skutkować określonym rezultatem. Bazę przypadków można przygotować wcześniej i sprawić, że nadal będzie można zrobić podział na grupy. I dajmy na to na ocenę 3: ma działać - tj testy mają być zielone. Na wyższą ocenę - w rozwiązaniu powinien być zaimplementowany wskazany wzorzec projektowy. Dostęp do internetu - proszę bardzo, ale kosztem czasu na rozwiązanie - tak, by nie opłacało się przesyłać rozwiązań między sobą. W większości przypadków egzaminów “kartkowych” sam IntelliSense dostępny w IDE wiele by uprościł.</p>
<p>Zadziała?</p>
Czas spłacić dług2017-04-21T17:29:00+00:00https://slawciu.github.io/dajsiepoznac/2017/04/21/czas-splacic-dlug<p>Jak dotąd większość czasu poświęciłem na rozwój części mobilnej całego systemu. Nie zapominajmy, że sama aplikacja mobilna jest tylko interfejsem między człowiekiem a właściwą magią, która sprawi, że to wszystko będzie działać.</p>
<h2 id="yolo">#yolo</h2>
<p>Dotychczas serwer był rozwijany w myśl słynnego ostatnio #yoloProgramming. Chodziło o to, żeby powstał działający szkielet backendu, do którego aplikacja mobilna będzie mogła się odzywać za pośrednictwem sieci.</p>
<h2 id="testy">Testy</h2>
<p>Czas spłacić dług techniczny, który został zaciągnięty i złożyć kilka unit testów w ofierze bogom programowania. Będzie to pierwszy krok do refaktoru kodziku napisanego w starym dobrym C#. Do napisania testów użyję frameworka <a href="https://xunit.github.io/">xUnit</a>, a same testy uruchamiał będę resharperowym <a href="https://github.com/xunit/resharper-xunit">runnerem</a> (którego trzeba doinstalować).</p>
<p><img class="postImage" src="/public/015-1.png" /></p>
<p>W widoku testów w solucji będziemy chcieli osiągnąć następującą sytuację:</p>
<p><img class="postImage" src="/public/015-2.png" /></p>
<p>Zanim o implementacji - trochę o strukturze. Odkąd zacząłem swoją przygodę z unit testami, w głowie utkwił mi taki schemat: skoro testuję klasę <code class="highlighter-rouge">LibraryHub</code>, to muszę stworzyć klasę zawierającą testy: <code class="highlighter-rouge">LibraryHubTests</code>, a w środku napisać testy właściwe w myśl konwencji: <code class="highlighter-rouge">Should<do-something>When<describe-current-situation-here></code>. I wszystko szło gładko, do czasu aż zestaw testów nie zawierał ściany <code class="highlighter-rouge">Should</code>-ów z przyrostkami definiującymi przypadki, w jakich dziać się powinny poszczególne rzeczy. W widoku testów nie było to czytelne. Jakiś czas poznałem inny sposób, w jaki można zaprojektować testy - tworząc z nich drzewko. Wtedy w widoku testów najpierw widzimy sytuacje, których dotyczą same testy, a rozwijając węzeł sytuacji widzimy test poszczególnych zachowań. Póki co nie znalazłem lepszej alternatywy - zatem do dzieła.</p>
<p>#Kodzik
Żeby osiągnąć zamiar z poprzedniego akapitu - zamiast tworzyć jedną klasę testującą - LibraryHubTests - tworzymy 2 <code class="highlighter-rouge">WhenGetLibraryStateCalled</code> oraz <code class="highlighter-rouge">WhenIsbnScannedCalled</code>. Wewnątrz napiszemy testy dla sytuacji, gdy na Hubie zostanie wykonana - w pierwszym przypadku metoda <code class="highlighter-rouge">GetLibraryState</code>, w drugim metoda <code class="highlighter-rouge">IsbnScanned</code>. Skupmy się na pierwszym przypadku. Moją intencją jest chęć posiadania pewności :), że po wykonaniu metody GetLibraryState na obiekcie reprezentującym rzecz, która ‘zawołała’ tą metodę zostanie wykonana metoda <code class="highlighter-rouge">updateLibraryState</code>. I tu pojawia się pytanie - jak to sprawdzić. Możemy na szybko napisać testowego klienta, który będzie się łączył do huba - ale w tym celu konieczne będzie uruchamianie całej aplikacji - bez sensu. Oczywistą drogą wydają się być mocki. Zamockujmy zatem potencjalnego <code class="highlighter-rouge">Callera</code> i zdefiniujmy mu akcję <code class="highlighter-rouge">updateLibraryState</code>, w której będziemy mogli wpłynąć na zmienne wewnątrz testu, które to z kolei będziemy mogli sprawdzać w asercji:
<script src="https://gist.github.com/slawciu/9d482055b56df3eb938f4986fcb89ece.js"></script></p>
<p>Testowany kod:</p>
<script src="https://gist.github.com/slawciu/a6bfa7116415327de85eb071c09a1a79.js"></script>
<p>Zielono! Czas na refactor! Aktualny wygląd huba i klasy testującej znajdziesz na moim <a href="https://github.com/slawciu/home-library">githubie</a>.</p>
<p>Jako funboy nUnita pokuszę się jeszcze o kilka spostrzeżeń zaobserwowanych podczas przesiadki: nUnit wymagał atrybutu <code class="highlighter-rouge">[SetUp]</code> przed metodą inicjalizującą test (co powodowało konieczność stworzenia takiej metody w każdej klasie z testami) - w xUnit załatwi nam to konstruktor - niesamowite w swej prostocie - 1 atrybut mniej. nUnitowy <code class="highlighter-rouge">[Test]</code> to <code class="highlighter-rouge">[Fact]</code>. Asserty są bardzo podobne - szczegółowy opis i więcej porównań znajdziesz oczywiście w <a href="https://xunit.github.io/docs/comparisons.html">dokumentacji</a>.</p>
Coraz bliżej backendu2017-04-13T21:29:00+00:00https://slawciu.github.io/dajsiepoznac/2017/04/13/coraz-blizej-backendu<p>Zeskanowanie kodu ISBN to dopiero pierwszy krok. Naszym celem jest uzyskanie informacji o książce jak najmniejszym kosztem - gdzie walutą jest czas spędzony nad katalogowaniem naszych wolumenów. Posiadając kod ISBN możemy odpytać jeden z serwisów udostępniających dane o książkach. Badając dostępne API doszedłem do wniosku, że najlepszym sposobem będzie odpytywać kilka serwisów i dostarczać na telefon wszystkie znalezione paczki informacji - to użytkownik wybierze najbardziej kompletną/prawidłową.
Dziś przygotujemy teren pod otrzymane z serwera dane na temat książki o zeskanowanym kodzie ISBN.</p>
<h2 id="miejsce-na-nowe-dane">Miejsce na nowe dane</h2>
<p>Potrzebna będzie prosta formatka, która wyświetli się po otrzymaniu danych z serwera i umożliwi prezentację tych danych. Na chwilę obecną zupełnie wystarczające będą Tytuł, Autor i kod ISBN</p>
<p><img class="postImage" src="/public/014.png" /></p>
<h2 id="stan-globalny-a-stan-lokalny">Stan globalny a stan lokalny</h2>
<p>Podczas tworzenia komponentu wprowadzimy w pola dane uzyskane z propsów. Zostały tam przepisane z globalnego stanu aplikacji. Od teraz będziemy nimi operować lokalnie - będą częścią stanu komponentu <code class="highlighter-rouge">NewBookForm</code>.</p>
<script src="https://gist.github.com/slawciu/25fcf121c3ac11fd8613e232df25565c.js"></script>
<h2 id="kilka-spostrzeżeń">Kilka spostrzeżeń</h2>
<p>Przy okazji ustawimy akcję przycisku Back na wywołanie ekranu skanowania kodu ISBN. Zwróć uwagę, że zamiast dotychczasowych push/pop wywołuję metodę replace. Replace zamienia aktualną ścieżkę <code class="highlighter-rouge">Navigatora</code> na podaną jako parametr. Co w ten sposób uzyskuję? Między innymi to, że aparat mam uruchomiony tylko w momencie skanowania (nie zostaje działać w tle). Ponadto przechodząc z ekranu skanowania do ekranu formularza komponent <code class="highlighter-rouge">Camera</code> nadal działał i możliwe było skanowanie kolejnych kodów… Nie będziemy implementować takiego ficzera :)</p>
<script src="https://gist.github.com/slawciu/07fc7c30e800a58881e9164e43fe8d24.js"></script>
<p>Metoda <code class="highlighter-rouge">onChangeText</code> komponentu <code class="highlighter-rouge">TextInput</code> “podmienia” tekst trzymany w stanie aplikacji na ten właśnie wprowadzony przez użytkownika. Po wprowadzeniu wszystkich danych wyślemy dane do huba - wykonując tap na <code class="highlighter-rouge">ActionButton</code>, do którego podepniemy odpowiednią akcję.</p>
Programowanie dynamiczne2017-04-13T20:32:00+00:00https://slawciu.github.io/dajsiepoznac/2017/04/13/programowanie-dynamiczne<p>Szukając inspiracji dla kolejnego posta nieprojektowego, natknąłem się na twitterze na wpis o programowaniu dynamicznym. To mi przypomniało, że kiedyś na studiach popełniłem pewien artykuł na ten temat…</p>
<p>Programowanie dynamiczne – metoda rozwiązywania problemów charakteryzujących się optymalną podstrukturą (droga do rozwiązania problemu prowadzi poprzez optymalne rozwiązanie podproblemów tego samego typu) i wspólnymi podproblemami. Nazwa programowanie dynamiczne nie odnosi się bezpośrednio do programowania komputerów, oznacza rozwiązywanie problemów z życiem tablic. Metoda ta ma zastosowanie w tych algorytmach, w których zapamiętanie obliczonego już wyniku i odwołanie się do niego w dalszej części może znacznie usprawnić jego działanie – zmniejszyć złożoność i czas wykonania samego algorytmu. W ten sposób oszczędza się czas, który byłby poświęcony na ponowne obliczanie tej samej wartości – w razie potrzeby odczytywana jest ona z pamięci.</p>
<p>Programowanie dynamiczne stosujemy jako jedną z metod działania algorytmu obok m. in. rekursji lub metody dziel i zwyciężaj, przeważnie tam, gdzie jedna z tych metod zawodzi. Np. użycie metody dziel i zwyciężaj do obliczenia dwumianu Newtona przynosi skutek fatalny – ze względu na drzewiastą budowę drogi do rozwiązania wiele obliczeń powtarza się, zasoby są tracone na kilkakrotne obliczanie tej samej wartości. Chcąc obliczyć wartość wyrażenia <img class="postImage" src="/public/013/01.png" /> wspomnianą metodą (opierając się na zależności <img class="postImage" src="/public/013/02.png" /> gdzie <img class="postImage" src="/public/013/03.png" /> musimy obliczyć wartości kolejno <img class="postImage" src="/public/013/04.png" /> i <img class="postImage" src="/public/013/05.png" /> żeby obliczyć te wartości należy obliczyć wyrażenia: dla <img class="postImage" src="/public/013/06.png" /> więc pozostaje policzenie wartości <img class="postImage" src="/public/013/07.png" /> – obie te wartości znamy, możemy policzyć drugą gałąź: dla <img class="postImage" src="/public/013/08.png" /> – drugą wartość znamy (jest równa 1), pierwszą musimy policzyć, jednak warto zauważyć, że była ona już wcześniej liczona. Przy obliczaniu wartości dwumianów dla większych wartości n i k drzewo rozwiązania się rozrasta, zatem liczba duplikujących się obliczeń rośnie.</p>
<p>Z drugiej strony decydując się na użycie programowania dynamicznego jako podstawowej zasady działania algorytmu należy wziąć pod uwagę rozmiar danych wejściowych n, dla których obliczane będą przykładowe wartości. Zgodnie z ideą programowania dynamicznego potrzebna jest tablica do przechowywania obliczonych wartości. Im większe n, tym większa tablica, co z kolei wymaga większej ilości potrzebnej pamięci. Sposób rozwiązania problemu zależy od posiadanych przez nas zasobów – czasu i pamięci komputera. Zazwyczaj rozwiązanie znajdzie się gdzieś w środku przedziału między najlepszą szybkością, a małą ilością zajmowanego miejsca w pamięci.
Aby lepiej zobrazować zalety programowania dynamicznego, zaimplementowano w języku c++ poniższe algorytmy i przeprowadzono testy sprawdzające czas wykonania algorytmów dla konkretnych danych wejściowych i ilość wykonywanych wybranych operacji. Wyniki przedstawiono na wykresach.
</p>
<h2 id="programowanie-dynamiczne-a-metoda-dziel-i-zwyciężaj">Programowanie dynamiczne a metoda dziel i zwyciężaj.</h2>
<p>Algorytm obliczania dwumianu Newtona oparty o wzór
<img class="postImage" src="/public/013/09.png" />
gdzie
<img class="postImage" src="/public/013/10.png" /></p>
<p>zaimplementowano ustawiając wartowników w miejscach występowania operacji przypisania i dodawania.</p>
<p>Algorytm w oparciu o metodę dziel i zwyciężaj</p>
<script src="https://gist.github.com/slawciu/efbde91b35c3de4a149700a6cc09cb16.js"></script>
<p>Algorytm w oparciu o programowanie dynamiczne</p>
<script src="https://gist.github.com/slawciu/54afcc8382b82fc1e14e29190ea8f731.js"></script>
<p>Uruchomiono oba algorytmy w trybie Debug w programie Visual Studio 2008 na komputerze z procesorem IntelCore 2 Duo T5750 2.00GHz, 3GB RAM, Windows Vista. Otrzymane dane przedstawiono na wykresach. Aby obliczyć czas wykonania posłużono się funkcją clock() z biblioteki time.h.
<img class="postImage" src="/public/013/w01.png" />
Kolorem niebieskim oznaczono wyniki dla algorytmu D&C. Czas wykonania algorytmu opartego o programowanie dynamiczne do zaprezentowanych n był mniejszy od tysięcznych części sekundy, wyniki są niewidoczne. Wyraźnie widać, że do n=27 nie ma prawie żadnej różnicy w czasie wykonania algorytmów, potem czas wykonania algorytmu D&C szybko rośnie.</p>
<p><img class="postImage" src="/public/013/w02.png" />
<img class="postImage" src="/public/013/w03.png" /></p>
<p>Powyższe dwa wykresy prezentują zależność pomiędzy ilością wykonanych operacji: przypisania i dodawania dla algorytmu programowania dynamicznego; porównania dla algorytmu D&C a wielkością n. Na powyższym wykresie zaprezentowano powiększenie przedziału ilości operacji od 0-600. W tej skali widać, że w przeciwieństwie do algorytmu D&C (punkty w kształcie rombów) algorytm oparty o programowanie dynamiczne ma złożoność zbliżoną do liniowej, co więcej nachylenie przybliżonej prostej do osi OX jest niewielkie, co sugeruje, że dla większych wartości n ilość wykonanych operacji będzie powoli liniowo wzrastać. Podkreślając tę zaletę nie należy jednak zapominać o wzrastającym zapotrzebowaniu na pamięć. Dla małych n (do 6) ilość wykonywanych operacji jest praktycznie taka sama.</p>
<p><img class="postImage" src="/public/013/w04.png" /></p>
<p>Powyżej przedstawiono zależność liczby operacji dodawania i przypisania od wielkości n dla algorytmu opartego o programowanie dynamiczne. Dla tej ilości danych już wyraźnie widać zakrzywienie, jednak w porównaniu z oczekiwaną ilością operacji dla algorytmu rekursywnego można przyjąć, że zależność ta jest nadal liniowa. Ilość operacji osiągnięta przez ten algorytm dla n=1650 odpowiada w przybliżeniu ilości operacji dla n=23 algorytmu rekursywnego.
</p>
<h2 id="programowanie-dynamiczne-a-rekursja">Programowanie dynamiczne a rekursja</h2>
<p>Zaimplementowano algorytm obliczający kolejne wyrazy ciągu Fibonacciego w oparciu o wzór
<img class="postImage" src="/public/013/11.png" />
W języku C++, ustawiając wartowników w miejscach występowania operacji przypisania i dodawania.
<script src="https://gist.github.com/slawciu/d2efb13e8870e65cc51bf835b7b18ceb.js"></script></p>
<p>Dla programowania dynamicznego:</p>
<script src="https://gist.github.com/slawciu/d0d5a06b8ccaf2a1b83d4060add134b0.js"></script>
<p><img class="postImage" src="/public/013/w05.png" /></p>
<p>Na wykresie widać, że dla n większego od 40 czas wykonania algorytmu zaczyna gwałtownie rosnąć. Zaznaczono wyniki dla algorytmu rekursywnego, czas wykonania algorytmu opartego o programowanie dynamiczne ponownie w tym przedziale był zbyt niski, by program mógł go wychwycić (mniejszy od tysięcznej części sekundy).</p>
<p><img class="postImage" src="/public/013/w06.png" /></p>
<p><img class="postImage" src="/public/013/w07.png" /></p>
<p>Powyższy wykres jest powiększeniem w dla n<=12. Widać, że dla n=4 algorytm rekursywny jest lepszy (liczba wykonanych operacji dominujących jest mniejsza), jednak wraz ze wzrostem n, czas jego wykonania rośnie gwałtownie szybko. Wykres nad nim obrazuje skalę przyrostu ilości operacji wraz ze wzrostem n.
Reasumując, programowanie dynamiczne w ogólnym przypadku możemy zastosować tam, gdzie dany rodzaj obliczeń jest wykonywany wielokrotnie dla tych samych danych i zapamiętanie raz policzonej wartości lub ogólnie wyniku danej operacji może być w przyszłości ponownie odczytany i użyty do dalszych obliczeń. Idea oparcia metody o tablicę powoduje, że dla większej ilości danych rośnie rozmiar programu w pamięci, dlatego sens użycia metody należy rozpatrywać również w kategoriach dostępnego sprzętu. Kryterium, którym będziemy się kierować wybierając tę metodę zależy od konkretnego przypadku.
Zestawienie programowania dynamicznego z metodą dziel i zwyciężaj oraz rekursją jednoznacznie pokazują, że programowanie dynamiczne może z sukcesem zastąpić wymienione wcześniej metody usprawniając czas wykonania algorytmu i znacznie redukując jego złożoność.</p>
Lokalizacja wewnątrz budynków - cd.2017-04-06T15:20:00+00:00https://slawciu.github.io/dajsiepoznac/2017/04/06/lokalizacja-wewnatrz-budynkow-cd<p>W ostatnim “nieprojektowym” <a href="/dajsiepoznac/2017/03/29/lokalizacja-wewnatrz-budynkow/">wpisie</a> opisałem, jak można wykorzystać pole magnetyczne Ziemi w celu lokalizacji wewnątrz budynków. Dziś zastanówmy się, gdzie można wykorzystać tę supermoc. Temat jest momentami dość śliski i łatwo wskazać elementy zwyczajnego śledzenia….</p>
<h2 id="nawigacja-w-centrum-handlowym">Nawigacja w centrum handlowym</h2>
<p>To może być ten przypadek, gdy końcowemu użytkownikowi aplikację możemy oferować za darmo, bo ilość informacji, które zbierzemy na jego temat z nawiązką pokryje wszelkie koszty.
Czasami do centrum handlowego jedziemy w konkretnym celu - zakup butów - nasza aplikacja mogłaby nawigować po wszystkich sklepach z butami. Chcemy odwiedzić ten jeden konkretny - proszę bardzo. Jakie informacje można uzyskać? Jak dużo czasu spędzamy przy półce z butami, w jakim sektorze sklepu. Jak je wykorzystać? Wysyłając reklamy przygotowane specjalnie dla odwiedzającego, podrzucając kupon rabatowy, by dodatkowo zachęcić do odwiedzenia konkretnego sklepu.</p>
<h2 id="nawigacja-w-budynkach-użyteczności-publicznej">Nawigacja w budynkach użyteczności publicznej</h2>
<p>Szpitale, urzędy - są to miejsca, które odwiedzamy rzadko i to przeważnie nie z własnej woli. Chcąc trafić do konkretnego pokoju/sali może przydać się soft do nawigacji.</p>
<h2 id="ratownictwo-górnicze">Ratownictwo górnicze</h2>
<p>Dostarczając pod ziemię Internet jesteśmy w stanie zmapować chodniki kopalniane i wykorzystywać aplikację lokalizacyjną do monitorowania osób, które są pod ziemią - w smutniejszych przypadkach - poszukiwać ich po zawałach. Górnik będzie tylko musiał mieć ze sobą telefon (albo prostsze urządzenie), które połączy się z systemem i poda jego aktualną pozycję.</p>
<h2 id="hale-magazynowe">Hale magazynowe</h2>
<p>Lokalizacja mogłaby być częścią autonomicznego systemu zarządzającego stanem magazynu. Drony i bezzałogowe wózki widłowe mogłyby wspierać ludzi.</p>
<h2 id="gdzie-w-tym-wszystkim-miejsce-dla-programisty">Gdzie w tym wszystkim miejsce dla programisty?</h2>
<p>Jedyne, co jest potrzebne to platforma, która pozwoli nam tworzyć tego typu rozwiązania. Możemy zakodzić swoją - rozbijając się o patenty - albo skorzystać z już istniejących. Tu warto wspomnieć o fińskim startupie IndoorAtlas, który przez lata zdołał dojrzeć - i naukową ideę przekuł w produkt, który ma potencjał. Dzięki <a href="http://docs.indooratlas.com/">dostępnemu SDK</a> developer jest w stanie tworzyć natywne aplikacje na systemy Android i iOS, a od niedawna również wykorzystując Cordovę - multiplatformowo. Tylko czekać aż osobna wtyczka pojawi się dla Xamarina i ReactNative.</p>
Skanowanie kodu ISBN2017-04-06T14:40:00+00:00https://slawciu.github.io/dajsiepoznac/2017/04/06/skanowanie-kodu-isbn<p>Jedną z kluczowych funkcjonalności aplikacji mobilnej będzie skanowanie kodu ISBN z książki. Kod ISBN to ten sam kod, który jest skanowany przy kasie, gdy kupujemy książkę.</p>
<h2 id="historia">Historia</h2>
<p><em>“Czy to prawda, że w Moskwie na placu Czerwonym rozdają Samochody? Tak, to prawda, tylko że nie w Moskwie, lecz w Leningradzie, i nie na placu Czerwonym, a na placu Rewolucji, i nie Samochody, a rowery, i nie rozdają, a kradną.”</em></p>
<p>Teza: Wg wikipedii, ISBN jest niepowtarzalnym 13-cyfrowym identyfikatorem książki. Jako międzynarodowy standard został zatwierdzony w 1970 roku</p>
<p>Tak, ale…</p>
<ul>
<li>do 31 grudnia ISBN składał się z 10 cyfr</li>
<li>w Polsce nadawany jest od 1974 roku, a norma powstała w 1982 roku</li>
<li>książka może być wydana bez numeru ISBN (wtedy jest obciążana 23% VATem - zamiast niższym na książki)</li>
<li>zdarzają się duplikaty:
<em>“Norma nie wskazuje jednoznacznie, jak należy postąpić w takiej sytuacji, a o przyjętym rozwiązaniu wydawca decyduje na własną odpowiedzialność.(…) Jeśli książka została już wprowadzona do sprzedaży, nie ma możliwości naprawienia błędu. W publicznym obiegu będą znajdowały się dwie książki oznaczone tym samym numerem ISBN. Dlatego też prosimy o skrupulatne sprawdzanie numeru ISBN, który ma być wydrukowany na książce, tak aby unikać sytuacji osygnowania książki zdublowanym lub błędnym numerem.”</em>
<a href="https://e-isbn.pl/IsbnWeb/start/poco.html">źródło</a></li>
</ul>
<p>Wniosek - odobnie jak z numerem <a href="http://www.polskieradio.pl/9/307/Artykul/1005998,Ten-sam-PESEL-dla-dwoch-roznych-osob-MSW-to-niemozliwe">PESEL</a> - tu też nie będzie tak różowo.</p>
<h2 id="kolejna-biblioteka-w-bibliotece">Kolejna biblioteka w Bibliotece</h2>
<p>Problemy będziemy rozwiązywać jak się pojawią. Tymczasem czas zapiąć kolejną bibliotekę do naszej aplikacji (wspominałem już, że praca z ReactNative to jak zabawa klockami LEGO?) <a href="https://github.com/lwansbrough/react-native-camera">react-native-camera</a>. Biblioteka, która nie tylko umożliwi nam skanowanie kodów, ale też w przyszłości posłuży nam do robienia zdjęć książkom (w celu jednoznacznego określenia jej stanu).</p>
<p>Użycie jest banalnie proste. Najpierw przedstawmy kamerę naszej aplikacji:</p>
<p><code class="highlighter-rouge">import Camera from 'react-native-camera';</code></p>
<p>potem wykorzystajmy kodzik z przykładu na githubie, delikatnie dostosowując go do naszych potrzeb</p>
<script src="https://gist.github.com/slawciu/c6e8eac135b0972371356180a477643a.js"></script>
<p>Teraz tylko wystarczy uruchomić aplikację i skierować aparat w kierunku kodu ISBN - i oto jest! Pojawia się na androidowym Toast. Zeskanowany numer możemy przesłać na serwer…</p>
<p><img class="postImage" src="/public/011.png" /></p>
Lokalizacja wewnątrz budynków2017-03-29T18:00:00+00:00https://slawciu.github.io/dajsiepoznac/2017/03/29/lokalizacja-wewnatrz-budynkow<p>Będąc na studiach przekonałem się, że informatyka to nie tylko wynik wyświetlony na ekranie po 4 godzinach pracy jakiegoś złożonego algorytmu. W dzisiejszych czasach możemy się na nią natknąć na każdym kroku. Informatyka wpływa na życie ludzi. Nie zawsze pozytywnie. Dziś trochę o lokalizacji wewnątrz budynków - dziedzina tak ekscytująca, że stała się tematem mojej pracy magisterskiej.</p>
<h2 id="nawigacja-a-lokalizacja">Nawigacja a lokalizacja</h2>
<p>Na początku rozdzielmy 2 rzeczy: nawigację i lokalizację - nawigacja to proces rozpoczynający się zdefiniowaniem punktów, między którymi chcemy znaleźć drogę, wytyczenie ścieżki między zdefiniowanymi punktami i ciągła informacja zwrotna - czy podążam założoną ścieżką, czy też zboczyłem z drogi i muszę na nią wrócić. Lokalizacja to określenie pozycji. Nawigacja korzysta z lokalizacji.</p>
<h2 id="za-firewallem">Za firewallem</h2>
<p>Jak działa lokalizacja na zewnątrz (GPS)? W dużym uproszczeniu pobieramy dane o naszym położeniu z satelit umieszczonych na orbicie okołoziemskiej. Im więcej satelit - tym dokładniejsze koordynaty naszej pozycji jesteśmy w stanie uzyskać. W budynkach jest gorzej, bo ściany najzwyczajniej w świecie tworzą barierę prawie nie do przedarcia dla sygnału z satelit. Ogromna wada budynków.</p>
<p>Czy zastanawialiście się kiedyś, skąd gołębie wiedzą, w którą stronę powinny zmierzać, by dotrzeć do założonego celu? Google Maps Pigeon odpada - ciężko operować aplikacją i jednocześnie machać skrzydłami. Poza tym gołębie potrafiły przenosić listy na długo przed stworzeniem Internetu. Niektóre zwierzęta nauczyły się korzystać z pola magnetycznego, które wytwarza kula ziemska. Z podstawówki wiemy, że Ziemia to taki wielki magnes z 2 biegunami. Gołębie, langusty i kto wie co jeszcze wykorzystywały możliwość ‘odczytu’ pola magnetycznego i na jego podstawie udawały się w długie wędrówki.</p>
<h2 id="pole-magnetyczne--zakłócenia--">Pole magnetyczne + zakłócenia = ????</h2>
<p>Pole magnetyczne działa do dziś, a budynki ze względu na materiały użyte podczas budowy zakłócają je w specyficzny sposób. I robią to na tyle sprytnie, że w ramach jednego budynku, godząc się na niewielki błąd pomiarowy jesteśmy w stanie jednoznacznie określić, gdzie aktualnie się znajdujemy. W ten sposób wielka wada w rozwiązaniu GPS stała się wielką zaletą. Co ciekawe, nie tylko budynki zakłócają pole magnetyczne. Analogiczne zjawisko możemy zaobserwować w kopalniach rud metali.</p>
<p>Zwierzęta już dawno poradziły sobie z odczytaniem tej niewidzialnej siły - człowiek też - tylko trochę później. Mało tego, przy odrobinie szczęścia posiadasz taki czytnik przy sobie. Gdzie? W Twoim telefonie komórkowym. Magnetometr jest wykorzystywany jako część układu odpowiadającego za orientację telefonu. Korzysta z niego aplikacja kompas i wszystkie kompasopochodne (live view Flightradara, Sky Map od Google’a). Możesz z niego skorzystać i Ty - na Androidzie jest to dziecinnie proste - wystarczy się ‘zapisać’ na zdarzenia generowane przez <a href="https://developer.android.com/reference/android/hardware/Sensor.html#TYPE_MAGNETIC_FIELD">czujnik</a> i z określoną częstotliwością będziemy otrzymywać wartości (x,y lub x,y,z w zależności od modelu) natężenia pola magnetycznego w mikro Teslach.</p>
<h2 id="pod-dachem">Pod dachem</h2>
<p>I znów w dużym uproszczeniu - żeby dowiedzieć się, gdzie się znajdujemy w danym budynku, ktoś musi wcześniej go zmapować - za firewallem zajmują się tym kartografowie - w budynku wystarczy, że osoba wyposażona w smartfon i odpowiednią aplikację przespaceruje się po miejscach, które chcemy objąć zasięgiem systemu lokalizacji - w ten sposób powstanie mapa pola magnetycznego budynku. Potem już zwykły użytkownik będzie mógł odpalić swoją aplikację i posiadając informację o mapie zobaczyć, w którym miejscu się znajduje. Lokalizacja zaimplementowana - można ją wstrzyknąć do modułu nawigacji i zacząć na tym zarabiać.</p>
<p>Btw - myśleliście, jak w dzisiejszych czasach można zrealizować <a href="https://www.youtube.com/watch?v=onm3sqQ4LMo">Mapę Huncwotów (ang. Marauder’s Map) </a>?</p>
Czy wszystko jest?2017-03-28T21:00:00+00:00https://slawciu.github.io/dajsiepoznac/2017/03/28/czy-wszystko-jest<p>Testować możemy wszystkie składowe Reduxa. Wiemy już jak ugryźć Reducers. Teraz czas na Components i Actions.</p>
<h2 id="components">Components</h2>
<script src="https://gist.github.com/slawciu/1c3c69605ba2feca771e923f57f4a068.js"></script>
<p>W celu sprawdzenia, czy nasz komponent jest w stanie się prawidłowo narysować (wyrenderować) musimy go przesłać jako parametr metody create() renderera z paczki <a href="https://www.npmjs.com/package/react-test-renderer">react-test-renderer</a>. Przesłanie Reacta jest proste - możesz mnie użyć wszędzie, gdzie dostępny będzie odpowiedni renderer (nawet na bardzo niskim poziomie, patrz <a href="https://github.com/iamdustan/react-hardware">ReactHardware</a>. I proszę bardzo - chcę uruchomić Reacta w testach, więc wykorzystuję renderera :) Obiekt zwrócony przez metodę create w moim przypadku wygląda tak:
<script src="https://gist.github.com/slawciu/fca16ef13a23d921cdbc2157a3f57bce.js"></script>
Odpowiada temu, co wcześniej zakodziłem w BooksList. Operując na tym jsonie jesteśmy w stanie sprawdzać, czy poszczególne elementy naszego widoku są widoczne, czy nie. Gwoli wyjaśnienia - w celu zapewnienia wykonania testu, musiałem dorzucić kilka propsów: store, navigator i route - podobnie jak w użyciu tego komponentu w testowanej aplikacji. Ten test potraktuję jako smoke’a i nic dodatkowo nie sprawdzę.</p>
<h2 id="actions">Actions</h2>
<p>A właściwie ActionsCreators zwracają obiekt akcji, która ma wpłynąć na stan aplikacji.
<script src="https://gist.github.com/slawciu/0998807fd96b7405c251aaadf6406b84.js"></script></p>
<p>Podobnie jak w przypadku Reducera - odpalamy metodę i sprawdzamy, czy otrzymany obiekt odpowiada oczekiwanemu.</p>
<h2 id="__mocks__">__mocks__</h2>
<p>Prędzej czy później - musiały się pojawić. Aplikacja mobilna wykorzystuje signalR, a w testach opieranie się na tym, że gdzieś w cyberprzestrzeni jest uruchomiony jakiś hub, który może wpłynąć na wyniki naszych testów jest… niebezpieczne, niepoważne - jednym słowem - nie. Wykorzystując mechanizm mockowania dostarczony przez jest skrobniemy na szybko mocka signalRa.</p>
<p>SignalR to nie jedyna przeszkoda w testowaniu. Może się zdarzyć, że testowane przez nas komponenty będą korzystać z zewnętrznych zależności - w moim przypadku kontrolki stylu. Na chwilę obecną nie są mi potrzebne, dla nich mock też powstanie. Jedyny zgrzyt, jaki się tu pojawia, to konieczność tworzenia katalogu __mocks__ jak najbliżej mockowanej paczki/biblioteki. I tak dla klienta signalr, który wylądował w katalogu lib, mock musiał sie znaleźć w lib\__mocks__, a mock dla material ui zasłużył na katalog ‘obok’ node_modules. Osobiście nie podoba mi się takie podejście, gdyż logika testów jest rozsmarowana po całym repo - z drugiej strony mocki mamy najbliżej mockowanej funkcjonalności jak się tylko da. Całe szczęście, że Visual Studio ‘skraca’ nam drogę między testem a implementacją rozsądną nawigacją.</p>
<p><img class="postImage" src="/public/009.png" /></p>
<p>Zielono!</p>
Stop! Teraz testy2017-03-23T22:00:00+00:00https://slawciu.github.io/dajsiepoznac/2017/03/23/stop-teraz-testy<p>Po dość owocnym okresie tworzenia kodziku wyrzuty sumienia zaczynają gryźć niemiłosiernie, a widmo zbliżającej się klęski majaczy się na horyzoncie. O czym mowa - proste o projekcie bez testów. Po stronie mobilnej tworzenie aplikacji przypomina bardzo długiego spike’a, którego zadowalające (mnie) efekty lądują w repozytorium. Jako że szkielet aplikacji jest gotowy, czas dodać testy, które pokryją kodzik…</p>
<h2 id="__test__">__test__</h2>
<p>Katalog o wiele mówiącej nazwie jest częścią template’a, który tworzy się za pomocą komendy <code class="highlighter-rouge">react-native init</code>. Znajdują się w nim 2 pliki testujące przykładowy kodzik na platformę Android i iOS. Mnie się nie przydadzą, więc wylatują. Na ich miejsce pojawi się kod testujący Reducery, Actions i Components. Jako że Redux leci z nami, testowanie powinno być błahostką.</p>
<h2 id="jest">Jest</h2>
<p>Facebook tworząc Reacta nie zapomniał o jednej z ważniejszych części życia oprogramowania (i dewelopera :)) - o testowaniu - i przygotował całkiem wygodną bibliotekę (sami określają ją mianem Painless JavaScript Testing). Painless i JavaScript? Sprawdźmy ten oksymoron. Na pierwszy ogień idzie Reducer. Będzie stosunkowo łatwy do przetestowania, gdyż przetwarza informację zawartą w otrzymanym obiekcie Action, transformując stan aplikacji.</p>
<p>Kod odpowiedzialny za obsługę zmiany stanu połączenia z hubem signalR:</p>
<script src="https://gist.github.com/slawciu/f8ffd8081f27b328ee7401b20f6eaed7.js"></script>
<p>Możemy przetestować tak:</p>
<script src="https://gist.github.com/slawciu/d068cf58162a82fa27f8c39c9a66bd1a.js"></script>
<p>Urzeka fluent api i mnogość funkcji sprawdzających efekt testów. Na pokładzie biblioteki znajdziemy funkcje sprawdzające obiekty jak i obiekty, programista .net odnajdzie też odpowiedniki assertów ze swojej ulubionej biblioteki na <a href="https://www.nunit.org/">N</a> czy <a href="https://xunit.github.io/">x</a>. Oczywiście Jest posiada obszerną <a href="https://facebook.github.io/jest/">dokumentację</a>. Wspomniałem już o możliwości mockowania? Nic tylko brać i testować.</p>
<p>Żeby uruchomić nasze testy wystarczy w konsoli uruchomić magiczną komendę <code class="highlighter-rouge">npm test</code></p>
<p><img class="postImage" src="/public/008.png" /></p>
Arbitrem w ringu Redux2017-03-21T22:08:00+00:00https://slawciu.github.io/dajsiepoznac/2017/03/21/arbitrem-w-ringu-redux<h2 id="redux">Redux</h2>
<p>Rozwijając aplikację w duchu #yoloProgramming można łatwo skodzić swoje własne legacy, którego w życiu nie będziemy chcieli tknąć. Łatwo wpaść w tę pułapkę tworząc aplikacje w React, gdzie każdy komponent posiada swój własny stan, a my możemy wyczyniać z nim niestworzone rzeczy. Czas ukręcić na siebie bata i zapiąć do Domowej Biblioteki <a href="https://github.com/reactjs/redux">Reduxa</a> - wariacji na temat <a href="https://facebook.github.io/flux/">Fluxa</a>, który delikatnie zmienia sposób, w jaki informacje przepływają przez aplikację.</p>
<p><img src="/public/007.png" alt="Redux - diagram" /></p>
<h2 id="actions">Actions</h2>
<p>Chcąc zmienić stan naszej aplikacji definiujemy akcję, która zostanie wywołana z poziomu komponentu (prawdopodobnie w wyniku interakcji z człowiekiem). Akcja przedstawia się typem i niesie ze sobą jakąś informację - tekst, liczbę, obiekt - cokolwiek wymyślimy. W tworzeniu akcji wg Reduxa powinni nam pomóc ActionCreators.</p>
<h2 id="reducers">Reducers</h2>
<p>Skoro akcja opisuje zmianę, warto na nią zareagować. W tym celu posłuży nam <del>Manager</del> Reducer. Redux zakłada, że stan naszej aplikacji jest globalny - pozbywamy się <code class="highlighter-rouge">state</code> komponentu skąd tylko się da. Ponadto stan jako taki nie ulega zmianie - po każdej modyfikacji wynikającej z akcji mamy do czynienia z nowym stanem. Obiekty z rodziny Reducers posiadając informację o poprzednim stanie i dokonanej zmianie, tworzą nowy stan.</p>
<h2 id="store">Store</h2>
<p>Nad wszystkim czuwa Store. Przechowuje stan aplikacji, umożliwia jego pobieranie i modyfikowanie. Ponadto przechowuje informację o subskrybentach zmian stanu aplikacji.</p>
<h2 id="components">Components</h2>
<p>Wracamy do komponentów. Te w większości przypadków pozbawione stanu operują na danych dostępnych w <code class="highlighter-rouge">props</code>.</p>
<p>Na <a href="https://github.com/slawciu/home-library/tree/master/HomeLibraryMobile">githubie</a> możesz zobaczyć, jak to wygląda w aplikacji mobilnej.
Przy ‘zapinaniu’ Reduxa korzystałem z <a href="https://medium.com/@jonlebensold/getting-started-with-react-native-redux-2b01408c0053#.2ytogtjgv">tutoriala</a> - działa :)</p>
<p>Teraz już prosta droga do rozwijania funkcjonalności właściwych.</p>
ReactNative i MaterialUI2017-03-15T22:25:00+00:00https://slawciu.github.io/dajsiepoznac/2017/03/15/react-native-material-ui<p>Uruchomiliśmy szkielet aplikacji. Swą spartańską urodą urzekła zapewne niejednego. Mnie nie ;) Dziś skupimy się na 2 rzeczach: nadaniu naszej aplikacji mobilnej stylu zbliżonego do <a href="https://material.io/guidelines/">Material Design</a> i dorzucimy Navigator.</p>
<h2 id="konfiguracja">Konfiguracja</h2>
<p>Styl nadawać możemy ręcznie - wymyślając wygląd każdej nowej kontrolki, albo skorzystać z <a href="https://github.com/xotahal/react-native-material-ui">gotowego rozwiązania</a>.</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>yarn add react-native-material-ui
react-native link react-native-vector-icons
</code></pre></div></div>
<p>Po wykonaniu powyższych poleceń musimy jeszcze dorzucić linijkę</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>compile project(':react-native-vector-icons')
</code></pre></div></div>
<p>do pliku <code class="highlighter-rouge">build.gradle</code> w sekcji <code class="highlighter-rouge">dependencies</code></p>
<p>Teraz możemy czerpać garściami z ostylowanych komponentów, o ile wcześniej poinformujemy ReactNative, gdzie je znajdzie</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>import { COLOR, ThemeProvider, Toolbar } from 'react-native-material-ui';
</code></pre></div></div>
<h2 id="użycie-react-native-material-ui">Użycie react-native-material-ui</h2>
<p>Zaczniemy od <code class="highlighter-rouge"><ThemeProvider uiTheme={uiTheme}></code>. Ten komponent opakuje nam całą aplikację (komponenty wewnątrz) w styl Material Design. Jako <code class="highlighter-rouge">prop</code> przekazujemy mu <code class="highlighter-rouge">uiTheme</code> - obiekt, za pomocą którego możemy dostosować styl do naszych potrzeb - ustawiając np. kolor przewodni aplikacji.</p>
<h2 id="navigator">Navigator</h2>
<p>Wewnątrz <code class="highlighter-rouge">ThemeProvider</code> wrzucamy komponent <code class="highlighter-rouge">Navigator</code>. Skorzystam z Navigatora dostępnego w samym ReactNative. <a href="https://facebook.github.io/react-native/docs/navigation.html">Tutaj</a> możesz poczytać o innych opcjach. Navigator sam w sobie niczego nam nie narysuje (dopóki mu nie powiemy jak), ale sprawi, że poruszanie się między ekranami i co najważniejsze - zarządzanie tym procesem będzie o wiele prostsze w przyszłości. Musimy tylko zdefiniować ścieżki (<code class="highlighter-rouge">routes</code>), którymi będziemy się poruszać. Pierwszym przystankiem na naszej ścieżce będzie lista książek.</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>const routes = {
home: {
Title: 'Domowa Biblioteka',
Page: BooksList
}
};
</code></pre></div></div>
<p>Skoro Navigator zna już ścieżki, powiedzmy mu, w jaki sposób ma nam je przedstawić.
Korzystamy z faktu, że elementowi ścieżki zdefiniowaliśmy komponent odpowiedzialny, więc wrzucamy ten komponent pomiędzy <code class="highlighter-rouge"><</code> i <code class="highlighter-rouge">></code>. Magia, smrodek, kwiatek, herezja, gamechanger? Nazwij to jak chcesz - działa :).</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>_renderScene(route, navigator) {
return (
<View>
<route.page route={route} navigator={navigator}/>
</View>
);
}
</code></pre></div></div>
<p>Teraz tylko wystarczy stworzyć komponent <code class="highlighter-rouge">BooksList</code>. Przy zacznę porządkować to, co ostatnio zostawiłem w kodzie - mały bałagan. Nowy komponent wyląduje w osobnym pliku. Rysując się wykorzysta <code class="highlighter-rouge">ListView</code> od facebooka i <code class="highlighter-rouge">Toolbar</code> z paczki Material Design. Dorzucimy jeszcze jakieś przykładowe dane i oto jest. Pierwszy kolorowy widok.</p>
<p><img class="postImage" src="/public/006 (Mobile).png" /></p>
<p>Więcej kodziku z dzisiejszego posta znajdziesz na <a href="https://github.com/slawciu/home-library/tree/master/HomeLibraryMobile">githubie</a>.</p>
W prawym narożniku - ReactNative2017-03-14T21:15:00+00:00https://slawciu.github.io/dajsiepoznac/2017/03/14/w-prawym-narozniku-reactnative<p>Gdzieś w sieci dostępny jest serwer z hubem signalR na pokładzie. Szczęśliwie się składa, że wiemy, gdzie dokładnie i w jaki sposób z owym hubem możemy “porozmawiać”. Czas stworzyć aplikację mobilną, która stanie się częścią naszej Domowej Biblioteki.</p>
<h2 id="krok-po-kroku">Krok po kroku..</h2>
<p>Podążając za <a href="https://facebook.github.io/react-native/docs/tutorial.html">tutorialem</a> dostępnym na stronie ReactNative konfigurujemy środowisko. Na uwagę zasługuje fakt, że facebook sugeruje użycie narzędzia <a href="https://chocolatey.org/">Chocolatey</a> - kto nie zna, niechaj się mu przyjrzy z bliska - całkiem wygodne i można sobie “zDevOpsować” konfigurację domowego sprzętu. Instalacja większości najczęściej używanych programów zaraz po formacie odpalając prosty skrypt? Brzmi kusząco…</p>
<p>Po udanej instalacji wszystkich niezbędnych elementów naszego środowiska możemy facebook sugeruje prostą komendę:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>react-native init HomeLibraryMobile
</code></pre></div></div>
<p>magia w konsoli i mamy gotową aplikację!</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>react-native run-android
</code></pre></div></div>
<p>wykonane w utworzonym katalogu z aplikacją skompiluje i uruchomi ją na podłączonym urządzeniu (emulatorze albo telefonie), a naszym oczom pojawi się prosty hello world. Czy da się zacząć prościej? Nie sądzę. Jak już jesteśmy w konsoli…</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>code .
</code></pre></div></div>
<h2 id="wygenerowana-aplikacja">Wygenerowana aplikacja</h2>
<p>Przyjrzyjmy się bliżej potworkowi, który powstał za pomocą komendy init. Projekt jest wyraźnie podzielony na część dedykowaną Androidowi i iOSowi. Do rzeczy związanych z iOS zaglądał nie będę, póki co nie mam tam żadnego interesu, albo inaczej - wprowadzanie zmian w tym obszarze nie posiada wartości biznesowej.</p>
<p><img class="postImage" src="/public/005-1 (Mobile).png" /></p>
<p><code class="highlighter-rouge">android</code> -> Klik! Zaglądając do tego katalogu osoba posiadająca choć minimalne doświadczenie z programowaniem na platformę od Wujka Googla ujrzy… aplikację androidową! w katalogu app znajdziemy katalog <code class="highlighter-rouge">src</code>, w nim <code class="highlighter-rouge">main</code> z androidowym manifestem, gdzieś w otchłani katalogu <code class="highlighter-rouge">java</code> znajdą się <code class="highlighter-rouge">MainActivity.java</code> i <code class="highlighter-rouge">MainApplication.java</code>. Obie te klasy posiadają wiedzę o obiektach z React i Native w swoich nazwach. W tym momencie zostawmy te pliki w spokoju - bądźmy tylko świadomi ich istnienia. Nas interesują pliki z rozszerzeniem js.</p>
<p><img class="postImage" src="/public/005-4.png" /></p>
<h2 id="reactnative">ReactNative</h2>
<p>Wracając do głównego katalogu natrafimy na 2 podobnie wyglądające pliki <code class="highlighter-rouge">index.android.js</code> oraz <code class="highlighter-rouge">index.ios.js</code> - one posłużą nam do rozwijania aplikacji pod konkretne platformy. Od nas zależy, ile kodu będzie wspólnego. Wartość biznesowa kieruje nas do pliku z androidem w nazwie. A w nim - nasz dobry znajomy, Reakcik! Klasa <code class="highlighter-rouge">HomeLibraryMobile</code> wita nas informacją, że sama już zdążyła rozszerzyć Component i ma dla nas wstępnie zaimplementowaną metodę <code class="highlighter-rouge">render</code>. Pojawiły się dziwne tagi htmlowe, rozpoczynające się z wielkiej litery. Web developerze znający Reacta - w tym momencie div został przemianowany na View! Spójrz jeszcze na sam dół tego pliku - rozpoznajesz CSSy? Skoro wszyscy się już znają, w gronie znajomych wprowadzenie pierwszej funkcjonalności będzie przyjemnością.</p>
<h2 id="połączmy-się-z-hubem">Połączmy się z hubem</h2>
<p>ReactNative pomimo swojego młodego wieku doczekał się już <a href="https://react.parts/native">szeregu paczek</a> (bibliotek) tworzonych przez społeczność. Szczęśliwie się składa, że nie musimy kodzić komunikacji przez WebSockety, żeby skorzystać z signalR - z pomocą przyjdzie nam <a href="https://github.com/olofd/react-native-signalr">react-native-signalr</a>. Korzystając z instrukcji na githubie dorzucamy paczkę do naszego projektu, przeklejamy ze zrozumieniem kodzik inicjujący połączenie (wprowadzając po drodze kosmetyczne zmiany) i włączamy serwer.
<img class="postImage" src="/public/005-2 (Mobile).png" />
Może się zdarzyć, że nie będziemy w stanie połączyć się z naszym dev-środowiskiem hostowanym na IIS Express. Od czego mamy <a href="https://stackoverflow.com/questions/3313616/iis-express-enable-external-request/15809698#15809698">stackoverflow</a>. U mnie działa.</p>
<p>Na dzień dobry zawołajmy tę samą metodę huba, którą woła strona internetowa. Po drodze poinformujmy Użytkownika naszej aplikacji o stanie połączenia z serwerem wyświetlając <a href="https://facebook.github.io/react-native/docs/toastandroid.html">Toasta</a>.</p>
<script src="https://gist.github.com/slawciu/d80b12decd59c4b14ef4eeaf6a28a65d.js"></script>
<h2 id="gdy-coś-pójdzie-nie-tak">Gdy coś pójdzie nie tak…</h2>
<p>Co zrobić, gdy napisaliśmy dobry kodzik, ale jest jakiś błąd w jego wykonaniu i chcemy pokazać telefonowi, co robi źle… ReactNative w trybie debug uruchamia się na sporej nakładce z wbudowanymi potężnymi narzędziami. Jak się do niego dostać? Klikając przycisk menu, albo tak jak w moim przypadku - potrząsając telefonem. Polecam włączyć Hot Reloading (aplikacja przeładuje się, gdy zapiszemy edytowany plik w naszym IDE). W poszukiwaniu potencjalnych błędów pomoże nam debugger - opcja Debug JS Remotely odpali Chrome’a, a w konsoli developerskiej będziemy mieć możliwość debugowania kodu js naszej aplikacji - kolejny ukłon w stronę web-developerów.</p>
<p><img class="postImage" src="/public/005-3 (Mobile).png" /></p>
<p>Ponadto wspomniana nakładka posiada bardzo przyjemny ekran błędów (czerwony) i ostrzeżeń (żółty). Gdy popełnimy jakiś błąd podczas bycia mobile developerem ReactNative podpowie co może być przyczyną błędu, a czasem nawet podpowie potencjalne rozwiązanie. Zupełnie nowa jakość po androidowym enigmatycznym “Wystąpił błąd, aplikacja została zamknięta” z podprogowym przekazem - miłego czytania logów, developerze!</p>
Czy studia są potrzebne programiście?2017-03-09T20:15:00+00:00https://slawciu.github.io/dajsiepoznac/2017/03/09/czy-programista-potrzebuje-studiow<p>Po mojej wieloletniej przygodzie z Politechniką Śląską mogę rozgłaszać wszem i wobec, że posiadam tytuł naukowy - mgr inż., choć przyznaję, że nigdzie się jeszcze w ten sposób nie podpisałem.
Pracować zacząłem już na studiach - jak zdecydowana większość moich kolegów z roku. A teraz do rzeczy - z perspektywy deva.</p>
<h2 id="do-pracy-jak-najprędzej">Do pracy jak najprędzej</h2>
<p>Kiedy zdecydowałem się podjąć pracę, byłem na 3 roku studiów. Wcześniej nie wydawało mi się to konieczne, ponadto gdzieś z tyłu głowy siedziała mi myśl, że przecież zdecydowanie za mało potrafię, żebym mógł zostać zauważony przez jakąkolwiek firmę programistyczną. Jak zamierzałem zmienić stan wiedzy? Postudiować, zaliczyć kolejne przedmioty traktujące o programowaniu, spróbować w przyszłości. Praca wydawała mi się poważną rzeczą, do której trzeba podejść na poważnie - a jak wygląda student, który w zapleczu ma kilka projektów zrobionych na zaliczenie? Dziś wydaje mi się, że w czasach wypokowych programistów 15k, człowiek z maturą składa podanie na studia i CV do kilku firm programistycznych, z roszczeniami o rynkowe zarobki. Między zajęciami narzeka na ich bezsens, w pracy wymiguje się koniecznością studiowania. Nie tędy droga…</p>
<h2 id="przedmioty-bez-sensu">Przedmioty bez sensu</h2>
<p>Wśród znajomych z roku niosła się pieśń o niepotrzebnych przedmiotach. Po co komu na Informatyce Podstawy Elektrotechniki?! Elektronika i Miernictwo?! Przecież przyszedłem tu programować, a nie bawić się prądem! Jeszcze mnie kopnie…
Rysowanie procesora na kartce? Rejestry? C# ftw! mam zmienną i nie zawaham się jej użyć!</p>
<p>Patrząc na te “problemy” z perspektywy czasu, dochodzę do wniosku, że te wszystkie “bzdurne przedmioty” były potrzebne, bo Informatyka to nie tylko kolejne sklepy internetowe zakodzone z jakiegoś znoszonego templejta. Zrozumienie podstaw działania elektroniki dało (powinno było dać?) jako-takie pojęcie jak działa komputer. Mało tego - kto by dzisiaj nie chciał pobawić się w Internet Rzeczy? A czym są te rzeczy? Elektroniką. Byłoby smutno, gdyby okazało się, że Twój nowy moduł wi-fi spaliłeś, bo okazało się, że jednak napięcie zasilania ma znaczenie… Jak już tu jesteśmy - programowanie niskopoziomowe, asembler. Ta wiedza powinna przynajmniej zadzwonić w pewnym momencie Twojej kariery i zaprocentować.</p>
<h2 id="mało-praktyki-zawodowej">Mało praktyki zawodowej</h2>
<p>Nie zapominajmy, że są to studia, nie zawodówka, a Informatyka to nauka, a nie zawód i jako nauka dość szybko wyewoluowała. Profesorowie, którzy wykładają na uczelniach przeważnie brali udział w konstruowaniu maszyn cyfrowych, pracach nad nowymi algorytmami, prowadzili badania i rozważania na temat sieci komputerowych. Dziś wyniki swoich badań próbują przekazać młodym, którzy niekoniecznie chcą słuchać - bo jak będą potrzebować tej wiedzy, to znajdą w Internecie. Poza tym, po co wiedza o sieciach, kiedy właśnie rozwijam platformę e-commerce? Dziś do bycia programistą wcale nie jest potrzebna cała zaawansowana wiedza z teorii informatyki.</p>
<p>Kurs współczesnego programowania odbił delikatnie od Informatyki “klasycznej”. Zamierzasz iść na studia informatyczne, żeby się przygotować do pracy? Będziesz smutny przez 5 lat, a po pierwszym miesiącu w pracy dojdziesz do wniosku, że studia to strata czasu. Studia są po to, żebyś studiował (nie tylko w sensie imprezowym :)), myślał, odkrywał, nauczył się szybko przyswajać wiedzę, utrwalił zdolność analitycznego myślenia i w idealnym przypadku - nauczył się pracować w grupie.</p>
<h2 id="czy-warto-iść-na-studia">Czy warto iść na studia?</h2>
<p>Rozważmy 5 lat:
Kończysz szkołę średnią, co możesz zrobić w 5 lat? Pytanie pomocnicze: jak widzisz swoją przyszłość w zawodzie?</p>
<p>Jeżeli chcesz skakać od jednego frameworka js do kolejnego, tworzyć proste aplikacje na telefony - szukaj pracy w młodym, dynamicznym zespole, gdzie wykształcenie wyższe nie jest wymagane.
Kiedy Twoi koledzy będą kończyć studia, Ty będziesz miał 5 lat doświadczenia w zawodzie. Ale bądź też świadom, że jeżeli zechcesz zmienić pracę, potencjalny pracodawca zapyta Cię o dyplom.
W tym momencie może zamknąć się droga do błyskotliwej kariery albo/i pracy w wymarzonej firmie.</p>
<p>Jeżeli interesuje Cię Informatyka jako taka i chcesz zgłębić wiedzę - zapisz się na studia, a po pierwszym stopniu zdecyduj, czy chcesz walczyć o tytuł magistra. Czas spędzony na studiach zaprocentuje w przyszłości, ponadto już 3 lata licencjatu (3,5 roku inżyniera) liczy się, jak 8 lat pracy zawodowej w naszym niezachwianym systemie emerytalnym. Dla pracodawcy będziesz osobą z wykształceniem wyższym - w wyścigu o pracę pokonasz kolegę, z poprzedniego punktu. Praca na tym etapie może być pułapką, która sprawi, że zawalisz naukę. Ostrożnie. Wolny czas można wykorzystać na koła naukowe, uczelniane grupy programistyczne, czy projekty open source - tym nadrobisz dystans do wspomnianego kolegi.</p>
<p>Magisterka - 1,5 - 2 lat. Skoro już się obroniło tytuł, warto powalczyć o ten drugi. Należy tylko pamiętać, czym są studia magisterskie - masz posiąść zaawansowaną wiedzę (nie zdziw się, jak dostaniesz całką w twarz), wykonać projekt, który będzie zawierał element badawczy (przyda się myślenie), a na samym końcu go obronić przed komisją, która oficjalnie nada Ci tytuł naukowy.</p>
<p>Odpowiadając na pytanie: Warto. Tylko trzeba wiedzieć, po co.</p>
<p>Warto też posłuchać, co mają inni do powiedzenia - weźmy takiego <a href="https://www.youtube.com/watch?v=p5CPvSDEIyk&t=3s">Maćka Aniserowicza</a> - spoiler alert - wychodzi na to, że mam dość zbieżne poglądy…</p>
W lewym narożniku - React i SignalR...2017-03-08T20:15:00+00:00https://slawciu.github.io/dajsiepoznac/2017/03/08/react-signalr<p>W ramach konkursu Daj się poznać rozwijam aplikację do zarządzania domowym zbiorem książek. Na <a href="https://github.com/slawciu/home-library">githubie</a> wylądował pierwszy kawałek kodu.</p>
<p><img class="postImage" src="/public/003.png" /></p>
<h2 id="signalr">SignalR</h2>
<p>Biblioteka dostarczana przez Microsoft, jak sami się chwalą:
“Incredibly simple real-time web for .NET”
i mają rację. Po stronie serwera musimy zakodzić Hub, po stronie klienta połączyć się do tego Huba. Biblioteka sprawi, że w aplikacji będziemy mieć dostępne “stałe łącze” między klientami a serwerem. W pudełku z samym signalR dostajemy informację o połączonych klientach (po stronie Huba), z możliwością filtrowania odbiorców potencjalnych wiadomości.
Jak wygląda komunikacja? Posiadając nawiązane połączenie, po stronie klienta wywołujemy metodę dostępną w hubie:</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$.connection.hub.url = "/signalr";
this.sHub = $.connection.library;
this.sHub.client.updateLibraryState = function (libraryState) {
this.setState((prevState, props) => {
return { libraryState: libraryState }
});
}.bind(this);
$.connection.hub.start().done(function () {
this.sHub.server.getLibraryState("Maurice");
}.bind(this));
</code></pre></div></div>
<p>Jeżeli klient, który wywołał funkcję huba ma zaimplementowaną obsługę metody updateLibraryState, będzie w stanie zareagować na “głos serwera”. Zwróć uwagę, że hub posiada informację o bycie, który wykonał na nim metodę.</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>public void GetLibraryState(string myIdentity)
{
Clients.Caller.updateLibraryState($"new state for you, {myIdentity}");
}
</code></pre></div></div>
<p>#React
Kiedy Facebook <a href="https://www.youtube.com/watch?v=XxVg_s8xAms">poinformował świat</a> o swoim najmłodszym dziecku - React - wszyscy pukali się w głowę. W świecie web-developmentu, gdzie rozłączność czystego htmla, javascriptu i cssów jest świętością, pojawili się goście od Marka Z. i próbują przekonać całe to świątobliwe towarzystwo, że wrzucenie htmla do javascriptu to będzie przełom. I przełom nastąpił. Statyczny html wykorzystujemy do tworzenia komponentów, które mają swój stan - state i niezmienniki - props. Zmiana stanu powoduje, że komponent jest przerysowany - tj coś zmienia się w oknie przeglądarki użytkownika. Co jest najbardziej sexy w tym całym “reakcie”? <a href="https://facebook.github.io/react/docs/reconciliation.html">Algorytm</a>, który sprawia, że przerysowują się tylko te komponenty, których stan uległ zmianie. Jak wygląda ten potworek od FB?</p>
<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>render() {
return (<div>
<h1>Domowa Biblioteka</h1>
<div>Gdzieś poniżej wyświetlimy książki...</div>
<div>Stan biblioteki: { this.state.libraryState }</div>
</div>);
}
</code></pre></div></div>
<p>Każdemu komponentowi musimy powiedzieć, jak się ma narysować (implementując funkcję render) tu możemy stworzyć potworka htmlowo-javascriptowego. Oprócz tego, do dyspozycji mamy kilka “wejść” w czas życia komponentu:</p>
<ul>
<li><a href="https://facebook.github.io/react/docs/react-component.html#componentwillmount">componentWillMount()</a></li>
<li><a href="https://facebook.github.io/react/docs/react-component.html#componentdidmount">componentDidMount()</a></li>
<li><a href="https://facebook.github.io/react/docs/react-component.html#componentwillreceiveprops">componentWillReceiveProps()</a></li>
<li><a href="https://facebook.github.io/react/docs/react-component.html#componentwillupdate">componentWillUpdate()</a></li>
<li><a href="https://facebook.github.io/react/docs/react-component.html#componentdidupdate">componentDidUpdate()</a></li>
<li><a href="https://facebook.github.io/react/docs/react-component.html#componentwillunmount">componentWillUnmount()</a></li>
</ul>
<p>Przy okazji polecam dokumentację od FB - daje radę. Moja biblioteka skorzysta z łącznika między czystym Reactem a światem .NETa - <a href="https://reactjs.net/">ReactJS.net</a></p>
<h2 id="kodzik">Kodzik</h2>
<p>Co robi kodzik? Po uruchomieniu, z poziomu komponentu Dashboard wołana jest metoda huba library - żądanie o aktualny stan biblioteki, opatrzone prostym parametrem. Hub w podzięce za pobudzenie, wywołuje metodę klienta, który go zawołał, a otrzymana wiadomość pojawia się na stronie. Ta skomplikowana machina ma swoje miejsce w chmurze Azure.</p>
Daj Się poznać - podsumowanie2017-03-02T17:15:00+00:00https://slawciu.github.io/dajsiepoznac/2017/03/02/daj-sie-poznac-podsumowanie<p>Zeszłoroczny konkurs miał dla mnie 2 zakończenia:</p>
<p>Nagłe - na blogu - po osiągnięciu regulaminowej ilości postów zabrałem się za nadrabianie życia poza-pracowo-blogowego i nagle zdałem sobie sprawę, że nawet nie napisałem podsumowania….</p>
<p>Zaskakujące - 8 czerwca 2016 dowiedziałem się, że grono uczestników wybrało mojego bloga do <a href="http://devstyle.pl/daj-sie-poznac-2016/daj-sie-poznac-finalisci-2016/">TOP16</a> konkursu</p>
<div class="media">
<blockquote class="twitter-tweet" data-lang="pl"><p lang="pl" dir="ltr">Moje rzeczybezinternetu są w Top 16 :D Wow! Chyba pora zacząć zbierać głosy :) <a href="https://t.co/tOQ0YMB9ns">https://t.co/tOQ0YMB9ns</a> <a href="https://twitter.com/hashtag/dajsiepoznac?src=hash">#dajsiepoznac</a></p>— Sławek Rudawski (@slavciu) <a href="https://twitter.com/slavciu/status/740430564038184960">8 czerwca 2016</a></blockquote>
<script async="" src="//platform.twitter.com/widgets.js" charset="utf-8"></script>
</div>
<p>Na gali finałowej Procent ogłosił, że zająłem jedno z 4 trzecich miejsc (7. wg ilości głosów) :).</p>
<div class="media">
<blockquote class="twitter-tweet" data-lang="pl"><p lang="pl" dir="ltr">Jest podium! Gratulacje <a href="https://twitter.com/slavciu">@slavciu</a> i reszta! <a href="https://t.co/py9qH1MKar">pic.twitter.com/py9qH1MKar</a></p>— Jaroslaw Porwol (@pako1337) <a href="https://twitter.com/pako1337/status/744128450848505857">18 czerwca 2016</a></blockquote>
<script async="" src="//platform.twitter.com/widgets.js" charset="utf-8"></script>
</div>
<p>Nie spodziewałem się takiego obrotu sprawy i przez prawie pół roku nie wiedziałem jak się znalazłem pośród laureatów. Do przemyślenia całej sytuacji zmobilizował mnie <a href="https://twitter.com/michalgellert">Michał Gellert</a>, który poprosił mnie o rady, które mógłby zawrzeć w <a href="https://www.michalgellert.pl/blog/poradnik-dsp2017-jak-dac-sie-poznac/">poradniku</a> dla tegorocznych uczestników konkursu Daj się poznać.</p>
<ul>
<li>
<p>Przede wszystkim, warto wybrać temat (technologię), którą się lubi – nie ma znaczenia, czy dopiero chcesz ją lepiej poznać, czy już ją znasz – dopóki jej nie znienawidzisz, posty będą pisać się same.
Co do samych postów – staraj się opisywać rzeczy tak, jakbyś chciał je wytłumaczyć dziecku lub komuś, kto się totalnie nie zna na Twoim temacie – zdobędziesz szersze grono czytelników i ograniczysz grupę „meh, to są jakieś super-kombo-smoki, których nie rozumiem i nie mam czasu zrozumieć”. Z drugiej strony – ciężko ominąć bardziej „mięsne” wstawki – nadal ok! Byle nie przegiąć.</p>
</li>
<li>Postaraj się też, by Twój post był przyjemny w odbiorze: przeproś się ze słownikiem, włącz autokorektę, pisz w edytorze, który podkreśla błędy. Zwróć uwagę na to, że książki są wyjustowane - pozwól mi przeczytać kawałek książki na Twoim blogu - wyjustuj tekst :)</li>
<li>
<p>Daj znać innym, że powstał nowy post – zapnij twittera do swojego bloga – możesz to robić manualnie, albo skorzystać z jednego z narzędzi typu <a href="https://ifttt.com/">IFTT</a>, nie zapomnij o hashtagach.</p>
</li>
<li>
<p>Chwal się na slacku Devs PL, wrzucaj bloga na #blogreview. Slack jest też źródłem wiedzy tajemnej – w poprzedniej edycji pojawiła się dyskusja, na temat godziny publikacji posta – odpowiedź: rano. Moje były ustawione na 8:00, by załapać się w „poranny przegląd prasy” potencjalnych czytelników. W gronie <a href="http://uczestnicy.dajsiepoznac.pl/lista">uczestników</a> #dajSiePoznac drzemie duża porcja inspiracji i wsparcia w walce z samym sobą o… systematyczność!</p>
</li>
<li>
<p>Czytaj inne blogi #dajSiePoznac. Nie bój się popełniać błędów, ale też – ucz się na błędach innych. Czytając blogi dostrzegamy rzeczy, których nie widać, gdy je piszemy – brzmi znajomo?
Zaplanuj sobie czas na pisanie bloga, zrób z tego „rytuał”, by stał się częścią dnia. Jeżeli Ci dobrze idzie i przez przypadek popełniłeś dzieło długością porównywalne do „Pana Tadeusza” – nie popełniaj błędu Mickiewicza – podziel post na kilka. Kiedy mój post jest za długi? Kiedy myślisz sobie: „a, dodam jeszcze tl;dr; na początku…”.</p>
</li>
<li>Wykorzystaj mechanizm automatycznego publikowania postów o zadanym czasie. Przydadzą się, gdy niespodziewane rzeczy zajmą Twój czas na bloga. Nie staraj się też pisać na siłę – ciężko się czyta kolejnego posta z serii „To mój [n] post. Nic się nie dzieje.” – jeśli będziesz systematycznie pracował nad swoim projektem – zawsze wpadnie coś godne opisania – tu pomocą może być commit log, dlatego warto dbać o jego jakość.</li>
</ul>
<p>Jednym słowem:</p>
<p><img class="postImage" src="/public/dsp2017-1.png" /></p>
HomeLibrary intro!2017-03-01T20:15:00+00:00https://slawciu.github.io/dajsiepoznac/2017/03/01/homelibrary-intro<h2 id="opis-domeny">Opis domeny</h2>
<p>Wyobraź sobie, że Twój księgozbiór osiągnął rozmiar, którego nie sposób zmieścić na jednym regale w jednym pokoju. Dorzuć do tego fakt, że wyprowadzasz się z domu, a pośród książek znajdują się w nim pozycje, po które sięgasz częściej - Gra Endera i przyległości, przygody Inkwizytora Mordimera Madderdina i kilka innych… więc część książek zabierasz ze sobą. Czy wspomniałem już, że kolekcjonujesz całe serie książek? A serie mają to do siebie, że mogą być kontynuowane po latach oczekiwania na kolejną część. Nie martw się, w okolicy księgozbioru są 3 osoby, które szybko i chętnie uzupełniają brakujące tomy (zarówno te nowe, jak i te starsze, bo właśnie ukazało się tłumaczenie książki z 1992 roku). Idylla.</p>
<p>Do czasu, aż okazuje się, że wiele z tomów posiadasz w 2 lub więcej kopiach i nie jest powiedziane, że nie pojawią się kolejne - po prostu nie sposób spamiętać, czy dany egzemplarz jest w lokalizacji bazowej księgozbioru, czy po prostu w aktualnym miejscu zamieszkania jednego z opiekunów… Zasada jest prosta - widzę na półce ostatni egzemplarz, a nie ma go u mnie - kupuję! Jakby tego było mało, pojawiają się też znajomi o zbieżnych z Twoimi gustach czytelniczych, więc dzielisz się z nimi swoimi papierowymi dobrami i starasz się zapamiętać co, kto, kiedy…</p>
<p><img class="postImage" src="/public/001.jpg" /></p>
<p>Po kilku latach zaczynają doskwierać problemy:</p>
<ol>
<li>Jakie ja właściwie mam książki?</li>
<li>Gdzie jest książka X?</li>
<li>Kto pożyczył moją książkę?</li>
<li>Można to skatalogować, ale to przecież zajmie tyle czasu…</li>
</ol>
<p>Które prostym zabiegiem zamieniamy w wyzwania…</p>
<h2 id="co-może-ci-pomóc-w-rozwiązaniu-tych-problemów-podjęciu-tych-wyzwań">Co może Ci pomóc w <del>rozwiązaniu tych problemów</del> podjęciu tych wyzwań?</h2>
<p>Proste, Kodzik! I same książki, które opatrzone są swego rodzaju identyfikatorem - ISBN - czy unikalnym? Cóż… z tym bywa różnie. Kod ISBN wydrukowany jest na każdej książce w Polsce od 1974, w nowszych wydawnictwach nie tylko jako ciąg cyfr, ale też jako kod paskowy. Dreszcz ekscytacji?
Kod kreskowy możemy zeskanować skanerem takim jak w sklepie - albo wykorzystując do tego kamerę naszego telefonu. Posiadając numer ISBN i połączenie z Internetem możemy pobrać informacje o naszej książce - tytuł, autora, wydawnictwo, krótki opis, a jak będziemy mieć odrobinę szczęścia, to nawet okładkę.</p>
<h2 id="tech-mięsko-tutaj">Tech-mięsko tutaj</h2>
<p>Skoro księgozbiór okazuje chęć współpracy, trzeba jeszcze wybrać technologię. Testy zaplecza napiszę w C#, wykorzystując xUnit, sam backend również w starym dobrym C#, hostując rozwiązanie w chmurze Azure. Przyda się webowy podgląd na książki w sytemie - ReactJS, a skoro już mamy podwaliny ASPowej aplikacji, można użyć ReactJS.net.</p>
<p>Do sqlowej bazy - grzecznie, za pomocą EntityFramework, a wszystkie zależności rozwiąże Autofac.
ISBN dostanie się do systemu za pośrednictwem telefonu z Androidem. Aplikacja zostanie napisana w multiplatformowym (bo 2 to już multi, a 8 użytkowników Windows Phone’a jakoś przełknie brak wsparcia - są przyzwyczajeni…) ReactNative.</p>