Tygodniowe wyzwanie programistyczne — #4

By 17 October 2016 October 18th, 2016 #main, ITlogy, Wydarzenia

Czwarty dzień wyzwa­nia oznacza, że jesteśmy w połowie dro­gi! Początku­ją­cych czeka dziś pra­ca z bib­lioteka­mi i “cud­zym” kodem, zaawan­sowanych krót­ka pro­gramisty­cz­na wprawka z małą niespodzianką :) Gotowi?

Wyzwanie dla początkujących

Przed przys­tąpi­e­niem do zada­nia, zas­tanów się nad rezul­tatem Two­jej wczo­ra­jszej pra­cy: Czego dowiedzi­ałeś się o swoich umiejęt­noś­ci­ach? Czego się nauczyłeś? Co zro­bisz z tą wiedzą?

 

Soft­ware devel­op­ment to nie tylko tworze­nie nowego kodu i rozwi­janie go, ale też umiejęt­ność zrozu­mienia rozwiązań innych i radze­nie sobie z prob­le­ma­mi jakie mogą się tam pojaw­ić. Pewnie usłysza­łaś już jakaś his­torię o kodzie, który przy­pom­i­na wykopaliska i nikt nie chce go dotknąć ;) No cóż, cza­sem trze­ba. Dlat­ego od samego początku warto nauczyć się rozu­mieć pracę innych. A jak to moż­na zro­bić? Ano czy­ta­jąc kod na głos. Więcej o samej metodzie zna­jdziecie, trady­cyjnie w naszym wpisie. Czy­tanie kodu jest super ćwicze­niem, bo pozwala Ci zrozu­mieć log­iczny ciąg przy­czynowo-skutkowy zapisanego pro­gra­mu, a także może być świet­nym sposobem na poz­nanie nowych bib­liotek i wzorców ;)

Wyszukaj na GitHu­bie jak­iś pro­jekt open source/ pop­u­larną bib­liotekę w Twoim języku pro­gramowa­nia i zacznij go czy­tać. Zna­jdź jeden plik, najlepiej taki, który ma metody pomoc­nicze (np. SpringRe­flec­tionU­tils albo IOUtils z bib­liote­ki Apache Com­mons) i lin­ij­ka po lin­i­jce opowiadaj sobie co w danym miejs­cu się dzieje.

Po 45 min takiego czy­ta­nia odpowiedź na pytania:

  • czego doty­czył czy­tany przeze mnie kod?
  • jakie rozwiąza­nia zas­tosowane w czy­tanym kodzie już znalałam?
  • co było dla mnie nowością?
  • co z tego mogę również zas­tosować w swoim kodzie?

Nasza odpowiedź

Wybrałam do „poczy­ta­nia” klasę IOUtils z bib­liote­ki Apache Com­mons.
Jest to bib­liote­ka, która służy do pra­cy z I/O, czyli w prak­tyce możesz uży­wać ją w pra­cy z obra­bi­an­iem stru­mieni danych np. dzi­ała­jąc z dany­mi zebrany­mi w pliku csv. Tak, oczy­wiś­cie, możesz to wszys­tko robić „samemu” w Javie (java.io), jed­nak, jako, że takie zada­nia są częste pow­stała właśnie taka bib­liote­ka, która pozwala Ci korzys­tać z gotowych metod związanych z przetwarzaniem takich stru­mieni infor­ma­cji. Dzię­ki temu, że sko­rzys­tasz z jej inter­fe­jsów, możesz skupić się na fak­ty­cznym zada­niu, a nie „kodować” koło na nowo. Jed­nak zobacze­nie jak to wyglą­da w środ­ku jest ciekawym doświadczeniem.
W Klasie IOUtils mamy kil­ka pod­sta­wowych metod związanych z obróbką danych, a także staty­czne zmi­enne reprezen­tu­jące różne sposo­by dzie­le­nia linii w zależnoś­ci od systemu.
  • W klasie może­my znaleźć metodę close­Qui­et­ly(), która od metody z javy.io różni się tym, że ignoru­je IO Excep­tion — tutaj warto zwró­cić uwagę, na to, że taki pusty catch jest oznac­zony komen­tarzem //ignore (czyli wiemy, czemu jest on pusty).
  • rozróżnione zostało kopi­owanie i kopi­owane dużych Obiek­tów (metody copy() i copyLarge()),
  • zas­tosowany został kon­cept over­loadin­gu (prze­ciąża­nia), czyli pod taką samą nazwą mamy takie metody, które przyj­mu­ją różny zestaw argumentów

Więk­szość tego kodu przy­pom­i­na to, co samemu musi­ałabyś napisać nie uży­wa­jąc bib­liote­ki. Dzię­ki jej zas­tosowa­niu, kod sta­je się trochę czyst­szy i masz pewność, ze nie zapom­nisz o żad­nym szczególe.

Wyzwanie dla praktyków

Przed przys­tąpi­e­niem do zada­nia, zas­tanów się nad rezul­tatem wczo­ra­jszej pra­cy: Czego dowiedzi­ałeś się o swoich umiejęt­noś­ci­ach? Czego się nauczyłeś? Co zro­bisz z tą wiedzą?

Code Kata, to sposób na ćwicze­nie się w pisa­niu kodu. I dzisi­aj mamy dla Was takie właśnie ćwicze­nie. Założe­nie jakie przyj­mum­jesz na początku: to zadanie, jest jak prawdzi­we życie :), a wyty­czne przyras­ta­ją z każdym rozwiązaniem. Czy­taj je więc po kolei, nie prze­chodź do kole­jnej częś­ci bez zaim­ple­men­towa­nia poprzed­niej, bo odbierzesz sobie całą zabawę!

Część 1: Pogoda

Napisz aplikację wycią­ga­jącą dane o pogodzie (np. z https://developer.yahoo.com/weather/). Możesz wybrać maksy­mal­ną tem­per­aturę, opis, czy całą prognozę…

Część 2: Sport

Napisz drugą aplikację przetwarząjącą dane o zawod­nikach sportowych(np. z uży­ciem https://developer.yahoo.com/fantasysports/guide/).

«<Tutaj jest 3 część zadania, zaznacz, by przeczytać»>

Część 3: DRY

Połącz obie aplikac­je ze sobą, korzys­ta­jąc z zasady DRY.

Podsumowanie:

    • w jaki sposób decyz­je, które pode­j­mowałeś pisząc każdy z tych frag­men­tów wpły­wał na to, że połacze­nie ich było później łatwiejsze/trudniejsze?
    • czy sposób pisa­nia drugiego pro­gra­mu był w jakimś stop­niu dos­tosowany do pier­wszej aplikacji?
    • co osiągnąłeś poprzez wyciąg­nię­cie wspól­nych ele­men­tów? Co musi­ałeś poświęcić/w czym takie ;wspólne’ rozwiązanie jest gorsze? Które wer­sje były­by łatwiejsze w utrzy­ma­niu i rozwi­ja­niu w przyszłości?

Zadanie pochodzi ze strony: http://codekata.com/kata/kata04-data-munging/

Nasza odpowiedź

Jako dwa źródła danych wybrałem nieco inne API niż w zada­niu — pier­wsze to API ser­wisu Wikipedia, z którego odczy­tu­ję kiedy miała miejsce ostat­nia zmi­ana strony głównej oraz jej opis. Drugie API doty­czy pogody, pobier­am pogodę dla Wrocław­ia i wyświ­et­lam jej opis na najbliższy dzień. Kod obu rozwiązań zna­jdziesz na GitHub’ie: https://gist.github.com/jderda/a7b3f4e14370f264ec932bce037e0d08

Oczy­wiś­cie pomi­jamy tutaj kwest­ię nieczytel­nego kodu czy braku podzi­ału na mniejsze blo­ki kodu — nie o clean code w tym zada­niu przede wszys­tkim chodziło ;)

Kwes­t­ia, która od razu rzu­ca się w oczy to fakt, że pomi­mo są to całkowicie odmi­enne API, więk­szość kodu pozosta­je taka sama — różni się adres URL, konkret­na ‘ścież­ka’ w odpowiedzi, którą chce­my pobrać z JSONa oraz (ewen­tu­al­nie) rodzaj zwracanych danych.

Daje nam to trzy metody, które na pewno może­my wyłączyć jako abstrak­cyjne i zależne od przy­pad­ku, niech będą to:

buil­dReques­tURI — jej celem jest zbu­dowanie konkret­nego URI, pod którym otrzy­mamy dane

read­Raw­Da­ta — ma za zadanie zamienić odpowiedź z ser­w­era na obiek­tową reprezentację

con­vert — ma za zadanie zamienić obiek­tową reprezen­tację odpowiedzi ser­w­era na docelową odpowiedź

Całość jak zapewne zauważyłaś przy­pom­i­na pro­ces ETL (ang. Extract-Trans­form-Load; i nim w isto­cie jest) — najpierw pobier­amy dane, kon­wer­tu­je­my je w sposób pozwala­ją­cy na filtrowanie/obróbkę, wyciągamy intere­su­jące nas infor­ma­c­je i zwracamy je. W prak­tyce moglibyśmy wyko­rzys­tać dowolne narzędzie przez­nac­zone do pra­cy z tego rodza­ju proce­sa­mi, i także by zadziałało :)

Jako że treść zada­nia była jas­na — połączyć kod w sposób, który jak najbardziej elimin­u­je dup­likac­je, zaim­ple­men­towałem rozwiązanie z uży­ciem gen­eryków i klas bazowych. Pozwala na imple­men­tac­je logi­ki ETL dla dowol­nego źródła danych opartego o pro­tokół HTTP, nieza­leżnie od for­matu danych (wystar­czy zaim­ple­men­tować odpowied­nią logikę konwertującą).

Oczy­wiś­cie całość imple­men­tacji mogła wyglą­dać jeszcze lep­iej, moż­na było użyć inter­fe­jsów funkcyjnych itp, ale jak już wspom­ni­ałem ide­al­ny Clean code nie był celem tego zadania ;)

Oczy­wiś­cie drugie rozwiązanie jest zde­cy­dowanie łatwiejsze do utrzy­ma­nia i rozwi­ja­nia w przyszłości.

Kod rozwiąza­nia po refak­torze zna­jdziesz na https://gist.github.com/jderda/3a9ddea19734c0e1a83cdc7fd07cbb3c

Pamię­taj, że nowe zada­nia będą się pojaw­iać codzi­en­nie o godzinie 11. Rozwiąza­nia będziemy umieszczać pod zada­ni­a­mi kole­jnego dnia o godzinie 18. Nie zapom­nij podzielić się swoi­mi odpowiedzi­a­mi i prze­myśle­ni­a­mi na wydarze­niu na face­booku, a jak masz ochotę to też w komentarzu ;)!

Lin­ki do wszys­t­kich zadań zna­jdziesz w innym wpisie na naszym blogu. Powodzenia!